Commit a230e033 authored by David S. Miller's avatar David S. Miller

Merge tag 'batman-adv-for-davem' of git://git.open-mesh.org/linux-merge

Included changes:
- reduce broadcast overhead on non-lossy wired links
- fix typos in kernel doc
- use eth_hdr() when possible
- use netdev_allock_skb_ip_align() and don't deal with NET_IP_ALIGN
- change VID semantic in the BLA component
- other minor cleanups and code refactoring
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents cbb963de 6715fd3f
...@@ -32,7 +32,6 @@ batman-adv-y += icmp_socket.o ...@@ -32,7 +32,6 @@ batman-adv-y += icmp_socket.o
batman-adv-y += main.o batman-adv-y += main.o
batman-adv-$(CONFIG_BATMAN_ADV_NC) += network-coding.o batman-adv-$(CONFIG_BATMAN_ADV_NC) += network-coding.o
batman-adv-y += originator.o batman-adv-y += originator.o
batman-adv-y += ring_buffer.o
batman-adv-y += routing.o batman-adv-y += routing.o
batman-adv-y += send.o batman-adv-y += send.o
batman-adv-y += soft-interface.o batman-adv-y += soft-interface.o
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
#include "main.h" #include "main.h"
#include "translation-table.h" #include "translation-table.h"
#include "ring_buffer.h"
#include "originator.h" #include "originator.h"
#include "routing.h" #include "routing.h"
#include "gateway_common.h" #include "gateway_common.h"
...@@ -29,16 +28,57 @@ ...@@ -29,16 +28,57 @@
#include "bat_algo.h" #include "bat_algo.h"
#include "network-coding.h" #include "network-coding.h"
/**
* batadv_ring_buffer_set - update the ring buffer with the given value
* @lq_recv: pointer to the ring buffer
* @lq_index: index to store the value at
* @value: value to store in the ring buffer
*/
static void batadv_ring_buffer_set(uint8_t lq_recv[], uint8_t *lq_index,
uint8_t value)
{
lq_recv[*lq_index] = value;
*lq_index = (*lq_index + 1) % BATADV_TQ_GLOBAL_WINDOW_SIZE;
}
/**
* batadv_ring_buffer_set - compute the average of all non-zero values stored
* in the given ring buffer
* @lq_recv: pointer to the ring buffer
*
* Returns computed average value.
*/
static uint8_t batadv_ring_buffer_avg(const uint8_t lq_recv[])
{
const uint8_t *ptr;
uint16_t count = 0, i = 0, sum = 0;
ptr = lq_recv;
while (i < BATADV_TQ_GLOBAL_WINDOW_SIZE) {
if (*ptr != 0) {
count++;
sum += *ptr;
}
i++;
ptr++;
}
if (count == 0)
return 0;
return (uint8_t)(sum / count);
}
static struct batadv_neigh_node * static struct batadv_neigh_node *
batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface, batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface,
const uint8_t *neigh_addr, const uint8_t *neigh_addr,
struct batadv_orig_node *orig_node, struct batadv_orig_node *orig_node,
struct batadv_orig_node *orig_neigh, __be32 seqno) struct batadv_orig_node *orig_neigh)
{ {
struct batadv_neigh_node *neigh_node; struct batadv_neigh_node *neigh_node;
neigh_node = batadv_neigh_node_new(hard_iface, neigh_addr, neigh_node = batadv_neigh_node_new(hard_iface, neigh_addr);
ntohl(seqno));
if (!neigh_node) if (!neigh_node)
goto out; goto out;
...@@ -413,18 +453,16 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff, ...@@ -413,18 +453,16 @@ static void batadv_iv_ogm_aggregate_new(const unsigned char *packet_buff,
else else
skb_size = packet_len; skb_size = packet_len;
skb_size += ETH_HLEN + NET_IP_ALIGN; skb_size += ETH_HLEN;
forw_packet_aggr->skb = dev_alloc_skb(skb_size); forw_packet_aggr->skb = netdev_alloc_skb_ip_align(NULL, skb_size);
if (!forw_packet_aggr->skb) { if (!forw_packet_aggr->skb) {
if (!own_packet) if (!own_packet)
atomic_inc(&bat_priv->batman_queue_left); atomic_inc(&bat_priv->batman_queue_left);
kfree(forw_packet_aggr); kfree(forw_packet_aggr);
goto out; goto out;
} }
skb_reserve(forw_packet_aggr->skb, ETH_HLEN + NET_IP_ALIGN); skb_reserve(forw_packet_aggr->skb, ETH_HLEN);
INIT_HLIST_NODE(&forw_packet_aggr->list);
skb_buff = skb_put(forw_packet_aggr->skb, packet_len); skb_buff = skb_put(forw_packet_aggr->skb, packet_len);
forw_packet_aggr->packet_len = packet_len; forw_packet_aggr->packet_len = packet_len;
...@@ -590,6 +628,41 @@ static void batadv_iv_ogm_forward(struct batadv_orig_node *orig_node, ...@@ -590,6 +628,41 @@ static void batadv_iv_ogm_forward(struct batadv_orig_node *orig_node,
if_incoming, 0, batadv_iv_ogm_fwd_send_time()); if_incoming, 0, batadv_iv_ogm_fwd_send_time());
} }
/**
* batadv_iv_ogm_slide_own_bcast_window - bitshift own OGM broadcast windows for
* the given interface
* @hard_iface: the interface for which the windows have to be shifted
*/
static void
batadv_iv_ogm_slide_own_bcast_window(struct batadv_hard_iface *hard_iface)
{
struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
struct batadv_hashtable *hash = bat_priv->orig_hash;
struct hlist_head *head;
struct batadv_orig_node *orig_node;
unsigned long *word;
uint32_t i;
size_t word_index;
uint8_t *w;
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
rcu_read_lock();
hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
spin_lock_bh(&orig_node->ogm_cnt_lock);
word_index = hard_iface->if_num * BATADV_NUM_WORDS;
word = &(orig_node->bcast_own[word_index]);
batadv_bit_get_packet(bat_priv, word, 1, 0);
w = &orig_node->bcast_own_sum[hard_iface->if_num];
*w = bitmap_weight(word, BATADV_TQ_LOCAL_WINDOW_SIZE);
spin_unlock_bh(&orig_node->ogm_cnt_lock);
}
rcu_read_unlock();
}
}
static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
{ {
struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
...@@ -634,7 +707,7 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface) ...@@ -634,7 +707,7 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
batadv_ogm_packet->gw_flags = BATADV_NO_FLAGS; batadv_ogm_packet->gw_flags = BATADV_NO_FLAGS;
} }
batadv_slide_own_bcast_window(hard_iface); batadv_iv_ogm_slide_own_bcast_window(hard_iface);
batadv_iv_ogm_queue_add(bat_priv, hard_iface->bat_iv.ogm_buff, batadv_iv_ogm_queue_add(bat_priv, hard_iface->bat_iv.ogm_buff,
hard_iface->bat_iv.ogm_buff_len, hard_iface, 1, hard_iface->bat_iv.ogm_buff_len, hard_iface, 1,
batadv_iv_ogm_emit_send_time(bat_priv)); batadv_iv_ogm_emit_send_time(bat_priv));
...@@ -670,7 +743,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv, ...@@ -670,7 +743,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
if (batadv_compare_eth(neigh_addr, ethhdr->h_source) && if (batadv_compare_eth(neigh_addr, ethhdr->h_source) &&
tmp_neigh_node->if_incoming == if_incoming && tmp_neigh_node->if_incoming == if_incoming &&
atomic_inc_not_zero(&tmp_neigh_node->refcount)) { atomic_inc_not_zero(&tmp_neigh_node->refcount)) {
if (neigh_node) if (WARN(neigh_node, "too many matching neigh_nodes"))
batadv_neigh_node_free_ref(neigh_node); batadv_neigh_node_free_ref(neigh_node);
neigh_node = tmp_neigh_node; neigh_node = tmp_neigh_node;
continue; continue;
...@@ -696,8 +769,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv, ...@@ -696,8 +769,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv,
neigh_node = batadv_iv_ogm_neigh_new(if_incoming, neigh_node = batadv_iv_ogm_neigh_new(if_incoming,
ethhdr->h_source, ethhdr->h_source,
orig_node, orig_tmp, orig_node, orig_tmp);
batadv_ogm_packet->seqno);
batadv_orig_node_free_ref(orig_tmp); batadv_orig_node_free_ref(orig_tmp);
if (!neigh_node) if (!neigh_node)
...@@ -829,8 +901,7 @@ static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, ...@@ -829,8 +901,7 @@ static int batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node,
neigh_node = batadv_iv_ogm_neigh_new(if_incoming, neigh_node = batadv_iv_ogm_neigh_new(if_incoming,
orig_neigh_node->orig, orig_neigh_node->orig,
orig_neigh_node, orig_neigh_node,
orig_neigh_node, orig_neigh_node);
batadv_ogm_packet->seqno);
if (!neigh_node) if (!neigh_node)
goto out; goto out;
...@@ -991,7 +1062,7 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, ...@@ -991,7 +1062,7 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
struct batadv_neigh_node *orig_neigh_router = NULL; struct batadv_neigh_node *orig_neigh_router = NULL;
int has_directlink_flag; int has_directlink_flag;
int is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0; int is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0;
int is_broadcast = 0, is_bidirect; int is_bidirect;
bool is_single_hop_neigh = false; bool is_single_hop_neigh = false;
bool is_from_best_next_hop = false; bool is_from_best_next_hop = false;
int is_duplicate, sameseq, simlar_ttl; int is_duplicate, sameseq, simlar_ttl;
...@@ -1054,19 +1125,9 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, ...@@ -1054,19 +1125,9 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
if (batadv_compare_eth(batadv_ogm_packet->prev_sender, if (batadv_compare_eth(batadv_ogm_packet->prev_sender,
hard_iface->net_dev->dev_addr)) hard_iface->net_dev->dev_addr))
is_my_oldorig = 1; is_my_oldorig = 1;
if (is_broadcast_ether_addr(ethhdr->h_source))
is_broadcast = 1;
} }
rcu_read_unlock(); rcu_read_unlock();
if (batadv_ogm_packet->header.version != BATADV_COMPAT_VERSION) {
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
"Drop packet: incompatible batman version (%i)\n",
batadv_ogm_packet->header.version);
return;
}
if (is_my_addr) { if (is_my_addr) {
batadv_dbg(BATADV_DBG_BATMAN, bat_priv, batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
"Drop packet: received my own broadcast (sender: %pM)\n", "Drop packet: received my own broadcast (sender: %pM)\n",
...@@ -1074,13 +1135,6 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, ...@@ -1074,13 +1135,6 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr,
return; return;
} }
if (is_broadcast) {
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
"Drop packet: ignoring all packets with broadcast source addr (sender: %pM)\n",
ethhdr->h_source);
return;
}
if (is_my_orig) { if (is_my_orig) {
unsigned long *word; unsigned long *word;
int offset; int offset;
...@@ -1288,7 +1342,7 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb, ...@@ -1288,7 +1342,7 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb,
skb->len + ETH_HLEN); skb->len + ETH_HLEN);
packet_len = skb_headlen(skb); packet_len = skb_headlen(skb);
ethhdr = (struct ethhdr *)skb_mac_header(skb); ethhdr = eth_hdr(skb);
packet_buff = skb->data; packet_buff = skb->data;
batadv_ogm_packet = (struct batadv_ogm_packet *)packet_buff; batadv_ogm_packet = (struct batadv_ogm_packet *)packet_buff;
......
This diff is collapsed.
...@@ -21,9 +21,10 @@ ...@@ -21,9 +21,10 @@
#define _NET_BATMAN_ADV_BLA_H_ #define _NET_BATMAN_ADV_BLA_H_
#ifdef CONFIG_BATMAN_ADV_BLA #ifdef CONFIG_BATMAN_ADV_BLA
int batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb, short vid, int batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
bool is_bcast); unsigned short vid, bool is_bcast);
int batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb, short vid); int batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb,
unsigned short vid);
int batadv_bla_is_backbone_gw(struct sk_buff *skb, int batadv_bla_is_backbone_gw(struct sk_buff *skb,
struct batadv_orig_node *orig_node, int hdr_size); struct batadv_orig_node *orig_node, int hdr_size);
int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset); int batadv_bla_claim_table_seq_print_text(struct seq_file *seq, void *offset);
...@@ -42,13 +43,14 @@ void batadv_bla_free(struct batadv_priv *bat_priv); ...@@ -42,13 +43,14 @@ void batadv_bla_free(struct batadv_priv *bat_priv);
#else /* ifdef CONFIG_BATMAN_ADV_BLA */ #else /* ifdef CONFIG_BATMAN_ADV_BLA */
static inline int batadv_bla_rx(struct batadv_priv *bat_priv, static inline int batadv_bla_rx(struct batadv_priv *bat_priv,
struct sk_buff *skb, short vid, bool is_bcast) struct sk_buff *skb, unsigned short vid,
bool is_bcast)
{ {
return 0; return 0;
} }
static inline int batadv_bla_tx(struct batadv_priv *bat_priv, static inline int batadv_bla_tx(struct batadv_priv *bat_priv,
struct sk_buff *skb, short vid) struct sk_buff *skb, unsigned short vid)
{ {
return 0; return 0;
} }
......
This diff is collapsed.
...@@ -117,6 +117,58 @@ static int batadv_is_valid_iface(const struct net_device *net_dev) ...@@ -117,6 +117,58 @@ static int batadv_is_valid_iface(const struct net_device *net_dev)
return 1; return 1;
} }
/**
* batadv_is_wifi_netdev - check if the given net_device struct is a wifi
* interface
* @net_device: the device to check
*
* Returns true if the net device is a 802.11 wireless device, false otherwise.
*/
static bool batadv_is_wifi_netdev(struct net_device *net_device)
{
#ifdef CONFIG_WIRELESS_EXT
/* pre-cfg80211 drivers have to implement WEXT, so it is possible to
* check for wireless_handlers != NULL
*/
if (net_device->wireless_handlers)
return true;
#endif
/* cfg80211 drivers have to set ieee80211_ptr */
if (net_device->ieee80211_ptr)
return true;
return false;
}
/**
* batadv_is_wifi_iface - check if the given interface represented by ifindex
* is a wifi interface
* @ifindex: interface index to check
*
* Returns true if the interface represented by ifindex is a 802.11 wireless
* device, false otherwise.
*/
bool batadv_is_wifi_iface(int ifindex)
{
struct net_device *net_device = NULL;
bool ret = false;
if (ifindex == BATADV_NULL_IFINDEX)
goto out;
net_device = dev_get_by_index(&init_net, ifindex);
if (!net_device)
goto out;
ret = batadv_is_wifi_netdev(net_device);
out:
if (net_device)
dev_put(net_device);
return ret;
}
static struct batadv_hard_iface * static struct batadv_hard_iface *
batadv_hardif_get_active(const struct net_device *soft_iface) batadv_hardif_get_active(const struct net_device *soft_iface)
{ {
...@@ -525,7 +577,7 @@ batadv_hardif_add_interface(struct net_device *net_dev) ...@@ -525,7 +577,7 @@ batadv_hardif_add_interface(struct net_device *net_dev)
dev_hold(net_dev); dev_hold(net_dev);
hard_iface = kmalloc(sizeof(*hard_iface), GFP_ATOMIC); hard_iface = kzalloc(sizeof(*hard_iface), GFP_ATOMIC);
if (!hard_iface) if (!hard_iface)
goto release_dev; goto release_dev;
...@@ -541,18 +593,16 @@ batadv_hardif_add_interface(struct net_device *net_dev) ...@@ -541,18 +593,16 @@ batadv_hardif_add_interface(struct net_device *net_dev)
INIT_WORK(&hard_iface->cleanup_work, INIT_WORK(&hard_iface->cleanup_work,
batadv_hardif_remove_interface_finish); batadv_hardif_remove_interface_finish);
hard_iface->num_bcasts = BATADV_NUM_BCASTS_DEFAULT;
if (batadv_is_wifi_netdev(net_dev))
hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS;
/* extra reference for return */ /* extra reference for return */
atomic_set(&hard_iface->refcount, 2); atomic_set(&hard_iface->refcount, 2);
batadv_check_known_mac_addr(hard_iface->net_dev); batadv_check_known_mac_addr(hard_iface->net_dev);
list_add_tail_rcu(&hard_iface->list, &batadv_hardif_list); list_add_tail_rcu(&hard_iface->list, &batadv_hardif_list);
/* This can't be called via a bat_priv callback because
* we have no bat_priv yet.
*/
atomic_set(&hard_iface->bat_iv.ogm_seqno, 1);
hard_iface->bat_iv.ogm_buff = NULL;
return hard_iface; return hard_iface;
free_if: free_if:
...@@ -657,38 +707,6 @@ static int batadv_hard_if_event(struct notifier_block *this, ...@@ -657,38 +707,6 @@ static int batadv_hard_if_event(struct notifier_block *this,
return NOTIFY_DONE; return NOTIFY_DONE;
} }
/* This function returns true if the interface represented by ifindex is a
* 802.11 wireless device
*/
bool batadv_is_wifi_iface(int ifindex)
{
struct net_device *net_device = NULL;
bool ret = false;
if (ifindex == BATADV_NULL_IFINDEX)
goto out;
net_device = dev_get_by_index(&init_net, ifindex);
if (!net_device)
goto out;
#ifdef CONFIG_WIRELESS_EXT
/* pre-cfg80211 drivers have to implement WEXT, so it is possible to
* check for wireless_handlers != NULL
*/
if (net_device->wireless_handlers)
ret = true;
else
#endif
/* cfg80211 drivers have to set ieee80211_ptr */
if (net_device->ieee80211_ptr)
ret = true;
out:
if (net_device)
dev_put(net_device);
return ret;
}
struct notifier_block batadv_hard_if_notifier = { struct notifier_block batadv_hard_if_notifier = {
.notifier_call = batadv_hard_if_event, .notifier_call = batadv_hard_if_event,
}; };
...@@ -177,13 +177,13 @@ static ssize_t batadv_socket_write(struct file *file, const char __user *buff, ...@@ -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 + NET_IP_ALIGN); skb = netdev_alloc_skb_ip_align(NULL, packet_len + ETH_HLEN);
if (!skb) { if (!skb) {
len = -ENOMEM; len = -ENOMEM;
goto out; goto out;
} }
skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN); skb_reserve(skb, ETH_HLEN);
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)) {
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#define BATADV_DRIVER_DEVICE "batman-adv" #define BATADV_DRIVER_DEVICE "batman-adv"
#ifndef BATADV_SOURCE_VERSION #ifndef BATADV_SOURCE_VERSION
#define BATADV_SOURCE_VERSION "2013.2.0" #define BATADV_SOURCE_VERSION "2013.3.0"
#endif #endif
/* B.A.T.M.A.N. parameters */ /* B.A.T.M.A.N. parameters */
...@@ -76,6 +76,11 @@ ...@@ -76,6 +76,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 */
/* number of packets to send for broadcasts on different interface types */
#define BATADV_NUM_BCASTS_DEFAULT 1
#define BATADV_NUM_BCASTS_WIRELESS 3
#define BATADV_NUM_BCASTS_MAX 3
/* msecs after which an ARP_REQUEST is sent in broadcast as fallback */ /* msecs after which an ARP_REQUEST is sent in broadcast as fallback */
#define ARP_REQ_DELAY 250 #define ARP_REQ_DELAY 250
/* numbers of originator to contact for any PUT/GET DHT operation */ /* numbers of originator to contact for any PUT/GET DHT operation */
...@@ -157,6 +162,17 @@ enum batadv_uev_type { ...@@ -157,6 +162,17 @@ enum batadv_uev_type {
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include "types.h" #include "types.h"
/**
* batadv_vlan_flags - flags for the four MSB of any vlan ID field
* @BATADV_VLAN_HAS_TAG: whether the field contains a valid vlan tag or not
*/
enum batadv_vlan_flags {
BATADV_VLAN_HAS_TAG = BIT(15),
};
#define BATADV_PRINT_VID(vid) (vid & BATADV_VLAN_HAS_TAG ? \
(int)(vid & VLAN_VID_MASK) : -1)
extern char batadv_routing_algo[]; extern char batadv_routing_algo[];
extern struct list_head batadv_hardif_list; extern struct list_head batadv_hardif_list;
......
...@@ -1245,7 +1245,7 @@ static void batadv_nc_skb_store_before_coding(struct batadv_priv *bat_priv, ...@@ -1245,7 +1245,7 @@ static void batadv_nc_skb_store_before_coding(struct batadv_priv *bat_priv,
return; return;
/* Set the mac header as if we actually sent the packet uncoded */ /* Set the mac header as if we actually sent the packet uncoded */
ethhdr = (struct ethhdr *)skb_mac_header(skb); ethhdr = eth_hdr(skb);
memcpy(ethhdr->h_source, ethhdr->h_dest, ETH_ALEN); memcpy(ethhdr->h_source, ethhdr->h_dest, ETH_ALEN);
memcpy(ethhdr->h_dest, eth_dst_new, ETH_ALEN); memcpy(ethhdr->h_dest, eth_dst_new, ETH_ALEN);
...@@ -1359,18 +1359,17 @@ static bool batadv_nc_skb_add_to_path(struct sk_buff *skb, ...@@ -1359,18 +1359,17 @@ static bool batadv_nc_skb_add_to_path(struct sk_buff *skb,
* buffer * buffer
* @skb: data skb to forward * @skb: data skb to forward
* @neigh_node: next hop to forward packet to * @neigh_node: next hop to forward packet to
* @ethhdr: pointer to the ethernet header inside the skb
* *
* Returns true if the skb was consumed (encoded packet sent) or false otherwise * Returns true if the skb was consumed (encoded packet sent) or false otherwise
*/ */
bool batadv_nc_skb_forward(struct sk_buff *skb, bool batadv_nc_skb_forward(struct sk_buff *skb,
struct batadv_neigh_node *neigh_node, struct batadv_neigh_node *neigh_node)
struct ethhdr *ethhdr)
{ {
const struct net_device *netdev = neigh_node->if_incoming->soft_iface; const struct net_device *netdev = neigh_node->if_incoming->soft_iface;
struct batadv_priv *bat_priv = netdev_priv(netdev); struct batadv_priv *bat_priv = netdev_priv(netdev);
struct batadv_unicast_packet *packet; struct batadv_unicast_packet *packet;
struct batadv_nc_path *nc_path; struct batadv_nc_path *nc_path;
struct ethhdr *ethhdr = eth_hdr(skb);
__be32 packet_id; __be32 packet_id;
u8 *payload; u8 *payload;
...@@ -1423,7 +1422,7 @@ void batadv_nc_skb_store_for_decoding(struct batadv_priv *bat_priv, ...@@ -1423,7 +1422,7 @@ void batadv_nc_skb_store_for_decoding(struct batadv_priv *bat_priv,
{ {
struct batadv_unicast_packet *packet; struct batadv_unicast_packet *packet;
struct batadv_nc_path *nc_path; struct batadv_nc_path *nc_path;
struct ethhdr *ethhdr = (struct ethhdr *)skb_mac_header(skb); struct ethhdr *ethhdr = eth_hdr(skb);
__be32 packet_id; __be32 packet_id;
u8 *payload; u8 *payload;
...@@ -1482,7 +1481,7 @@ void batadv_nc_skb_store_for_decoding(struct batadv_priv *bat_priv, ...@@ -1482,7 +1481,7 @@ void batadv_nc_skb_store_for_decoding(struct batadv_priv *bat_priv,
void batadv_nc_skb_store_sniffed_unicast(struct batadv_priv *bat_priv, void batadv_nc_skb_store_sniffed_unicast(struct batadv_priv *bat_priv,
struct sk_buff *skb) struct sk_buff *skb)
{ {
struct ethhdr *ethhdr = (struct ethhdr *)skb_mac_header(skb); struct ethhdr *ethhdr = eth_hdr(skb);
if (batadv_is_my_mac(bat_priv, ethhdr->h_dest)) if (batadv_is_my_mac(bat_priv, ethhdr->h_dest))
return; return;
...@@ -1533,7 +1532,7 @@ batadv_nc_skb_decode_packet(struct batadv_priv *bat_priv, struct sk_buff *skb, ...@@ -1533,7 +1532,7 @@ batadv_nc_skb_decode_packet(struct batadv_priv *bat_priv, struct sk_buff *skb,
skb_reset_network_header(skb); skb_reset_network_header(skb);
/* Reconstruct original mac header */ /* Reconstruct original mac header */
ethhdr = (struct ethhdr *)skb_mac_header(skb); ethhdr = eth_hdr(skb);
memcpy(ethhdr, &ethhdr_tmp, sizeof(*ethhdr)); memcpy(ethhdr, &ethhdr_tmp, sizeof(*ethhdr));
/* Select the correct unicast header information based on the location /* Select the correct unicast header information based on the location
...@@ -1677,7 +1676,7 @@ static int batadv_nc_recv_coded_packet(struct sk_buff *skb, ...@@ -1677,7 +1676,7 @@ static int batadv_nc_recv_coded_packet(struct sk_buff *skb,
return NET_RX_DROP; return NET_RX_DROP;
coded_packet = (struct batadv_coded_packet *)skb->data; coded_packet = (struct batadv_coded_packet *)skb->data;
ethhdr = (struct ethhdr *)skb_mac_header(skb); ethhdr = eth_hdr(skb);
/* Verify frame is destined for us */ /* Verify frame is destined for us */
if (!batadv_is_my_mac(bat_priv, ethhdr->h_dest) && if (!batadv_is_my_mac(bat_priv, ethhdr->h_dest) &&
...@@ -1763,6 +1762,13 @@ int batadv_nc_nodes_seq_print_text(struct seq_file *seq, void *offset) ...@@ -1763,6 +1762,13 @@ int batadv_nc_nodes_seq_print_text(struct seq_file *seq, void *offset)
/* For each orig_node in this bin */ /* For each orig_node in this bin */
rcu_read_lock(); rcu_read_lock();
hlist_for_each_entry_rcu(orig_node, head, hash_entry) { hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
/* no need to print the orig node if it does not have
* network coding neighbors
*/
if (list_empty(&orig_node->in_coding_list) &&
list_empty(&orig_node->out_coding_list))
continue;
seq_printf(seq, "Node: %pM\n", orig_node->orig); seq_printf(seq, "Node: %pM\n", orig_node->orig);
seq_puts(seq, " Ingoing: "); seq_puts(seq, " Ingoing: ");
......
...@@ -36,8 +36,7 @@ void batadv_nc_purge_orig(struct batadv_priv *bat_priv, ...@@ -36,8 +36,7 @@ void batadv_nc_purge_orig(struct batadv_priv *bat_priv,
void batadv_nc_init_bat_priv(struct batadv_priv *bat_priv); void batadv_nc_init_bat_priv(struct batadv_priv *bat_priv);
void batadv_nc_init_orig(struct batadv_orig_node *orig_node); void batadv_nc_init_orig(struct batadv_orig_node *orig_node);
bool batadv_nc_skb_forward(struct sk_buff *skb, bool batadv_nc_skb_forward(struct sk_buff *skb,
struct batadv_neigh_node *neigh_node, struct batadv_neigh_node *neigh_node);
struct ethhdr *ethhdr);
void batadv_nc_skb_store_for_decoding(struct batadv_priv *bat_priv, void batadv_nc_skb_store_for_decoding(struct batadv_priv *bat_priv,
struct sk_buff *skb); struct sk_buff *skb);
void batadv_nc_skb_store_sniffed_unicast(struct batadv_priv *bat_priv, void batadv_nc_skb_store_sniffed_unicast(struct batadv_priv *bat_priv,
...@@ -87,8 +86,7 @@ static inline void batadv_nc_init_orig(struct batadv_orig_node *orig_node) ...@@ -87,8 +86,7 @@ static inline void batadv_nc_init_orig(struct batadv_orig_node *orig_node)
} }
static inline bool batadv_nc_skb_forward(struct sk_buff *skb, static inline bool batadv_nc_skb_forward(struct sk_buff *skb,
struct batadv_neigh_node *neigh_node, struct batadv_neigh_node *neigh_node)
struct ethhdr *ethhdr)
{ {
return false; return false;
} }
......
...@@ -92,7 +92,7 @@ batadv_orig_node_get_router(struct batadv_orig_node *orig_node) ...@@ -92,7 +92,7 @@ batadv_orig_node_get_router(struct batadv_orig_node *orig_node)
struct batadv_neigh_node * struct batadv_neigh_node *
batadv_neigh_node_new(struct batadv_hard_iface *hard_iface, batadv_neigh_node_new(struct batadv_hard_iface *hard_iface,
const uint8_t *neigh_addr, uint32_t seqno) const uint8_t *neigh_addr)
{ {
struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface); struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
struct batadv_neigh_node *neigh_node; struct batadv_neigh_node *neigh_node;
...@@ -110,8 +110,8 @@ batadv_neigh_node_new(struct batadv_hard_iface *hard_iface, ...@@ -110,8 +110,8 @@ batadv_neigh_node_new(struct batadv_hard_iface *hard_iface,
atomic_set(&neigh_node->refcount, 2); atomic_set(&neigh_node->refcount, 2);
batadv_dbg(BATADV_DBG_BATMAN, bat_priv, batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
"Creating new neighbor %pM, initial seqno %d\n", "Creating new neighbor %pM on interface %s\n", neigh_addr,
neigh_addr, seqno); hard_iface->net_dev->name);
out: out:
return neigh_node; return neigh_node;
......
...@@ -31,7 +31,7 @@ struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv, ...@@ -31,7 +31,7 @@ struct batadv_orig_node *batadv_get_orig_node(struct batadv_priv *bat_priv,
const uint8_t *addr); const uint8_t *addr);
struct batadv_neigh_node * struct batadv_neigh_node *
batadv_neigh_node_new(struct batadv_hard_iface *hard_iface, batadv_neigh_node_new(struct batadv_hard_iface *hard_iface,
const uint8_t *neigh_addr, uint32_t seqno); const uint8_t *neigh_addr);
void batadv_neigh_node_free_ref(struct batadv_neigh_node *neigh_node); void batadv_neigh_node_free_ref(struct batadv_neigh_node *neigh_node);
struct batadv_neigh_node * struct batadv_neigh_node *
batadv_orig_node_get_router(struct batadv_orig_node *orig_node); batadv_orig_node_get_router(struct batadv_orig_node *orig_node);
......
/* Copyright (C) 2007-2013 B.A.T.M.A.N. contributors:
*
* Marek Lindner
*
* 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 "ring_buffer.h"
void batadv_ring_buffer_set(uint8_t lq_recv[], uint8_t *lq_index,
uint8_t value)
{
lq_recv[*lq_index] = value;
*lq_index = (*lq_index + 1) % BATADV_TQ_GLOBAL_WINDOW_SIZE;
}
uint8_t batadv_ring_buffer_avg(const uint8_t lq_recv[])
{
const uint8_t *ptr;
uint16_t count = 0, i = 0, sum = 0;
ptr = lq_recv;
while (i < BATADV_TQ_GLOBAL_WINDOW_SIZE) {
if (*ptr != 0) {
count++;
sum += *ptr;
}
i++;
ptr++;
}
if (count == 0)
return 0;
return (uint8_t)(sum / count);
}
/* Copyright (C) 2007-2013 B.A.T.M.A.N. contributors:
*
* Marek Lindner
*
* 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_RING_BUFFER_H_
#define _NET_BATMAN_ADV_RING_BUFFER_H_
void batadv_ring_buffer_set(uint8_t lq_recv[], uint8_t *lq_index,
uint8_t value);
uint8_t batadv_ring_buffer_avg(const uint8_t lq_recv[]);
#endif /* _NET_BATMAN_ADV_RING_BUFFER_H_ */
...@@ -34,35 +34,6 @@ ...@@ -34,35 +34,6 @@
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);
void batadv_slide_own_bcast_window(struct batadv_hard_iface *hard_iface)
{
struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
struct batadv_hashtable *hash = bat_priv->orig_hash;
struct hlist_head *head;
struct batadv_orig_node *orig_node;
unsigned long *word;
uint32_t i;
size_t word_index;
uint8_t *w;
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
rcu_read_lock();
hlist_for_each_entry_rcu(orig_node, head, hash_entry) {
spin_lock_bh(&orig_node->ogm_cnt_lock);
word_index = hard_iface->if_num * BATADV_NUM_WORDS;
word = &(orig_node->bcast_own[word_index]);
batadv_bit_get_packet(bat_priv, word, 1, 0);
w = &orig_node->bcast_own_sum[hard_iface->if_num];
*w = bitmap_weight(word, BATADV_TQ_LOCAL_WINDOW_SIZE);
spin_unlock_bh(&orig_node->ogm_cnt_lock);
}
rcu_read_unlock();
}
}
static void _batadv_update_route(struct batadv_priv *bat_priv, static void _batadv_update_route(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node, struct batadv_orig_node *orig_node,
struct batadv_neigh_node *neigh_node) struct batadv_neigh_node *neigh_node)
...@@ -256,7 +227,7 @@ bool batadv_check_management_packet(struct sk_buff *skb, ...@@ -256,7 +227,7 @@ bool batadv_check_management_packet(struct sk_buff *skb,
if (unlikely(!pskb_may_pull(skb, header_len))) if (unlikely(!pskb_may_pull(skb, header_len)))
return false; return false;
ethhdr = (struct ethhdr *)skb_mac_header(skb); ethhdr = eth_hdr(skb);
/* packet with broadcast indication but unicast recipient */ /* packet with broadcast indication but unicast recipient */
if (!is_broadcast_ether_addr(ethhdr->h_dest)) if (!is_broadcast_ether_addr(ethhdr->h_dest))
...@@ -314,7 +285,7 @@ static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv, ...@@ -314,7 +285,7 @@ static int batadv_recv_my_icmp_packet(struct batadv_priv *bat_priv,
icmp_packet->msg_type = BATADV_ECHO_REPLY; icmp_packet->msg_type = BATADV_ECHO_REPLY;
icmp_packet->header.ttl = BATADV_TTL; icmp_packet->header.ttl = BATADV_TTL;
if (batadv_send_skb_to_orig(skb, orig_node, NULL)) if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP)
ret = NET_RX_SUCCESS; ret = NET_RX_SUCCESS;
out: out:
...@@ -362,7 +333,7 @@ static int batadv_recv_icmp_ttl_exceeded(struct batadv_priv *bat_priv, ...@@ -362,7 +333,7 @@ static int batadv_recv_icmp_ttl_exceeded(struct batadv_priv *bat_priv,
icmp_packet->msg_type = BATADV_TTL_EXCEEDED; icmp_packet->msg_type = BATADV_TTL_EXCEEDED;
icmp_packet->header.ttl = BATADV_TTL; icmp_packet->header.ttl = BATADV_TTL;
if (batadv_send_skb_to_orig(skb, orig_node, NULL)) if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP)
ret = NET_RX_SUCCESS; ret = NET_RX_SUCCESS;
out: out:
...@@ -392,7 +363,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb, ...@@ -392,7 +363,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
if (unlikely(!pskb_may_pull(skb, hdr_size))) if (unlikely(!pskb_may_pull(skb, hdr_size)))
goto out; goto out;
ethhdr = (struct ethhdr *)skb_mac_header(skb); ethhdr = eth_hdr(skb);
/* packet with unicast indication but broadcast recipient */ /* packet with unicast indication but broadcast recipient */
if (is_broadcast_ether_addr(ethhdr->h_dest)) if (is_broadcast_ether_addr(ethhdr->h_dest))
...@@ -439,7 +410,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb, ...@@ -439,7 +410,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb,
icmp_packet->header.ttl--; icmp_packet->header.ttl--;
/* route it */ /* route it */
if (batadv_send_skb_to_orig(skb, orig_node, recv_if)) if (batadv_send_skb_to_orig(skb, orig_node, recv_if) != NET_XMIT_DROP)
ret = NET_RX_SUCCESS; ret = NET_RX_SUCCESS;
out: out:
...@@ -569,7 +540,7 @@ static int batadv_check_unicast_packet(struct batadv_priv *bat_priv, ...@@ -569,7 +540,7 @@ static int batadv_check_unicast_packet(struct batadv_priv *bat_priv,
if (unlikely(!pskb_may_pull(skb, hdr_size))) if (unlikely(!pskb_may_pull(skb, hdr_size)))
return -ENODATA; return -ENODATA;
ethhdr = (struct ethhdr *)skb_mac_header(skb); ethhdr = eth_hdr(skb);
/* packet with unicast indication but broadcast recipient */ /* packet with unicast indication but broadcast recipient */
if (is_broadcast_ether_addr(ethhdr->h_dest)) if (is_broadcast_ether_addr(ethhdr->h_dest))
...@@ -803,8 +774,8 @@ static int batadv_route_unicast_packet(struct sk_buff *skb, ...@@ -803,8 +774,8 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
struct batadv_orig_node *orig_node = NULL; struct batadv_orig_node *orig_node = NULL;
struct batadv_neigh_node *neigh_node = NULL; struct batadv_neigh_node *neigh_node = NULL;
struct batadv_unicast_packet *unicast_packet; struct batadv_unicast_packet *unicast_packet;
struct ethhdr *ethhdr = (struct ethhdr *)skb_mac_header(skb); struct ethhdr *ethhdr = eth_hdr(skb);
int ret = NET_RX_DROP; int res, ret = NET_RX_DROP;
struct sk_buff *new_skb; struct sk_buff *new_skb;
unicast_packet = (struct batadv_unicast_packet *)skb->data; unicast_packet = (struct batadv_unicast_packet *)skb->data;
...@@ -864,16 +835,19 @@ static int batadv_route_unicast_packet(struct sk_buff *skb, ...@@ -864,16 +835,19 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
/* decrement ttl */ /* decrement ttl */
unicast_packet->header.ttl--; unicast_packet->header.ttl--;
/* network code packet if possible */ res = batadv_send_skb_to_orig(skb, orig_node, recv_if);
if (batadv_nc_skb_forward(skb, neigh_node, ethhdr)) {
ret = NET_RX_SUCCESS;
} else if (batadv_send_skb_to_orig(skb, orig_node, recv_if)) {
ret = NET_RX_SUCCESS;
/* Update stats counter */ /* translate transmit result into receive result */
if (res == NET_XMIT_SUCCESS) {
/* skb was transmitted and consumed */
batadv_inc_counter(bat_priv, BATADV_CNT_FORWARD); batadv_inc_counter(bat_priv, BATADV_CNT_FORWARD);
batadv_add_counter(bat_priv, BATADV_CNT_FORWARD_BYTES, batadv_add_counter(bat_priv, BATADV_CNT_FORWARD_BYTES,
skb->len + ETH_HLEN); skb->len + ETH_HLEN);
ret = NET_RX_SUCCESS;
} else if (res == NET_XMIT_POLICED) {
/* skb was buffered and consumed */
ret = NET_RX_SUCCESS;
} }
out: out:
...@@ -1165,7 +1139,7 @@ int batadv_recv_bcast_packet(struct sk_buff *skb, ...@@ -1165,7 +1139,7 @@ int batadv_recv_bcast_packet(struct sk_buff *skb,
if (unlikely(!pskb_may_pull(skb, hdr_size))) if (unlikely(!pskb_may_pull(skb, hdr_size)))
goto out; goto out;
ethhdr = (struct ethhdr *)skb_mac_header(skb); ethhdr = eth_hdr(skb);
/* packet with broadcast indication but unicast recipient */ /* packet with broadcast indication but unicast recipient */
if (!is_broadcast_ether_addr(ethhdr->h_dest)) if (!is_broadcast_ether_addr(ethhdr->h_dest))
...@@ -1265,7 +1239,7 @@ int batadv_recv_vis_packet(struct sk_buff *skb, ...@@ -1265,7 +1239,7 @@ int batadv_recv_vis_packet(struct sk_buff *skb,
return NET_RX_DROP; return NET_RX_DROP;
vis_packet = (struct batadv_vis_packet *)skb->data; vis_packet = (struct batadv_vis_packet *)skb->data;
ethhdr = (struct ethhdr *)skb_mac_header(skb); ethhdr = eth_hdr(skb);
/* not for me */ /* not for me */
if (!batadv_is_my_mac(bat_priv, ethhdr->h_dest)) if (!batadv_is_my_mac(bat_priv, ethhdr->h_dest))
......
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
#ifndef _NET_BATMAN_ADV_ROUTING_H_ #ifndef _NET_BATMAN_ADV_ROUTING_H_
#define _NET_BATMAN_ADV_ROUTING_H_ #define _NET_BATMAN_ADV_ROUTING_H_
void batadv_slide_own_bcast_window(struct batadv_hard_iface *hard_iface);
bool batadv_check_management_packet(struct sk_buff *skb, bool batadv_check_management_packet(struct sk_buff *skb,
struct batadv_hard_iface *hard_iface, struct batadv_hard_iface *hard_iface,
int header_len); int header_len);
......
...@@ -61,7 +61,7 @@ int batadv_send_skb_packet(struct sk_buff *skb, ...@@ -61,7 +61,7 @@ int batadv_send_skb_packet(struct sk_buff *skb,
skb_reset_mac_header(skb); skb_reset_mac_header(skb);
ethhdr = (struct ethhdr *)skb_mac_header(skb); ethhdr = eth_hdr(skb);
memcpy(ethhdr->h_source, hard_iface->net_dev->dev_addr, ETH_ALEN); memcpy(ethhdr->h_source, hard_iface->net_dev->dev_addr, ETH_ALEN);
memcpy(ethhdr->h_dest, dst_addr, ETH_ALEN); memcpy(ethhdr->h_dest, dst_addr, ETH_ALEN);
ethhdr->h_proto = __constant_htons(ETH_P_BATMAN); ethhdr->h_proto = __constant_htons(ETH_P_BATMAN);
...@@ -96,26 +96,37 @@ int batadv_send_skb_packet(struct sk_buff *skb, ...@@ -96,26 +96,37 @@ int batadv_send_skb_packet(struct sk_buff *skb,
* host, NULL can be passed as recv_if and no interface alternating is * host, NULL can be passed as recv_if and no interface alternating is
* attempted. * attempted.
* *
* Returns TRUE on success; FALSE otherwise. * Returns NET_XMIT_SUCCESS on success, NET_XMIT_DROP on failure, or
* NET_XMIT_POLICED if the skb is buffered for later transmit.
*/ */
bool batadv_send_skb_to_orig(struct sk_buff *skb, int batadv_send_skb_to_orig(struct sk_buff *skb,
struct batadv_orig_node *orig_node, struct batadv_orig_node *orig_node,
struct batadv_hard_iface *recv_if) struct batadv_hard_iface *recv_if)
{ {
struct batadv_priv *bat_priv = orig_node->bat_priv; struct batadv_priv *bat_priv = orig_node->bat_priv;
struct batadv_neigh_node *neigh_node; struct batadv_neigh_node *neigh_node;
int ret = NET_XMIT_DROP;
/* batadv_find_router() increases neigh_nodes refcount if found. */ /* batadv_find_router() increases neigh_nodes refcount if found. */
neigh_node = batadv_find_router(bat_priv, orig_node, recv_if); neigh_node = batadv_find_router(bat_priv, orig_node, recv_if);
if (!neigh_node) if (!neigh_node)
return false; return ret;
/* route it */ /* try to network code the packet, if it is received on an interface
batadv_send_skb_packet(skb, neigh_node->if_incoming, neigh_node->addr); * (i.e. being forwarded). If the packet originates from this node or if
* network coding fails, then send the packet as usual.
*/
if (recv_if && batadv_nc_skb_forward(skb, neigh_node)) {
ret = NET_XMIT_POLICED;
} else {
batadv_send_skb_packet(skb, neigh_node->if_incoming,
neigh_node->addr);
ret = NET_XMIT_SUCCESS;
}
batadv_neigh_node_free_ref(neigh_node); batadv_neigh_node_free_ref(neigh_node);
return true; return ret;
} }
void batadv_schedule_bat_ogm(struct batadv_hard_iface *hard_iface) void batadv_schedule_bat_ogm(struct batadv_hard_iface *hard_iface)
...@@ -152,8 +163,6 @@ _batadv_add_bcast_packet_to_list(struct batadv_priv *bat_priv, ...@@ -152,8 +163,6 @@ _batadv_add_bcast_packet_to_list(struct batadv_priv *bat_priv,
struct batadv_forw_packet *forw_packet, struct batadv_forw_packet *forw_packet,
unsigned long send_time) unsigned long send_time)
{ {
INIT_HLIST_NODE(&forw_packet->list);
/* add new packet to packet list */ /* add new packet to packet list */
spin_lock_bh(&bat_priv->forw_bcast_list_lock); spin_lock_bh(&bat_priv->forw_bcast_list_lock);
hlist_add_head(&forw_packet->list, &bat_priv->forw_bcast_list); hlist_add_head(&forw_packet->list, &bat_priv->forw_bcast_list);
...@@ -260,6 +269,9 @@ static void batadv_send_outstanding_bcast_packet(struct work_struct *work) ...@@ -260,6 +269,9 @@ static void batadv_send_outstanding_bcast_packet(struct work_struct *work)
if (hard_iface->soft_iface != soft_iface) if (hard_iface->soft_iface != soft_iface)
continue; continue;
if (forw_packet->num_packets >= hard_iface->num_bcasts)
continue;
/* send a copy of the saved skb */ /* send a copy of the saved skb */
skb1 = skb_clone(forw_packet->skb, GFP_ATOMIC); skb1 = skb_clone(forw_packet->skb, GFP_ATOMIC);
if (skb1) if (skb1)
...@@ -271,7 +283,7 @@ static void batadv_send_outstanding_bcast_packet(struct work_struct *work) ...@@ -271,7 +283,7 @@ static void batadv_send_outstanding_bcast_packet(struct work_struct *work)
forw_packet->num_packets++; forw_packet->num_packets++;
/* if we still have some more bcasts to send */ /* if we still have some more bcasts to send */
if (forw_packet->num_packets < 3) { if (forw_packet->num_packets < BATADV_NUM_BCASTS_MAX) {
_batadv_add_bcast_packet_to_list(bat_priv, forw_packet, _batadv_add_bcast_packet_to_list(bat_priv, forw_packet,
msecs_to_jiffies(5)); msecs_to_jiffies(5));
return; return;
......
...@@ -23,9 +23,9 @@ ...@@ -23,9 +23,9 @@
int batadv_send_skb_packet(struct sk_buff *skb, int batadv_send_skb_packet(struct sk_buff *skb,
struct batadv_hard_iface *hard_iface, struct batadv_hard_iface *hard_iface,
const uint8_t *dst_addr); const uint8_t *dst_addr);
bool batadv_send_skb_to_orig(struct sk_buff *skb, int batadv_send_skb_to_orig(struct sk_buff *skb,
struct batadv_orig_node *orig_node, struct batadv_orig_node *orig_node,
struct batadv_hard_iface *recv_if); struct batadv_hard_iface *recv_if);
void batadv_schedule_bat_ogm(struct batadv_hard_iface *hard_iface); void batadv_schedule_bat_ogm(struct batadv_hard_iface *hard_iface);
int batadv_add_bcast_packet_to_list(struct batadv_priv *bat_priv, int batadv_add_bcast_packet_to_list(struct batadv_priv *bat_priv,
const struct sk_buff *skb, const struct sk_buff *skb,
......
...@@ -154,7 +154,7 @@ static int batadv_interface_tx(struct sk_buff *skb, ...@@ -154,7 +154,7 @@ static int batadv_interface_tx(struct sk_buff *skb,
0x00, 0x00}; 0x00, 0x00};
unsigned int header_len = 0; unsigned int header_len = 0;
int data_len = skb->len, ret; int data_len = skb->len, ret;
short vid __maybe_unused = -1; unsigned short vid __maybe_unused = BATADV_NO_FLAGS;
bool do_bcast = false; bool do_bcast = false;
uint32_t seqno; uint32_t seqno;
unsigned long brd_delay = 1; unsigned long brd_delay = 1;
...@@ -303,7 +303,7 @@ void batadv_interface_rx(struct net_device *soft_iface, ...@@ -303,7 +303,7 @@ void batadv_interface_rx(struct net_device *soft_iface,
struct ethhdr *ethhdr; struct ethhdr *ethhdr;
struct vlan_ethhdr *vhdr; struct vlan_ethhdr *vhdr;
struct batadv_header *batadv_header = (struct batadv_header *)skb->data; struct batadv_header *batadv_header = (struct batadv_header *)skb->data;
short vid __maybe_unused = -1; unsigned short vid __maybe_unused = BATADV_NO_FLAGS;
__be16 ethertype = __constant_htons(ETH_P_BATMAN); __be16 ethertype = __constant_htons(ETH_P_BATMAN);
bool is_bcast; bool is_bcast;
...@@ -316,7 +316,7 @@ void batadv_interface_rx(struct net_device *soft_iface, ...@@ -316,7 +316,7 @@ void batadv_interface_rx(struct net_device *soft_iface,
skb_pull_rcsum(skb, hdr_size); skb_pull_rcsum(skb, hdr_size);
skb_reset_mac_header(skb); skb_reset_mac_header(skb);
ethhdr = (struct ethhdr *)skb_mac_header(skb); ethhdr = eth_hdr(skb);
switch (ntohs(ethhdr->h_proto)) { switch (ntohs(ethhdr->h_proto)) {
case ETH_P_8021Q: case ETH_P_8021Q:
......
...@@ -163,10 +163,19 @@ batadv_tt_orig_list_entry_free_ref(struct batadv_tt_orig_list_entry *orig_entry) ...@@ -163,10 +163,19 @@ batadv_tt_orig_list_entry_free_ref(struct batadv_tt_orig_list_entry *orig_entry)
call_rcu(&orig_entry->rcu, batadv_tt_orig_list_entry_free_rcu); call_rcu(&orig_entry->rcu, batadv_tt_orig_list_entry_free_rcu);
} }
/**
* batadv_tt_local_event - store a local TT event (ADD/DEL)
* @bat_priv: the bat priv with all the soft interface information
* @tt_local_entry: the TT entry involved in the event
* @event_flags: flags to store in the event structure
*/
static void batadv_tt_local_event(struct batadv_priv *bat_priv, static void batadv_tt_local_event(struct batadv_priv *bat_priv,
const uint8_t *addr, uint8_t flags) struct batadv_tt_local_entry *tt_local_entry,
uint8_t event_flags)
{ {
struct batadv_tt_change_node *tt_change_node, *entry, *safe; struct batadv_tt_change_node *tt_change_node, *entry, *safe;
struct batadv_tt_common_entry *common = &tt_local_entry->common;
uint8_t flags = common->flags | event_flags;
bool event_removed = false; bool event_removed = false;
bool del_op_requested, del_op_entry; bool del_op_requested, del_op_entry;
...@@ -176,7 +185,7 @@ static void batadv_tt_local_event(struct batadv_priv *bat_priv, ...@@ -176,7 +185,7 @@ static void batadv_tt_local_event(struct batadv_priv *bat_priv,
return; return;
tt_change_node->change.flags = flags; tt_change_node->change.flags = flags;
memcpy(tt_change_node->change.addr, addr, ETH_ALEN); memcpy(tt_change_node->change.addr, common->addr, ETH_ALEN);
del_op_requested = flags & BATADV_TT_CLIENT_DEL; del_op_requested = flags & BATADV_TT_CLIENT_DEL;
...@@ -184,7 +193,7 @@ static void batadv_tt_local_event(struct batadv_priv *bat_priv, ...@@ -184,7 +193,7 @@ static void batadv_tt_local_event(struct batadv_priv *bat_priv,
spin_lock_bh(&bat_priv->tt.changes_list_lock); spin_lock_bh(&bat_priv->tt.changes_list_lock);
list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list, list_for_each_entry_safe(entry, safe, &bat_priv->tt.changes_list,
list) { list) {
if (!batadv_compare_eth(entry->change.addr, addr)) if (!batadv_compare_eth(entry->change.addr, common->addr))
continue; continue;
/* DEL+ADD in the same orig interval have no effect and can be /* DEL+ADD in the same orig interval have no effect and can be
...@@ -332,7 +341,7 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr, ...@@ -332,7 +341,7 @@ void batadv_tt_local_add(struct net_device *soft_iface, const uint8_t *addr,
} }
add_event: add_event:
batadv_tt_local_event(bat_priv, addr, tt_local->common.flags); batadv_tt_local_event(bat_priv, tt_local, BATADV_NO_FLAGS);
check_roaming: check_roaming:
/* Check whether it is a roaming, but don't do anything if the roaming /* Check whether it is a roaming, but don't do anything if the roaming
...@@ -529,8 +538,7 @@ batadv_tt_local_set_pending(struct batadv_priv *bat_priv, ...@@ -529,8 +538,7 @@ batadv_tt_local_set_pending(struct batadv_priv *bat_priv,
struct batadv_tt_local_entry *tt_local_entry, struct batadv_tt_local_entry *tt_local_entry,
uint16_t flags, const char *message) uint16_t flags, const char *message)
{ {
batadv_tt_local_event(bat_priv, tt_local_entry->common.addr, batadv_tt_local_event(bat_priv, tt_local_entry, flags);
tt_local_entry->common.flags | flags);
/* The local client has to be marked as "pending to be removed" but has /* The local client has to be marked as "pending to be removed" but has
* to be kept in the table in order to send it in a full table * to be kept in the table in order to send it in a full table
...@@ -584,8 +592,7 @@ uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv, ...@@ -584,8 +592,7 @@ uint16_t batadv_tt_local_remove(struct batadv_priv *bat_priv,
/* if this client has been added right now, it is possible to /* if this client has been added right now, it is possible to
* immediately purge it * immediately purge it
*/ */
batadv_tt_local_event(bat_priv, tt_local_entry->common.addr, batadv_tt_local_event(bat_priv, tt_local_entry, BATADV_TT_CLIENT_DEL);
curr_flags | BATADV_TT_CLIENT_DEL);
hlist_del_rcu(&tt_local_entry->common.hash_entry); hlist_del_rcu(&tt_local_entry->common.hash_entry);
batadv_tt_local_entry_free_ref(tt_local_entry); batadv_tt_local_entry_free_ref(tt_local_entry);
...@@ -791,10 +798,25 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global, ...@@ -791,10 +798,25 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
batadv_tt_orig_list_entry_free_ref(orig_entry); batadv_tt_orig_list_entry_free_ref(orig_entry);
} }
/* caller must hold orig_node refcount */ /**
* batadv_tt_global_add - add a new TT global entry or update an existing one
* @bat_priv: the bat priv with all the soft interface information
* @orig_node: the originator announcing the client
* @tt_addr: the mac address of the non-mesh client
* @flags: TT flags that have to be set for this non-mesh client
* @ttvn: the tt version number ever announcing this non-mesh client
*
* Add a new TT global entry for the given originator. If the entry already
* exists add a new reference to the given originator (a global entry can have
* references to multiple originators) and adjust the flags attribute to reflect
* the function argument.
* If a TT local entry exists for this non-mesh client remove it.
*
* The caller must hold orig_node refcount.
*/
int batadv_tt_global_add(struct batadv_priv *bat_priv, int batadv_tt_global_add(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node, struct batadv_orig_node *orig_node,
const unsigned char *tt_addr, uint8_t flags, const unsigned char *tt_addr, uint16_t flags,
uint8_t ttvn) uint8_t ttvn)
{ {
struct batadv_tt_global_entry *tt_global_entry; struct batadv_tt_global_entry *tt_global_entry;
...@@ -1600,11 +1622,11 @@ batadv_tt_response_fill_table(uint16_t tt_len, uint8_t ttvn, ...@@ -1600,11 +1622,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 + NET_IP_ALIGN); skb = netdev_alloc_skb_ip_align(NULL, len + ETH_HLEN);
if (!skb) if (!skb)
goto out; goto out;
skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN); skb_reserve(skb, ETH_HLEN);
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;
...@@ -1665,11 +1687,11 @@ static int batadv_send_tt_request(struct batadv_priv *bat_priv, ...@@ -1665,11 +1687,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 + NET_IP_ALIGN); skb = netdev_alloc_skb_ip_align(NULL, sizeof(*tt_request) + ETH_HLEN);
if (!skb) if (!skb)
goto out; goto out;
skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN); skb_reserve(skb, ETH_HLEN);
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);
...@@ -1691,7 +1713,7 @@ static int batadv_send_tt_request(struct batadv_priv *bat_priv, ...@@ -1691,7 +1713,7 @@ static int batadv_send_tt_request(struct batadv_priv *bat_priv,
batadv_inc_counter(bat_priv, BATADV_CNT_TT_REQUEST_TX); batadv_inc_counter(bat_priv, BATADV_CNT_TT_REQUEST_TX);
if (batadv_send_skb_to_orig(skb, dst_orig_node, NULL)) if (batadv_send_skb_to_orig(skb, dst_orig_node, NULL) != NET_XMIT_DROP)
ret = 0; ret = 0;
out: out:
...@@ -1715,7 +1737,7 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv, ...@@ -1715,7 +1737,7 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv,
struct batadv_orig_node *req_dst_orig_node; struct batadv_orig_node *req_dst_orig_node;
struct batadv_orig_node *res_dst_orig_node = NULL; struct batadv_orig_node *res_dst_orig_node = NULL;
uint8_t orig_ttvn, req_ttvn, ttvn; uint8_t orig_ttvn, req_ttvn, ttvn;
int ret = false; int res, ret = false;
unsigned char *tt_buff; unsigned char *tt_buff;
bool full_table; bool full_table;
uint16_t tt_len, tt_tot; uint16_t tt_len, tt_tot;
...@@ -1762,11 +1784,11 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv, ...@@ -1762,11 +1784,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 + NET_IP_ALIGN); skb = netdev_alloc_skb_ip_align(NULL, len + ETH_HLEN);
if (!skb) if (!skb)
goto unlock; goto unlock;
skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN); skb_reserve(skb, ETH_HLEN);
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;
...@@ -1810,8 +1832,10 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv, ...@@ -1810,8 +1832,10 @@ batadv_send_other_tt_response(struct batadv_priv *bat_priv,
batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX); batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX);
if (batadv_send_skb_to_orig(skb, res_dst_orig_node, NULL)) res = batadv_send_skb_to_orig(skb, res_dst_orig_node, NULL);
if (res != NET_XMIT_DROP)
ret = true; ret = true;
goto out; goto out;
unlock: unlock:
...@@ -1878,11 +1902,11 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv, ...@@ -1878,11 +1902,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 + NET_IP_ALIGN); skb = netdev_alloc_skb_ip_align(NULL, len + ETH_HLEN);
if (!skb) if (!skb)
goto unlock; goto unlock;
skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN); skb_reserve(skb, ETH_HLEN);
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;
...@@ -1925,7 +1949,7 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv, ...@@ -1925,7 +1949,7 @@ batadv_send_my_tt_response(struct batadv_priv *bat_priv,
batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX); batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_TX);
if (batadv_send_skb_to_orig(skb, orig_node, NULL)) if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP)
ret = true; ret = true;
goto out; goto out;
...@@ -2212,11 +2236,11 @@ static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client, ...@@ -2212,11 +2236,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 + NET_IP_ALIGN); skb = netdev_alloc_skb_ip_align(NULL, len + ETH_HLEN);
if (!skb) if (!skb)
goto out; goto out;
skb_reserve(skb, ETH_HLEN + NET_IP_ALIGN); skb_reserve(skb, ETH_HLEN);
roam_adv_packet = (struct batadv_roam_adv_packet *)skb_put(skb, len); roam_adv_packet = (struct batadv_roam_adv_packet *)skb_put(skb, len);
...@@ -2238,7 +2262,7 @@ static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client, ...@@ -2238,7 +2262,7 @@ static void batadv_send_roam_adv(struct batadv_priv *bat_priv, uint8_t *client,
batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_TX); batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_TX);
if (batadv_send_skb_to_orig(skb, orig_node, NULL)) if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP)
ret = 0; ret = 0;
out: out:
......
...@@ -33,7 +33,7 @@ void batadv_tt_global_add_orig(struct batadv_priv *bat_priv, ...@@ -33,7 +33,7 @@ void batadv_tt_global_add_orig(struct batadv_priv *bat_priv,
const unsigned char *tt_buff, int tt_buff_len); const unsigned char *tt_buff, int tt_buff_len);
int batadv_tt_global_add(struct batadv_priv *bat_priv, int batadv_tt_global_add(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node, struct batadv_orig_node *orig_node,
const unsigned char *addr, uint8_t flags, const unsigned char *addr, uint16_t flags,
uint8_t ttvn); uint8_t ttvn);
int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset); int batadv_tt_global_seq_print_text(struct seq_file *seq, void *offset);
void batadv_tt_global_del_orig(struct batadv_priv *bat_priv, void batadv_tt_global_del_orig(struct batadv_priv *bat_priv,
......
...@@ -61,6 +61,7 @@ struct batadv_hard_iface_bat_iv { ...@@ -61,6 +61,7 @@ struct batadv_hard_iface_bat_iv {
* @if_status: status of the interface for batman-adv * @if_status: status of the interface for batman-adv
* @net_dev: pointer to the net_device * @net_dev: pointer to the net_device
* @frag_seqno: last fragment sequence number sent by this interface * @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 * @hardif_obj: kobject of the per interface sysfs "mesh" directory
* @refcount: number of contexts the object is used * @refcount: number of contexts the object is used
* @batman_adv_ptype: packet type describing packets that should be processed by * @batman_adv_ptype: packet type describing packets that should be processed by
...@@ -76,6 +77,7 @@ struct batadv_hard_iface { ...@@ -76,6 +77,7 @@ struct batadv_hard_iface {
char if_status; char if_status;
struct net_device *net_dev; struct net_device *net_dev;
atomic_t frag_seqno; atomic_t frag_seqno;
uint8_t num_bcasts;
struct kobject *hardif_obj; struct kobject *hardif_obj;
atomic_t refcount; atomic_t refcount;
struct packet_type batman_adv_ptype; struct packet_type batman_adv_ptype;
...@@ -640,7 +642,7 @@ struct batadv_socket_packet { ...@@ -640,7 +642,7 @@ struct batadv_socket_packet {
#ifdef CONFIG_BATMAN_ADV_BLA #ifdef CONFIG_BATMAN_ADV_BLA
struct batadv_bla_backbone_gw { struct batadv_bla_backbone_gw {
uint8_t orig[ETH_ALEN]; uint8_t orig[ETH_ALEN];
short vid; unsigned short vid;
struct hlist_node hash_entry; struct hlist_node hash_entry;
struct batadv_priv *bat_priv; struct batadv_priv *bat_priv;
unsigned long lasttime; unsigned long lasttime;
...@@ -663,7 +665,7 @@ struct batadv_bla_backbone_gw { ...@@ -663,7 +665,7 @@ struct batadv_bla_backbone_gw {
*/ */
struct batadv_bla_claim { struct batadv_bla_claim {
uint8_t addr[ETH_ALEN]; uint8_t addr[ETH_ALEN];
short vid; unsigned short vid;
struct batadv_bla_backbone_gw *backbone_gw; struct batadv_bla_backbone_gw *backbone_gw;
unsigned long lasttime; unsigned long lasttime;
struct hlist_node hash_entry; struct hlist_node hash_entry;
......
...@@ -464,7 +464,7 @@ int batadv_unicast_generic_send_skb(struct batadv_priv *bat_priv, ...@@ -464,7 +464,7 @@ int batadv_unicast_generic_send_skb(struct batadv_priv *bat_priv,
goto out; goto out;
} }
if (batadv_send_skb_to_orig(skb, orig_node, NULL)) if (batadv_send_skb_to_orig(skb, orig_node, NULL) != NET_XMIT_DROP)
ret = 0; ret = 0;
out: out:
......
...@@ -392,12 +392,12 @@ batadv_add_packet(struct batadv_priv *bat_priv, ...@@ -392,12 +392,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 + NET_IP_ALIGN); info->skb_packet = netdev_alloc_skb_ip_align(NULL, len + ETH_HLEN);
if (!info->skb_packet) { if (!info->skb_packet) {
kfree(info); kfree(info);
return NULL; return NULL;
} }
skb_reserve(info->skb_packet, ETH_HLEN + NET_IP_ALIGN); skb_reserve(info->skb_packet, ETH_HLEN);
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);
...@@ -697,7 +697,7 @@ static void batadv_broadcast_vis_packet(struct batadv_priv *bat_priv, ...@@ -697,7 +697,7 @@ static void batadv_broadcast_vis_packet(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node; struct batadv_orig_node *orig_node;
struct batadv_vis_packet *packet; struct batadv_vis_packet *packet;
struct sk_buff *skb; struct sk_buff *skb;
uint32_t i; uint32_t i, res;
packet = (struct batadv_vis_packet *)info->skb_packet->data; packet = (struct batadv_vis_packet *)info->skb_packet->data;
...@@ -724,7 +724,8 @@ static void batadv_broadcast_vis_packet(struct batadv_priv *bat_priv, ...@@ -724,7 +724,8 @@ static void batadv_broadcast_vis_packet(struct batadv_priv *bat_priv,
if (!skb) if (!skb)
continue; continue;
if (!batadv_send_skb_to_orig(skb, orig_node, NULL)) res = batadv_send_skb_to_orig(skb, orig_node, NULL);
if (res == NET_XMIT_DROP)
kfree_skb(skb); kfree_skb(skb);
} }
rcu_read_unlock(); rcu_read_unlock();
...@@ -748,7 +749,7 @@ static void batadv_unicast_vis_packet(struct batadv_priv *bat_priv, ...@@ -748,7 +749,7 @@ static void batadv_unicast_vis_packet(struct batadv_priv *bat_priv,
if (!skb) if (!skb)
goto out; goto out;
if (!batadv_send_skb_to_orig(skb, orig_node, NULL)) if (batadv_send_skb_to_orig(skb, orig_node, NULL) == NET_XMIT_DROP)
kfree_skb(skb); kfree_skb(skb);
out: out:
...@@ -854,13 +855,13 @@ int batadv_vis_init(struct batadv_priv *bat_priv) ...@@ -854,13 +855,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; len = sizeof(*packet) + BATADV_MAX_VIS_PACKET_SIZE + ETH_HLEN;
len += ETH_HLEN + NET_IP_ALIGN; bat_priv->vis.my_info->skb_packet = netdev_alloc_skb_ip_align(NULL,
bat_priv->vis.my_info->skb_packet = dev_alloc_skb(len); 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 + NET_IP_ALIGN); skb_reserve(bat_priv->vis.my_info->skb_packet, ETH_HLEN);
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));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment