mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 22:40:53 +07:00
batman-adv: Remove old fragmentation code
Remove the existing fragmentation code before adding the new version and delete unicast.{h,c}. batadv_unicast_send_skb() is moved to send.c and renamed to batadv_send_skb_unicast(). fragmentation entry in sysfs (bat_priv->fragmentation) is kept for use in the new fragmentation code. BATADV_UNICAST_FRAG packet type is renamed to BATADV_FRAG for use in the new fragmentation code. Signed-off-by: Martin Hundebøll <martin@hundeboll.net> Signed-off-by: Marek Lindner <lindner_marek@yahoo.de> Signed-off-by: Antonio Quartulli <antonio@meshcoding.com>
This commit is contained in:
parent
2c598663e8
commit
f097e25dbe
@ -37,4 +37,3 @@ batman-adv-y += send.o
|
||||
batman-adv-y += soft-interface.o
|
||||
batman-adv-y += sysfs.o
|
||||
batman-adv-y += translation-table.o
|
||||
batman-adv-y += unicast.o
|
||||
|
@ -29,7 +29,6 @@
|
||||
#include "send.h"
|
||||
#include "types.h"
|
||||
#include "translation-table.h"
|
||||
#include "unicast.h"
|
||||
|
||||
static void batadv_dat_purge(struct work_struct *work);
|
||||
|
||||
@ -592,9 +591,9 @@ static bool batadv_dat_send_data(struct batadv_priv *bat_priv,
|
||||
goto free_orig;
|
||||
|
||||
tmp_skb = pskb_copy(skb, GFP_ATOMIC);
|
||||
if (!batadv_unicast_4addr_prepare_skb(bat_priv, tmp_skb,
|
||||
cand[i].orig_node,
|
||||
packet_subtype)) {
|
||||
if (!batadv_send_skb_prepare_unicast_4addr(bat_priv, tmp_skb,
|
||||
cand[i].orig_node,
|
||||
packet_subtype)) {
|
||||
kfree_skb(tmp_skb);
|
||||
goto free_neigh;
|
||||
}
|
||||
@ -990,10 +989,10 @@ bool batadv_dat_snoop_incoming_arp_request(struct batadv_priv *bat_priv,
|
||||
* that a node not using the 4addr packet format doesn't support it.
|
||||
*/
|
||||
if (hdr_size == sizeof(struct batadv_unicast_4addr_packet))
|
||||
err = batadv_unicast_4addr_send_skb(bat_priv, skb_new,
|
||||
err = batadv_send_skb_unicast_4addr(bat_priv, skb_new,
|
||||
BATADV_P_DAT_CACHE_REPLY);
|
||||
else
|
||||
err = batadv_unicast_send_skb(bat_priv, skb_new);
|
||||
err = batadv_send_skb_unicast(bat_priv, skb_new);
|
||||
|
||||
if (!err) {
|
||||
batadv_inc_counter(bat_priv, BATADV_CNT_DAT_CACHED_REPLY_TX);
|
||||
|
@ -444,7 +444,6 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
|
||||
hard_iface->batman_adv_ptype.dev = hard_iface->net_dev;
|
||||
dev_add_pack(&hard_iface->batman_adv_ptype);
|
||||
|
||||
atomic_set(&hard_iface->frag_seqno, 1);
|
||||
batadv_info(hard_iface->soft_iface, "Adding interface: %s\n",
|
||||
hard_iface->net_dev->name);
|
||||
|
||||
|
@ -36,7 +36,6 @@
|
||||
#include "gateway_client.h"
|
||||
#include "bridge_loop_avoidance.h"
|
||||
#include "distributed-arp-table.h"
|
||||
#include "unicast.h"
|
||||
#include "gateway_common.h"
|
||||
#include "hash.h"
|
||||
#include "bat_algo.h"
|
||||
@ -399,7 +398,6 @@ static void batadv_recv_handler_init(void)
|
||||
/* compile time checks for struct member offsets */
|
||||
BUILD_BUG_ON(offsetof(struct batadv_unicast_4addr_packet, src) != 10);
|
||||
BUILD_BUG_ON(offsetof(struct batadv_unicast_packet, dest) != 4);
|
||||
BUILD_BUG_ON(offsetof(struct batadv_unicast_frag_packet, dest) != 4);
|
||||
BUILD_BUG_ON(offsetof(struct batadv_unicast_tvlv_packet, dst) != 4);
|
||||
BUILD_BUG_ON(offsetof(struct batadv_icmp_packet, dst) != 4);
|
||||
BUILD_BUG_ON(offsetof(struct batadv_icmp_packet_rr, dst) != 4);
|
||||
@ -412,8 +410,6 @@ static void batadv_recv_handler_init(void)
|
||||
batadv_rx_handler[BATADV_UNICAST_4ADDR] = batadv_recv_unicast_packet;
|
||||
/* unicast packet */
|
||||
batadv_rx_handler[BATADV_UNICAST] = batadv_recv_unicast_packet;
|
||||
/* fragmented unicast packet */
|
||||
batadv_rx_handler[BATADV_UNICAST_FRAG] = batadv_recv_ucast_frag_packet;
|
||||
/* unicast tvlv packet */
|
||||
batadv_rx_handler[BATADV_UNICAST_TVLV] = batadv_recv_unicast_tvlv;
|
||||
/* batman icmp packet */
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include "routing.h"
|
||||
#include "gateway_client.h"
|
||||
#include "hard-interface.h"
|
||||
#include "unicast.h"
|
||||
#include "soft-interface.h"
|
||||
#include "bridge_loop_avoidance.h"
|
||||
#include "network-coding.h"
|
||||
@ -146,7 +145,6 @@ static void batadv_orig_node_free_rcu(struct rcu_head *rcu)
|
||||
/* Free nc_nodes */
|
||||
batadv_nc_purge_orig(orig_node->bat_priv, orig_node, NULL);
|
||||
|
||||
batadv_frag_list_free(&orig_node->frag_list);
|
||||
batadv_tt_global_del_orig(orig_node->bat_priv, orig_node,
|
||||
"originator timed out");
|
||||
|
||||
@ -269,9 +267,6 @@ struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv,
|
||||
size = bat_priv->num_ifaces * sizeof(uint8_t);
|
||||
orig_node->bcast_own_sum = kzalloc(size, GFP_ATOMIC);
|
||||
|
||||
INIT_LIST_HEAD(&orig_node->frag_list);
|
||||
orig_node->last_frag_packet = 0;
|
||||
|
||||
if (!orig_node->bcast_own_sum)
|
||||
goto free_bcast_own;
|
||||
|
||||
@ -393,10 +388,6 @@ static void _batadv_purge_orig(struct batadv_priv *bat_priv)
|
||||
batadv_orig_node_free_ref(orig_node);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (batadv_has_timed_out(orig_node->last_frag_packet,
|
||||
BATADV_FRAG_TIMEOUT))
|
||||
batadv_frag_list_free(&orig_node->frag_list);
|
||||
}
|
||||
spin_unlock_bh(list_lock);
|
||||
}
|
||||
|
@ -91,12 +91,6 @@ enum batadv_icmp_packettype {
|
||||
BATADV_PARAMETER_PROBLEM = 12,
|
||||
};
|
||||
|
||||
/* fragmentation defines */
|
||||
enum batadv_unicast_frag_flags {
|
||||
BATADV_UNI_FRAG_HEAD = BIT(0),
|
||||
BATADV_UNI_FRAG_LARGETAIL = BIT(1),
|
||||
};
|
||||
|
||||
/* tt data subtypes */
|
||||
#define BATADV_TT_DATA_TYPE_MASK 0x0F
|
||||
|
||||
@ -255,16 +249,6 @@ struct batadv_unicast_4addr_packet {
|
||||
*/
|
||||
};
|
||||
|
||||
struct batadv_unicast_frag_packet {
|
||||
struct batadv_header header;
|
||||
uint8_t ttvn; /* destination translation table version number */
|
||||
uint8_t dest[ETH_ALEN];
|
||||
uint8_t flags;
|
||||
uint8_t align;
|
||||
uint8_t orig[ETH_ALEN];
|
||||
__be16 seqno;
|
||||
} __packed;
|
||||
|
||||
struct batadv_bcast_packet {
|
||||
struct batadv_header header;
|
||||
uint8_t reserved;
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include "icmp_socket.h"
|
||||
#include "translation-table.h"
|
||||
#include "originator.h"
|
||||
#include "unicast.h"
|
||||
#include "bridge_loop_avoidance.h"
|
||||
#include "distributed-arp-table.h"
|
||||
#include "network-coding.h"
|
||||
@ -653,11 +652,9 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
|
||||
{
|
||||
struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
|
||||
struct batadv_orig_node *orig_node = NULL;
|
||||
struct batadv_neigh_node *neigh_node = NULL;
|
||||
struct batadv_unicast_packet *unicast_packet;
|
||||
struct ethhdr *ethhdr = eth_hdr(skb);
|
||||
int res, hdr_len, ret = NET_RX_DROP;
|
||||
struct sk_buff *new_skb;
|
||||
|
||||
unicast_packet = (struct batadv_unicast_packet *)skb->data;
|
||||
|
||||
@ -674,46 +671,12 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
|
||||
if (!orig_node)
|
||||
goto out;
|
||||
|
||||
/* find_router() increases neigh_nodes refcount if found. */
|
||||
neigh_node = batadv_find_router(bat_priv, orig_node, recv_if);
|
||||
|
||||
if (!neigh_node)
|
||||
goto out;
|
||||
|
||||
/* create a copy of the skb, if needed, to modify it. */
|
||||
if (skb_cow(skb, ETH_HLEN) < 0)
|
||||
goto out;
|
||||
|
||||
unicast_packet = (struct batadv_unicast_packet *)skb->data;
|
||||
|
||||
if (unicast_packet->header.packet_type == BATADV_UNICAST &&
|
||||
atomic_read(&bat_priv->fragmentation) &&
|
||||
skb->len > neigh_node->if_incoming->net_dev->mtu) {
|
||||
ret = batadv_frag_send_skb(skb, bat_priv,
|
||||
neigh_node->if_incoming,
|
||||
neigh_node->addr);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (unicast_packet->header.packet_type == BATADV_UNICAST_FRAG &&
|
||||
batadv_frag_can_reassemble(skb,
|
||||
neigh_node->if_incoming->net_dev->mtu)) {
|
||||
ret = batadv_frag_reassemble_skb(skb, bat_priv, &new_skb);
|
||||
|
||||
if (ret == NET_RX_DROP)
|
||||
goto out;
|
||||
|
||||
/* packet was buffered for late merge */
|
||||
if (!new_skb) {
|
||||
ret = NET_RX_SUCCESS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
skb = new_skb;
|
||||
unicast_packet = (struct batadv_unicast_packet *)skb->data;
|
||||
}
|
||||
|
||||
/* decrement ttl */
|
||||
unicast_packet = (struct batadv_unicast_packet *)skb->data;
|
||||
unicast_packet->header.ttl--;
|
||||
|
||||
switch (unicast_packet->header.packet_type) {
|
||||
@ -748,8 +711,6 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
|
||||
}
|
||||
|
||||
out:
|
||||
if (neigh_node)
|
||||
batadv_neigh_node_free_ref(neigh_node);
|
||||
if (orig_node)
|
||||
batadv_orig_node_free_ref(orig_node);
|
||||
return ret;
|
||||
@ -1003,51 +964,6 @@ int batadv_recv_unicast_packet(struct sk_buff *skb,
|
||||
return batadv_route_unicast_packet(skb, recv_if);
|
||||
}
|
||||
|
||||
int batadv_recv_ucast_frag_packet(struct sk_buff *skb,
|
||||
struct batadv_hard_iface *recv_if)
|
||||
{
|
||||
struct batadv_priv *bat_priv = netdev_priv(recv_if->soft_iface);
|
||||
struct batadv_unicast_frag_packet *unicast_packet;
|
||||
int hdr_size = sizeof(*unicast_packet);
|
||||
struct sk_buff *new_skb = NULL;
|
||||
int ret;
|
||||
|
||||
if (batadv_check_unicast_packet(bat_priv, skb, hdr_size) < 0)
|
||||
return NET_RX_DROP;
|
||||
|
||||
if (!batadv_check_unicast_ttvn(bat_priv, skb, hdr_size))
|
||||
return NET_RX_DROP;
|
||||
|
||||
unicast_packet = (struct batadv_unicast_frag_packet *)skb->data;
|
||||
|
||||
/* packet for me */
|
||||
if (batadv_is_my_mac(bat_priv, unicast_packet->dest)) {
|
||||
ret = batadv_frag_reassemble_skb(skb, bat_priv, &new_skb);
|
||||
|
||||
if (ret == NET_RX_DROP)
|
||||
return NET_RX_DROP;
|
||||
|
||||
/* packet was buffered for late merge */
|
||||
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;
|
||||
}
|
||||
|
||||
return batadv_route_unicast_packet(skb, recv_if);
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_recv_unicast_tvlv - receive and process unicast tvlv packets
|
||||
* @skb: unicast tvlv packet to process
|
||||
|
@ -30,8 +30,6 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
|
||||
struct batadv_hard_iface *recv_if);
|
||||
int batadv_recv_unicast_packet(struct sk_buff *skb,
|
||||
struct batadv_hard_iface *recv_if);
|
||||
int batadv_recv_ucast_frag_packet(struct sk_buff *skb,
|
||||
struct batadv_hard_iface *recv_if);
|
||||
int batadv_recv_bcast_packet(struct sk_buff *skb,
|
||||
struct batadv_hard_iface *recv_if);
|
||||
int batadv_recv_tt_query(struct sk_buff *skb,
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "soft-interface.h"
|
||||
#include "hard-interface.h"
|
||||
#include "gateway_common.h"
|
||||
#include "gateway_client.h"
|
||||
#include "originator.h"
|
||||
#include "network-coding.h"
|
||||
|
||||
@ -127,6 +128,179 @@ int batadv_send_skb_to_orig(struct sk_buff *skb,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_send_skb_push_fill_unicast - extend the buffer and initialize the
|
||||
* common fields for unicast packets
|
||||
* @skb: the skb carrying the unicast header to initialize
|
||||
* @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_send_skb_push_fill_unicast(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_send_skb_prepare_unicast - 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_send_skb_prepare_unicast(struct sk_buff *skb,
|
||||
struct batadv_orig_node *orig_node)
|
||||
{
|
||||
size_t uni_size = sizeof(struct batadv_unicast_packet);
|
||||
|
||||
return batadv_send_skb_push_fill_unicast(skb, uni_size, orig_node);
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_send_skb_prepare_unicast_4addr - encapsulate an skb with a
|
||||
* unicast 4addr 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 unicast 4addr packet subtype to use
|
||||
*
|
||||
* Returns false if the payload could not be encapsulated or true otherwise.
|
||||
*/
|
||||
bool batadv_send_skb_prepare_unicast_4addr(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 *uc_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 uc_4addr_packet
|
||||
* is of type struct unicast_packet
|
||||
*/
|
||||
if (!batadv_send_skb_push_fill_unicast(skb, sizeof(*uc_4addr_packet),
|
||||
orig))
|
||||
goto out;
|
||||
|
||||
uc_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data;
|
||||
uc_4addr_packet->u.header.packet_type = BATADV_UNICAST_4ADDR;
|
||||
memcpy(uc_4addr_packet->src, primary_if->net_dev->dev_addr, ETH_ALEN);
|
||||
uc_4addr_packet->subtype = packet_subtype;
|
||||
uc_4addr_packet->reserved = 0;
|
||||
|
||||
ret = true;
|
||||
out:
|
||||
if (primary_if)
|
||||
batadv_hardif_free_ref(primary_if);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_send_generic_unicast_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 unicast 4addr packet subtype (only relevant for unicast
|
||||
* 4addr packets)
|
||||
*
|
||||
* Returns 1 in case of error or 0 otherwise.
|
||||
*/
|
||||
int batadv_send_skb_generic_unicast(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;
|
||||
struct batadv_orig_node *orig_node;
|
||||
struct batadv_neigh_node *neigh_node;
|
||||
int ret = NET_RX_DROP;
|
||||
|
||||
/* get routing information */
|
||||
if (is_multicast_ether_addr(ethhdr->h_dest)) {
|
||||
orig_node = batadv_gw_get_selected_orig(bat_priv);
|
||||
if (orig_node)
|
||||
goto find_router;
|
||||
}
|
||||
|
||||
/* check for tt host - increases orig_node refcount.
|
||||
* returns NULL in case of AP isolation
|
||||
*/
|
||||
orig_node = batadv_transtable_search(bat_priv, ethhdr->h_source,
|
||||
ethhdr->h_dest);
|
||||
|
||||
find_router:
|
||||
/* find_router():
|
||||
* - if orig_node is NULL it returns NULL
|
||||
* - increases neigh_nodes refcount if found.
|
||||
*/
|
||||
neigh_node = batadv_find_router(bat_priv, orig_node, NULL);
|
||||
|
||||
if (!neigh_node)
|
||||
goto out;
|
||||
|
||||
switch (packet_type) {
|
||||
case BATADV_UNICAST:
|
||||
batadv_send_skb_prepare_unicast(skb, orig_node);
|
||||
break;
|
||||
case BATADV_UNICAST_4ADDR:
|
||||
batadv_send_skb_prepare_unicast_4addr(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;
|
||||
|
||||
/* 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
|
||||
* than the current one
|
||||
*/
|
||||
if (batadv_tt_global_client_is_roaming(bat_priv, ethhdr->h_dest))
|
||||
unicast_packet->ttvn = unicast_packet->ttvn - 1;
|
||||
|
||||
if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP)
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
if (neigh_node)
|
||||
batadv_neigh_node_free_ref(neigh_node);
|
||||
if (orig_node)
|
||||
batadv_orig_node_free_ref(orig_node);
|
||||
if (ret == NET_RX_DROP)
|
||||
kfree_skb(skb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void batadv_schedule_bat_ogm(struct batadv_hard_iface *hard_iface)
|
||||
{
|
||||
struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
|
||||
|
@ -34,5 +34,45 @@ void batadv_send_outstanding_bat_ogm_packet(struct work_struct *work);
|
||||
void
|
||||
batadv_purge_outstanding_packets(struct batadv_priv *bat_priv,
|
||||
const struct batadv_hard_iface *hard_iface);
|
||||
bool batadv_send_skb_prepare_unicast_4addr(struct batadv_priv *bat_priv,
|
||||
struct sk_buff *skb,
|
||||
struct batadv_orig_node *orig_node,
|
||||
int packet_subtype);
|
||||
int batadv_send_skb_generic_unicast(struct batadv_priv *bat_priv,
|
||||
struct sk_buff *skb, int packet_type,
|
||||
int packet_subtype);
|
||||
|
||||
|
||||
/**
|
||||
* batadv_send_unicast_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
|
||||
*
|
||||
* Returns 1 in case of error or 0 otherwise.
|
||||
*/
|
||||
static inline int batadv_send_skb_unicast(struct batadv_priv *bat_priv,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
return batadv_send_skb_generic_unicast(bat_priv, skb, BATADV_UNICAST,
|
||||
0);
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_send_4addr_unicast_skb - send the skb encapsulated in a unicast 4addr
|
||||
* packet
|
||||
* @bat_priv: the bat priv with all the soft interface information
|
||||
* @skb: the payload to send
|
||||
* @packet_subtype: the unicast 4addr packet subtype to use
|
||||
*
|
||||
* Returns 1 in case of error or 0 otherwise.
|
||||
*/
|
||||
static inline int batadv_send_skb_unicast_4addr(struct batadv_priv *bat_priv,
|
||||
struct sk_buff *skb,
|
||||
int packet_subtype)
|
||||
{
|
||||
return batadv_send_skb_generic_unicast(bat_priv, skb,
|
||||
BATADV_UNICAST_4ADDR,
|
||||
packet_subtype);
|
||||
}
|
||||
|
||||
#endif /* _NET_BATMAN_ADV_SEND_H_ */
|
||||
|
@ -34,8 +34,6 @@
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/if_vlan.h>
|
||||
#include <linux/if_ether.h>
|
||||
#include "unicast.h"
|
||||
#include "bridge_loop_avoidance.h"
|
||||
#include "network-coding.h"
|
||||
|
||||
@ -286,7 +284,7 @@ static int batadv_interface_tx(struct sk_buff *skb,
|
||||
|
||||
batadv_dat_snoop_outgoing_arp_reply(bat_priv, skb);
|
||||
|
||||
ret = batadv_unicast_send_skb(bat_priv, skb);
|
||||
ret = batadv_send_skb_unicast(bat_priv, skb);
|
||||
if (ret != 0)
|
||||
goto dropped_freed;
|
||||
}
|
||||
|
@ -60,7 +60,6 @@ struct batadv_hard_iface_bat_iv {
|
||||
* @if_num: identificator of the interface
|
||||
* @if_status: status of the interface for batman-adv
|
||||
* @net_dev: pointer to the net_device
|
||||
* @frag_seqno: last fragment sequence number sent by this interface
|
||||
* @num_bcasts: number of payload re-broadcasts on this interface (ARQ)
|
||||
* @hardif_obj: kobject of the per interface sysfs "mesh" directory
|
||||
* @refcount: number of contexts the object is used
|
||||
@ -76,7 +75,6 @@ struct batadv_hard_iface {
|
||||
int16_t if_num;
|
||||
char if_status;
|
||||
struct net_device *net_dev;
|
||||
atomic_t frag_seqno;
|
||||
uint8_t num_bcasts;
|
||||
struct kobject *hardif_obj;
|
||||
atomic_t refcount;
|
||||
@ -116,9 +114,6 @@ struct batadv_hard_iface {
|
||||
* last_bcast_seqno)
|
||||
* @last_bcast_seqno: last broadcast sequence number received by this host
|
||||
* @neigh_list: list of potential next hop neighbor towards this orig node
|
||||
* @frag_list: fragmentation buffer list for fragment re-assembly
|
||||
* @last_frag_packet: time when last fragmented packet from this node was
|
||||
* received
|
||||
* @neigh_list_lock: lock protecting neigh_list, router and bonding_list
|
||||
* @hash_entry: hlist node for batadv_priv::orig_hash
|
||||
* @bat_priv: pointer to soft_iface this orig node belongs to
|
||||
@ -159,8 +154,6 @@ struct batadv_orig_node {
|
||||
DECLARE_BITMAP(bcast_bits, BATADV_TQ_LOCAL_WINDOW_SIZE);
|
||||
uint32_t last_bcast_seqno;
|
||||
struct hlist_head neigh_list;
|
||||
struct list_head frag_list;
|
||||
unsigned long last_frag_packet;
|
||||
/* neigh_list_lock protects: neigh_list, router & bonding_list */
|
||||
spinlock_t neigh_list_lock;
|
||||
struct hlist_node hash_entry;
|
||||
@ -873,18 +866,6 @@ struct batadv_forw_packet {
|
||||
struct batadv_hard_iface *if_incoming;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct batadv_frag_packet_list_entry - storage for fragment packet
|
||||
* @list: list node for orig_node::frag_list
|
||||
* @seqno: sequence number of the fragment
|
||||
* @skb: fragment's skb buffer
|
||||
*/
|
||||
struct batadv_frag_packet_list_entry {
|
||||
struct list_head list;
|
||||
uint16_t seqno;
|
||||
struct sk_buff *skb;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct batadv_algo_ops - mesh algorithm callbacks
|
||||
* @list: list node for the batadv_algo_list
|
||||
|
@ -1,491 +0,0 @@
|
||||
/* Copyright (C) 2010-2013 B.A.T.M.A.N. contributors:
|
||||
*
|
||||
* Andreas Langer
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
#include "unicast.h"
|
||||
#include "send.h"
|
||||
#include "soft-interface.h"
|
||||
#include "gateway_client.h"
|
||||
#include "originator.h"
|
||||
#include "hash.h"
|
||||
#include "translation-table.h"
|
||||
#include "routing.h"
|
||||
#include "hard-interface.h"
|
||||
|
||||
|
||||
static struct sk_buff *
|
||||
batadv_frag_merge_packet(struct list_head *head,
|
||||
struct batadv_frag_packet_list_entry *tfp,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct batadv_unicast_frag_packet *up;
|
||||
struct sk_buff *tmp_skb;
|
||||
struct batadv_unicast_packet *unicast_packet;
|
||||
int hdr_len = sizeof(*unicast_packet);
|
||||
int uni_diff = sizeof(*up) - hdr_len;
|
||||
uint8_t *packet_pos;
|
||||
|
||||
up = (struct batadv_unicast_frag_packet *)skb->data;
|
||||
/* set skb to the first part and tmp_skb to the second part */
|
||||
if (up->flags & BATADV_UNI_FRAG_HEAD) {
|
||||
tmp_skb = tfp->skb;
|
||||
} else {
|
||||
tmp_skb = skb;
|
||||
skb = tfp->skb;
|
||||
}
|
||||
|
||||
if (skb_linearize(skb) < 0 || skb_linearize(tmp_skb) < 0)
|
||||
goto err;
|
||||
|
||||
skb_pull(tmp_skb, sizeof(*up));
|
||||
if (pskb_expand_head(skb, 0, tmp_skb->len, GFP_ATOMIC) < 0)
|
||||
goto err;
|
||||
|
||||
/* move free entry to end */
|
||||
tfp->skb = NULL;
|
||||
tfp->seqno = 0;
|
||||
list_move_tail(&tfp->list, head);
|
||||
|
||||
memcpy(skb_put(skb, tmp_skb->len), tmp_skb->data, tmp_skb->len);
|
||||
kfree_skb(tmp_skb);
|
||||
|
||||
memmove(skb->data + uni_diff, skb->data, hdr_len);
|
||||
packet_pos = skb_pull(skb, uni_diff);
|
||||
unicast_packet = (struct batadv_unicast_packet *)packet_pos;
|
||||
unicast_packet->header.packet_type = BATADV_UNICAST;
|
||||
|
||||
return skb;
|
||||
|
||||
err:
|
||||
/* free buffered skb, skb will be freed later */
|
||||
kfree_skb(tfp->skb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void batadv_frag_create_entry(struct list_head *head,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct batadv_frag_packet_list_entry *tfp;
|
||||
struct batadv_unicast_frag_packet *up;
|
||||
|
||||
up = (struct batadv_unicast_frag_packet *)skb->data;
|
||||
|
||||
/* free and oldest packets stand at the end */
|
||||
tfp = list_entry((head)->prev, typeof(*tfp), list);
|
||||
kfree_skb(tfp->skb);
|
||||
|
||||
tfp->seqno = ntohs(up->seqno);
|
||||
tfp->skb = skb;
|
||||
list_move(&tfp->list, head);
|
||||
return;
|
||||
}
|
||||
|
||||
static int batadv_frag_create_buffer(struct list_head *head)
|
||||
{
|
||||
int i;
|
||||
struct batadv_frag_packet_list_entry *tfp;
|
||||
|
||||
for (i = 0; i < BATADV_FRAG_BUFFER_SIZE; i++) {
|
||||
tfp = kmalloc(sizeof(*tfp), GFP_ATOMIC);
|
||||
if (!tfp) {
|
||||
batadv_frag_list_free(head);
|
||||
return -ENOMEM;
|
||||
}
|
||||
tfp->skb = NULL;
|
||||
tfp->seqno = 0;
|
||||
INIT_LIST_HEAD(&tfp->list);
|
||||
list_add(&tfp->list, head);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct batadv_frag_packet_list_entry *
|
||||
batadv_frag_search_packet(struct list_head *head,
|
||||
const struct batadv_unicast_frag_packet *up)
|
||||
{
|
||||
struct batadv_frag_packet_list_entry *tfp;
|
||||
struct batadv_unicast_frag_packet *tmp_up = NULL;
|
||||
bool is_head_tmp, is_head;
|
||||
uint16_t search_seqno;
|
||||
|
||||
if (up->flags & BATADV_UNI_FRAG_HEAD)
|
||||
search_seqno = ntohs(up->seqno)+1;
|
||||
else
|
||||
search_seqno = ntohs(up->seqno)-1;
|
||||
|
||||
is_head = up->flags & BATADV_UNI_FRAG_HEAD;
|
||||
|
||||
list_for_each_entry(tfp, head, list) {
|
||||
if (!tfp->skb)
|
||||
continue;
|
||||
|
||||
if (tfp->seqno == ntohs(up->seqno))
|
||||
goto mov_tail;
|
||||
|
||||
tmp_up = (struct batadv_unicast_frag_packet *)tfp->skb->data;
|
||||
|
||||
if (tfp->seqno == search_seqno) {
|
||||
is_head_tmp = tmp_up->flags & BATADV_UNI_FRAG_HEAD;
|
||||
if (is_head_tmp != is_head)
|
||||
return tfp;
|
||||
else
|
||||
goto mov_tail;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
||||
mov_tail:
|
||||
list_move_tail(&tfp->list, head);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void batadv_frag_list_free(struct list_head *head)
|
||||
{
|
||||
struct batadv_frag_packet_list_entry *pf, *tmp_pf;
|
||||
|
||||
if (!list_empty(head)) {
|
||||
list_for_each_entry_safe(pf, tmp_pf, head, list) {
|
||||
kfree_skb(pf->skb);
|
||||
list_del(&pf->list);
|
||||
kfree(pf);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* frag_reassemble_skb():
|
||||
* returns NET_RX_DROP if the operation failed - skb is left intact
|
||||
* returns NET_RX_SUCCESS if the fragment was buffered (skb_new will be NULL)
|
||||
* or the skb could be reassembled (skb_new will point to the new packet and
|
||||
* skb was freed)
|
||||
*/
|
||||
int batadv_frag_reassemble_skb(struct sk_buff *skb,
|
||||
struct batadv_priv *bat_priv,
|
||||
struct sk_buff **new_skb)
|
||||
{
|
||||
struct batadv_orig_node *orig_node;
|
||||
struct batadv_frag_packet_list_entry *tmp_frag_entry;
|
||||
int ret = NET_RX_DROP;
|
||||
struct batadv_unicast_frag_packet *unicast_packet;
|
||||
|
||||
unicast_packet = (struct batadv_unicast_frag_packet *)skb->data;
|
||||
*new_skb = NULL;
|
||||
|
||||
orig_node = batadv_orig_hash_find(bat_priv, unicast_packet->orig);
|
||||
if (!orig_node)
|
||||
goto out;
|
||||
|
||||
orig_node->last_frag_packet = jiffies;
|
||||
|
||||
if (list_empty(&orig_node->frag_list) &&
|
||||
batadv_frag_create_buffer(&orig_node->frag_list)) {
|
||||
pr_debug("couldn't create frag buffer\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
tmp_frag_entry = batadv_frag_search_packet(&orig_node->frag_list,
|
||||
unicast_packet);
|
||||
|
||||
if (!tmp_frag_entry) {
|
||||
batadv_frag_create_entry(&orig_node->frag_list, skb);
|
||||
ret = NET_RX_SUCCESS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
*new_skb = batadv_frag_merge_packet(&orig_node->frag_list,
|
||||
tmp_frag_entry, skb);
|
||||
/* if not, merge failed */
|
||||
if (*new_skb)
|
||||
ret = NET_RX_SUCCESS;
|
||||
|
||||
out:
|
||||
if (orig_node)
|
||||
batadv_orig_node_free_ref(orig_node);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int batadv_frag_send_skb(struct sk_buff *skb, struct batadv_priv *bat_priv,
|
||||
struct batadv_hard_iface *hard_iface,
|
||||
const uint8_t dstaddr[])
|
||||
{
|
||||
struct batadv_unicast_packet tmp_uc, *unicast_packet;
|
||||
struct batadv_hard_iface *primary_if;
|
||||
struct sk_buff *frag_skb;
|
||||
struct batadv_unicast_frag_packet *frag1, *frag2;
|
||||
int uc_hdr_len = sizeof(*unicast_packet);
|
||||
int ucf_hdr_len = sizeof(*frag1);
|
||||
int data_len = skb->len - uc_hdr_len;
|
||||
int large_tail = 0, ret = NET_RX_DROP;
|
||||
uint16_t seqno;
|
||||
|
||||
primary_if = batadv_primary_if_get_selected(bat_priv);
|
||||
if (!primary_if)
|
||||
goto dropped;
|
||||
|
||||
frag_skb = dev_alloc_skb(data_len - (data_len / 2) + ucf_hdr_len);
|
||||
if (!frag_skb)
|
||||
goto dropped;
|
||||
|
||||
skb->priority = TC_PRIO_CONTROL;
|
||||
skb_reserve(frag_skb, ucf_hdr_len);
|
||||
|
||||
unicast_packet = (struct batadv_unicast_packet *)skb->data;
|
||||
memcpy(&tmp_uc, unicast_packet, uc_hdr_len);
|
||||
skb_split(skb, frag_skb, data_len / 2 + uc_hdr_len);
|
||||
|
||||
if (batadv_skb_head_push(skb, ucf_hdr_len - uc_hdr_len) < 0 ||
|
||||
batadv_skb_head_push(frag_skb, ucf_hdr_len) < 0)
|
||||
goto drop_frag;
|
||||
|
||||
frag1 = (struct batadv_unicast_frag_packet *)skb->data;
|
||||
frag2 = (struct batadv_unicast_frag_packet *)frag_skb->data;
|
||||
|
||||
memcpy(frag1, &tmp_uc, sizeof(tmp_uc));
|
||||
|
||||
frag1->header.ttl--;
|
||||
frag1->header.version = BATADV_COMPAT_VERSION;
|
||||
frag1->header.packet_type = BATADV_UNICAST_FRAG;
|
||||
|
||||
memcpy(frag1->orig, primary_if->net_dev->dev_addr, ETH_ALEN);
|
||||
memcpy(frag2, frag1, sizeof(*frag2));
|
||||
|
||||
if (data_len & 1)
|
||||
large_tail = BATADV_UNI_FRAG_LARGETAIL;
|
||||
|
||||
frag1->flags = BATADV_UNI_FRAG_HEAD | large_tail;
|
||||
frag2->flags = large_tail;
|
||||
|
||||
seqno = atomic_add_return(2, &hard_iface->frag_seqno);
|
||||
frag1->seqno = htons(seqno - 1);
|
||||
frag2->seqno = htons(seqno);
|
||||
|
||||
batadv_send_skb_packet(skb, hard_iface, dstaddr);
|
||||
batadv_send_skb_packet(frag_skb, hard_iface, dstaddr);
|
||||
ret = NET_RX_SUCCESS;
|
||||
goto out;
|
||||
|
||||
drop_frag:
|
||||
kfree_skb(frag_skb);
|
||||
dropped:
|
||||
kfree_skb(skb);
|
||||
out:
|
||||
if (primary_if)
|
||||
batadv_hardif_free_ref(primary_if);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* This call might reallocate skb data.
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* This call might reallocate skb data.
|
||||
*/
|
||||
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;
|
||||
struct batadv_orig_node *orig_node;
|
||||
struct batadv_neigh_node *neigh_node;
|
||||
int data_len = skb->len;
|
||||
int ret = NET_RX_DROP;
|
||||
unsigned int dev_mtu, header_len;
|
||||
|
||||
/* get routing information */
|
||||
if (is_multicast_ether_addr(ethhdr->h_dest)) {
|
||||
orig_node = batadv_gw_get_selected_orig(bat_priv);
|
||||
if (orig_node)
|
||||
goto find_router;
|
||||
}
|
||||
|
||||
/* check for tt host - increases orig_node refcount.
|
||||
* returns NULL in case of AP isolation
|
||||
*/
|
||||
orig_node = batadv_transtable_search(bat_priv, ethhdr->h_source,
|
||||
ethhdr->h_dest);
|
||||
|
||||
find_router:
|
||||
/* find_router():
|
||||
* - if orig_node is NULL it returns NULL
|
||||
* - increases neigh_nodes refcount if found.
|
||||
*/
|
||||
neigh_node = batadv_find_router(bat_priv, orig_node, NULL);
|
||||
|
||||
if (!neigh_node)
|
||||
goto out;
|
||||
|
||||
switch (packet_type) {
|
||||
case BATADV_UNICAST:
|
||||
if (!batadv_unicast_prepare_skb(skb, orig_node))
|
||||
goto out;
|
||||
|
||||
header_len = sizeof(struct batadv_unicast_packet);
|
||||
break;
|
||||
case BATADV_UNICAST_4ADDR:
|
||||
if (!batadv_unicast_4addr_prepare_skb(bat_priv, skb, orig_node,
|
||||
packet_subtype))
|
||||
goto out;
|
||||
|
||||
header_len = sizeof(struct batadv_unicast_4addr_packet);
|
||||
break;
|
||||
default:
|
||||
/* this function supports UNICAST and UNICAST_4ADDR only. It
|
||||
* should never be invoked with any other packet type
|
||||
*/
|
||||
goto out;
|
||||
}
|
||||
|
||||
ethhdr = (struct ethhdr *)(skb->data + header_len);
|
||||
unicast_packet = (struct batadv_unicast_packet *)skb->data;
|
||||
|
||||
/* 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
|
||||
* than the current one
|
||||
*/
|
||||
if (batadv_tt_global_client_is_roaming(bat_priv, ethhdr->h_dest))
|
||||
unicast_packet->ttvn = unicast_packet->ttvn - 1;
|
||||
|
||||
dev_mtu = neigh_node->if_incoming->net_dev->mtu;
|
||||
/* 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++;
|
||||
ret = batadv_frag_send_skb(skb, bat_priv,
|
||||
neigh_node->if_incoming,
|
||||
neigh_node->addr);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP)
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
if (neigh_node)
|
||||
batadv_neigh_node_free_ref(neigh_node);
|
||||
if (orig_node)
|
||||
batadv_orig_node_free_ref(orig_node);
|
||||
if (ret == NET_RX_DROP)
|
||||
kfree_skb(skb);
|
||||
return ret;
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
/* Copyright (C) 2010-2013 B.A.T.M.A.N. contributors:
|
||||
*
|
||||
* Andreas Langer
|
||||
*
|
||||
* 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_UNICAST_H_
|
||||
#define _NET_BATMAN_ADV_UNICAST_H_
|
||||
|
||||
#include "packet.h"
|
||||
|
||||
#define BATADV_FRAG_TIMEOUT 10000 /* purge frag list entries after time in ms */
|
||||
#define BATADV_FRAG_BUFFER_SIZE 6 /* number of list elements in buffer */
|
||||
|
||||
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_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)
|
||||
{
|
||||
const struct batadv_unicast_frag_packet *unicast_packet;
|
||||
int uneven_correction = 0;
|
||||
unsigned int merged_size;
|
||||
|
||||
unicast_packet = (struct batadv_unicast_frag_packet *)skb->data;
|
||||
|
||||
if (unicast_packet->flags & BATADV_UNI_FRAG_LARGETAIL) {
|
||||
if (unicast_packet->flags & BATADV_UNI_FRAG_HEAD)
|
||||
uneven_correction = 1;
|
||||
else
|
||||
uneven_correction = -1;
|
||||
}
|
||||
|
||||
merged_size = (skb->len - sizeof(*unicast_packet)) * 2;
|
||||
merged_size += sizeof(struct batadv_unicast_packet) + uneven_correction;
|
||||
|
||||
return merged_size <= mtu;
|
||||
}
|
||||
|
||||
#endif /* _NET_BATMAN_ADV_UNICAST_H_ */
|
Loading…
Reference in New Issue
Block a user