Author: simon
Date: 2010-04-29 00:47:18 +0200 (Thu, 29 Apr 2010)
New Revision: 1641
Modified:
trunk/batman-adv-kernelland/aggregation.c
trunk/batman-adv-kernelland/bitarray.c
trunk/batman-adv-kernelland/bitarray.h
trunk/batman-adv-kernelland/main.h
trunk/batman-adv-kernelland/packet.h
trunk/batman-adv-kernelland/routing.c
trunk/batman-adv-kernelland/send.c
trunk/batman-adv-kernelland/soft-interface.c
trunk/batman-adv-kernelland/types.h
trunk/batman-adv-kernelland/vis.c
Log:
batman-adv: 32bit sequence number and TTL for broadcasts
From: Simon Wunderlich <simon.wunderlich(a)s2003.tu-chemnitz.de>
This patch changes the sequence number range from 8 or 16 bit to 32 bit.
This should avoid problems with the sequence number sliding window algorithm
which we had seen in the past for broadcast floods or malicious packet
injections. We can not assure 100% security with this patch, but it is quite
an improvement over the old 16 bit sequence numbers:
* expected window size can be increased (4096 -> 65536)
* 64k packets in the right order would now be needed to cause a loop,
which seems practically impossible.
Furthermore, a TTL field has been added to the broadcast packet type, just to
make sure.
These changes required to increase the compatibility level once again.
Signed-off-by: Sven Eckelmann <sven.eckelmann(a)gmx.de>
Signed-off-by: Simon Wunderlich <siwu(a)hrz.tu-chemnitz.de>
---
Simon Wunderlich:
These changes required to increase the compatibility level once again.
It should therefore only applied to the upcoming 0.3 branch.
Modified: trunk/batman-adv-kernelland/aggregation.c
===================================================================
--- trunk/batman-adv-kernelland/aggregation.c 2010-04-26 10:08:57 UTC (rev 1640)
+++ trunk/batman-adv-kernelland/aggregation.c 2010-04-28 22:47:18 UTC (rev 1641)
@@ -254,9 +254,9 @@
while (aggregated_packet(buff_pos, packet_len,
batman_packet->num_hna)) {
- /* network to host order for our 16bit seqno, and the
+ /* network to host order for our 32bit seqno, and the
orig_interval. */
- batman_packet->seqno = ntohs(batman_packet->seqno);
+ batman_packet->seqno = ntohl(batman_packet->seqno);
hna_buff = packet_buff + buff_pos + BAT_PACKET_LEN;
receive_bat_packet(ethhdr, batman_packet,
Modified: trunk/batman-adv-kernelland/bitarray.c
===================================================================
--- trunk/batman-adv-kernelland/bitarray.c 2010-04-26 10:08:57 UTC (rev 1640)
+++ trunk/batman-adv-kernelland/bitarray.c 2010-04-28 22:47:18 UTC (rev 1641)
@@ -24,10 +24,10 @@
/* returns true if the corresponding bit in the given seq_bits indicates true
* and curr_seqno is within range of last_seqno */
-uint8_t get_bit_status(TYPE_OF_WORD *seq_bits, uint16_t last_seqno,
- uint16_t curr_seqno)
+uint8_t get_bit_status(TYPE_OF_WORD *seq_bits, uint32_t last_seqno,
+ uint32_t curr_seqno)
{
- int16_t diff, word_offset, word_num;
+ int32_t diff, word_offset, word_num;
diff = last_seqno - curr_seqno;
if (diff < 0 || diff >= TQ_LOCAL_WINDOW_SIZE) {
@@ -125,7 +125,7 @@
* 1 if the window was moved (either new or very old)
* 0 if the window was not moved/shifted.
*/
-char bit_get_packet(TYPE_OF_WORD *seq_bits, int16_t seq_num_diff,
+char bit_get_packet(TYPE_OF_WORD *seq_bits, int32_t seq_num_diff,
int8_t set_mark)
{
/* sequence number is slightly older. We already got a sequence number
Modified: trunk/batman-adv-kernelland/bitarray.h
===================================================================
--- trunk/batman-adv-kernelland/bitarray.h 2010-04-26 10:08:57 UTC (rev 1640)
+++ trunk/batman-adv-kernelland/bitarray.h 2010-04-28 22:47:18 UTC (rev 1641)
@@ -26,8 +26,8 @@
/* returns true if the corresponding bit in the given seq_bits indicates true
* and curr_seqno is within range of last_seqno */
-uint8_t get_bit_status(TYPE_OF_WORD *seq_bits, uint16_t last_seqno,
- uint16_t curr_seqno);
+uint8_t get_bit_status(TYPE_OF_WORD *seq_bits, uint32_t last_seqno,
+ uint32_t curr_seqno);
/* turn corresponding bit on, so we can remember that we got the packet */
void bit_mark(TYPE_OF_WORD *seq_bits, int32_t n);
@@ -38,7 +38,7 @@
/* receive and process one packet, returns 1 if received seq_num is considered
* new, 0 if old */
-char bit_get_packet(TYPE_OF_WORD *seq_bits, int16_t seq_num_diff,
+char bit_get_packet(TYPE_OF_WORD *seq_bits, int32_t seq_num_diff,
int8_t set_mark);
/* count the hamming weight, how many good packets did we receive? */
Modified: trunk/batman-adv-kernelland/main.h
===================================================================
--- trunk/batman-adv-kernelland/main.h 2010-04-26 10:08:57 UTC (rev 1640)
+++ trunk/batman-adv-kernelland/main.h 2010-04-28 22:47:18 UTC (rev 1641)
@@ -69,7 +69,7 @@
#define MAX_AGGREGATION_MS 100
#define RESET_PROTECTION_MS 30000
-#define EXPECTED_SEQNO_RANGE 4096
+#define EXPECTED_SEQNO_RANGE 65536
/* don't reset again within 30 seconds */
#define MODULE_INACTIVE 0
Modified: trunk/batman-adv-kernelland/packet.h
===================================================================
--- trunk/batman-adv-kernelland/packet.h 2010-04-26 10:08:57 UTC (rev 1640)
+++ trunk/batman-adv-kernelland/packet.h 2010-04-28 22:47:18 UTC (rev 1641)
@@ -28,7 +28,7 @@
#define BAT_VIS 0x05
/* this file is included by batctl which needs these defines */
-#define COMPAT_VERSION 9
+#define COMPAT_VERSION 10
#define DIRECTLINK 0x40
#define VIS_SERVER 0x20
#define PRIMARIES_FIRST_HOP 0x10
@@ -49,7 +49,7 @@
uint8_t version; /* batman version field */
uint8_t flags; /* 0x40: DIRECTLINK flag, 0x20 VIS_SERVER flag... */
uint8_t tq;
- uint16_t seqno;
+ uint32_t seqno;
uint8_t orig[6];
uint8_t prev_sender[6];
uint8_t ttl;
@@ -99,15 +99,16 @@
uint8_t packet_type;
uint8_t version; /* batman version field */
uint8_t orig[6];
- uint16_t seqno;
+ uint8_t ttl;
+ uint32_t seqno;
} __attribute__((packed));
struct vis_packet {
uint8_t packet_type;
uint8_t version; /* batman version field */
uint8_t vis_type; /* which type of vis-participant sent this? */
- uint8_t seqno; /* sequence number */
uint8_t entries; /* number of entries behind this struct */
+ uint32_t seqno; /* sequence number */
uint8_t ttl; /* TTL */
uint8_t vis_orig[6]; /* originator that informs about its
* neighbors */
Modified: trunk/batman-adv-kernelland/routing.c
===================================================================
--- trunk/batman-adv-kernelland/routing.c 2010-04-26 10:08:57 UTC (rev 1640)
+++ trunk/batman-adv-kernelland/routing.c 2010-04-28 22:47:18 UTC (rev 1641)
@@ -323,7 +323,7 @@
* 0 if the packet is to be accepted
* 1 if the packet is to be ignored.
*/
-static int window_protected(int16_t seq_num_diff,
+static int window_protected(int32_t seq_num_diff,
unsigned long *last_reset)
{
if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE)
@@ -357,7 +357,7 @@
struct orig_node *orig_node;
struct neigh_node *tmp_neigh_node;
char is_duplicate = 0;
- int16_t seq_diff;
+ int32_t seq_diff;
int need_update = 0;
int set_mark;
@@ -526,7 +526,7 @@
char is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0;
char is_broadcast = 0, is_bidirectional, is_single_hop_neigh;
char is_duplicate;
- unsigned short if_incoming_seqno;
+ uint32_t if_incoming_seqno;
/* Silently drop when the batman packet is actually not a
* correct packet.
@@ -1129,7 +1129,7 @@
struct bcast_packet *bcast_packet;
struct ethhdr *ethhdr;
int hdr_size = sizeof(struct bcast_packet);
- int16_t seq_diff;
+ int32_t seq_diff;
unsigned long flags;
/* drop packet if it has not necessary minimum size */
@@ -1156,6 +1156,9 @@
if (is_my_mac(bcast_packet->orig))
return NET_RX_DROP;
+ if (bcast_packet->ttl < 2)
+ return NET_RX_DROP;
+
spin_lock_irqsave(&orig_hash_lock, flags);
orig_node = ((struct orig_node *)
hash_find(orig_hash, bcast_packet->orig));
@@ -1168,12 +1171,12 @@
/* check whether the packet is a duplicate */
if (get_bit_status(orig_node->bcast_bits,
orig_node->last_bcast_seqno,
- ntohs(bcast_packet->seqno))) {
+ ntohl(bcast_packet->seqno))) {
spin_unlock_irqrestore(&orig_hash_lock, flags);
return NET_RX_DROP;
}
- seq_diff = ntohs(bcast_packet->seqno) - orig_node->last_bcast_seqno;
+ seq_diff = ntohl(bcast_packet->seqno) - orig_node->last_bcast_seqno;
/* check whether the packet is old and the host just restarted. */
if (window_protected(seq_diff, &orig_node->bcast_seqno_reset)) {
@@ -1184,7 +1187,7 @@
/* mark broadcast in flood history, update window position
* if required. */
if (bit_get_packet(orig_node->bcast_bits, seq_diff, 1))
- orig_node->last_bcast_seqno = ntohs(bcast_packet->seqno);
+ orig_node->last_bcast_seqno = ntohl(bcast_packet->seqno);
spin_unlock_irqrestore(&orig_hash_lock, flags);
/* rebroadcast packet */
Modified: trunk/batman-adv-kernelland/send.c
===================================================================
--- trunk/batman-adv-kernelland/send.c 2010-04-26 10:08:57 UTC (rev 1640)
+++ trunk/batman-adv-kernelland/send.c 2010-04-28 22:47:18 UTC (rev 1641)
@@ -153,7 +153,7 @@
"%s %spacket (originator %pM, seqno %d, TQ %d, TTL %d, IDF %s) on interface %s [%s]\n",
fwd_str,
(packet_num > 0 ? "aggregated " : ""),
- batman_packet->orig, ntohs(batman_packet->seqno),
+ batman_packet->orig, ntohl(batman_packet->seqno),
batman_packet->tq, batman_packet->ttl,
(batman_packet->flags & DIRECTLINK ?
"on" : "off"),
@@ -196,7 +196,7 @@
bat_dbg(DBG_BATMAN,
"%s packet (originator %pM, seqno %d, TTL %d) on interface %s [%s]\n",
(forw_packet->own ? "Sending own" : "Forwarding"),
- batman_packet->orig, ntohs(batman_packet->seqno),
+ batman_packet->orig, ntohl(batman_packet->seqno),
batman_packet->ttl, forw_packet->if_incoming->dev,
forw_packet->if_incoming->addr_str);
@@ -275,7 +275,8 @@
batman_packet = (struct batman_packet *)batman_if->packet_buff;
/* change sequence number to network order */
- batman_packet->seqno = htons((uint16_t)atomic_read(&batman_if->seqno));
+ batman_packet->seqno =
+ htonl((uint32_t)atomic_read(&batman_if->seqno));
if (vis_server == VIS_TYPE_SERVER_SYNC)
batman_packet->flags |= VIS_SERVER;
@@ -288,7 +289,6 @@
else
batman_packet->gw_flags = 0;
- /* could be read by receive_bat_packet() */
atomic_inc(&batman_if->seqno);
slide_own_bcast_window(batman_if);
@@ -343,7 +343,7 @@
in_tq, tq_avg, batman_packet->tq, in_ttl - 1,
batman_packet->ttl);
- batman_packet->seqno = htons(batman_packet->seqno);
+ batman_packet->seqno = htonl(batman_packet->seqno);
/* switch of primaries first hop flag when forwarding */
batman_packet->flags &= ~PRIMARIES_FIRST_HOP;
@@ -397,6 +397,7 @@
int add_bcast_packet_to_list(struct sk_buff *skb)
{
struct forw_packet *forw_packet;
+ struct bcast_packet *bcast_packet;
/* FIXME: each batman_if will be attached to a softif */
struct bat_priv *bat_priv = netdev_priv(soft_device);
@@ -414,6 +415,10 @@
if (!skb)
goto packet_free;
+ /* as we have a copy now, it is safe to decrease the TTL */
+ bcast_packet = (struct bcast_packet *)skb->data;
+ bcast_packet->ttl--;
+
skb_reset_mac_header(skb);
forw_packet->skb = skb;
Modified: trunk/batman-adv-kernelland/soft-interface.c
===================================================================
--- trunk/batman-adv-kernelland/soft-interface.c 2010-04-26 10:08:57 UTC (rev 1640)
+++ trunk/batman-adv-kernelland/soft-interface.c 2010-04-28 22:47:18 UTC (rev 1641)
@@ -32,7 +32,7 @@
#include <linux/etherdevice.h>
#include "compat.h"
-static uint16_t bcast_seqno = 1; /* give own bcast messages seq numbers to avoid
+static uint32_t bcast_seqno = 1; /* give own bcast messages seq numbers to avoid
* broadcast storms */
static int32_t skb_packets;
static int32_t skb_bad_packets;
@@ -214,6 +214,7 @@
bcast_packet = (struct bcast_packet *)skb->data;
bcast_packet->version = COMPAT_VERSION;
+ bcast_packet->ttl = TTL;
/* batman packet type: broadcast */
bcast_packet->packet_type = BAT_BCAST;
@@ -223,7 +224,7 @@
memcpy(bcast_packet->orig, mainIfAddr, ETH_ALEN);
/* set broadcast sequence number */
- bcast_packet->seqno = htons(bcast_seqno);
+ bcast_packet->seqno = htonl(bcast_seqno);
/* broadcast packet. on success, increase seqno. */
if (add_bcast_packet_to_list(skb) == NETDEV_TX_OK)
Modified: trunk/batman-adv-kernelland/types.h
===================================================================
--- trunk/batman-adv-kernelland/types.h 2010-04-26 10:08:57 UTC (rev 1640)
+++ trunk/batman-adv-kernelland/types.h 2010-04-28 22:47:18 UTC (rev 1641)
@@ -63,10 +63,10 @@
uint8_t flags; /* for now only VIS_SERVER flag. */
unsigned char *hna_buff;
int16_t hna_buff_len;
- uint16_t last_real_seqno; /* last and best known squence number */
+ uint32_t last_real_seqno; /* last and best known sequence number */
uint8_t last_ttl; /* ttl of last received packet */
TYPE_OF_WORD bcast_bits[NUM_WORDS];
- uint16_t last_bcast_seqno; /* last broadcast sequence number received by this host */
+ uint32_t last_bcast_seqno; /* last received broadcast seqno */
struct list_head neigh_list;
struct {
uint8_t candidates; /* how many candidates are available */
Modified: trunk/batman-adv-kernelland/vis.c
===================================================================
--- trunk/batman-adv-kernelland/vis.c 2010-04-26 10:08:57 UTC (rev 1640)
+++ trunk/batman-adv-kernelland/vis.c 2010-04-28 22:47:18 UTC (rev 1641)
@@ -309,7 +309,8 @@
old_info = hash_find(vis_hash, &search_elem);
if (old_info != NULL) {
- if (!seq_after(vis_packet->seqno, old_info->packet.seqno)) {
+ if (!seq_after(ntohl(vis_packet->seqno),
+ ntohl(old_info->packet.seqno))) {
if (old_info->packet.seqno == vis_packet->seqno) {
recv_list_add(&old_info->recv_list,
vis_packet->sender_orig);
@@ -477,7 +478,7 @@
spin_lock_irqsave(&orig_hash_lock, flags);
memcpy(info->packet.target_orig, broadcastAddr, ETH_ALEN);
info->packet.ttl = TTL;
- info->packet.seqno++;
+ info->packet.seqno = htonl(ntohl(info->packet.seqno) + 1);
info->packet.entries = 0;
if (info->packet.vis_type == VIS_TYPE_CLIENT_UPDATE) {
Author: marek
Date: 2010-04-26 12:08:57 +0200 (Mon, 26 Apr 2010)
New Revision: 1640
Modified:
trunk/batman-adv-kernelland/routing.c
Log:
batman-adv: Update pointer to ethhdr after skb_copy
We must ensure that all pointer to a socket buffer are updated when we
copy a socket buffer and free our reference to the old one.
Another part of the kernel could also free its reference which maybe
removes the buffer completely. In that situation we would would feed
wrong information to the routing algorithm after the memory area is
written again by someone else.
Signed-off-by: Sven Eckelmann <sven.eckelmann(a)gmx.de>
Modified: trunk/batman-adv-kernelland/routing.c
===================================================================
--- trunk/batman-adv-kernelland/routing.c 2010-04-20 12:46:57 UTC (rev 1639)
+++ trunk/batman-adv-kernelland/routing.c 2010-04-26 10:08:57 UTC (rev 1640)
@@ -747,6 +747,7 @@
skb = skb_copy(skb, GFP_ATOMIC);
if (!skb)
return NET_RX_DROP;
+ ethhdr = (struct ethhdr *)skb_mac_header(skb);
kfree_skb(skb_old);
}
@@ -805,6 +806,7 @@
if (!skb)
return NET_RX_DROP;
icmp_packet = (struct icmp_packet_rr *)skb->data;
+ ethhdr = (struct ethhdr *)skb_mac_header(skb);
kfree_skb(skb_old);
}
@@ -865,6 +867,7 @@
if (!skb)
return NET_RX_DROP;
icmp_packet = (struct icmp_packet *) skb->data;
+ ethhdr = (struct ethhdr *)skb_mac_header(skb);
kfree_skb(skb_old);
}
@@ -960,6 +963,7 @@
if (!skb)
return NET_RX_DROP;
icmp_packet = (struct icmp_packet_rr *)skb->data;
+ ethhdr = (struct ethhdr *)skb_mac_header(skb);
kfree_skb(skb_old);
}
@@ -1106,6 +1110,7 @@
if (!skb)
return NET_RX_DROP;
unicast_packet = (struct unicast_packet *) skb->data;
+ ethhdr = (struct ethhdr *)skb_mac_header(skb);
kfree_skb(skb_old);
}
Author: simon
Date: 2010-04-19 23:14:19 +0200 (Mon, 19 Apr 2010)
New Revision: 1638
Modified:
trunk/batman-adv-kernelland/main.c
trunk/batman-adv-kernelland/main.h
trunk/batman-adv-kernelland/vis.c
Log:
batman-adv: convert vis_interval into define
vis_interval does not neccesarily needs to be a variable, as there is
no way to change it anyway (and probably no need to). We can therefore
remove yet another global variable.
Thanks Marek for pointing this out.
Signed-off-by: Simon Wunderlich <siwu(a)hrz.tu-chemnitz.de>
Modified: trunk/batman-adv-kernelland/main.c
===================================================================
--- trunk/batman-adv-kernelland/main.c 2010-04-19 20:13:31 UTC (rev 1637)
+++ trunk/batman-adv-kernelland/main.c 2010-04-19 21:14:19 UTC (rev 1638)
@@ -43,8 +43,6 @@
DEFINE_SPINLOCK(forw_bat_list_lock);
DEFINE_SPINLOCK(forw_bcast_list_lock);
-atomic_t vis_interval;
-
int16_t num_hna;
struct net_device *soft_device;
@@ -80,9 +78,6 @@
atomic_set(&module_state, MODULE_INACTIVE);
- atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only
- * for debugging now. */
-
/* the name should not be longer than 10 chars - see
* http://lwn.net/Articles/23634/ */
bat_event_workqueue = create_singlethread_workqueue("bat_events");
Modified: trunk/batman-adv-kernelland/main.h
===================================================================
--- trunk/batman-adv-kernelland/main.h 2010-04-19 20:13:31 UTC (rev 1637)
+++ trunk/batman-adv-kernelland/main.h 2010-04-19 21:14:19 UTC (rev 1638)
@@ -56,6 +56,8 @@
#define LOG_BUF_LEN 8192 /* has to be a power of 2 */
#define ETH_STR_LEN 20
+#define VIS_INTERVAL 5000 /* 5 seconds */
+
/* how much worse secondary interfaces may be to
* to be considered as bonding candidates */
@@ -137,7 +139,6 @@
extern spinlock_t forw_bat_list_lock;
extern spinlock_t forw_bcast_list_lock;
-extern atomic_t vis_interval;
extern int16_t num_hna;
extern struct net_device *soft_device;
Modified: trunk/batman-adv-kernelland/vis.c
===================================================================
--- trunk/batman-adv-kernelland/vis.c 2010-04-19 20:13:31 UTC (rev 1637)
+++ trunk/batman-adv-kernelland/vis.c 2010-04-19 21:14:19 UTC (rev 1638)
@@ -702,7 +702,7 @@
}
/* prefill the vis info */
- my_vis_info->first_seen = jiffies - atomic_read(&vis_interval);
+ my_vis_info->first_seen = jiffies - msecs_to_jiffies(VIS_INTERVAL);
INIT_LIST_HEAD(&my_vis_info->recv_list);
INIT_LIST_HEAD(&my_vis_info->send_list);
kref_init(&my_vis_info->refcount);
@@ -765,5 +765,5 @@
static void start_vis_timer(void)
{
queue_delayed_work(bat_event_workqueue, &vis_timer_wq,
- (atomic_read(&vis_interval) * HZ) / 1000);
+ (VIS_INTERVAL * HZ) / 1000);
}
Author: simon
Date: 2010-04-12 21:06:37 +0200 (Mon, 12 Apr 2010)
New Revision: 1633
Modified:
trunk/batman-adv-kernelland/soft-interface.c
Log:
batman-adv: kfree_skb() in interface_tx() in error case
As we always return that the we consumed the skb, we should also free the skb
in the case of an error.
Signed-off-by: Simon Wunderlich <siwu(a)hrz.tu-chemnitz.de>
Modified: trunk/batman-adv-kernelland/soft-interface.c
===================================================================
--- trunk/batman-adv-kernelland/soft-interface.c 2010-04-12 19:02:42 UTC (rev 1632)
+++ trunk/batman-adv-kernelland/soft-interface.c 2010-04-12 19:06:37 UTC (rev 1633)
@@ -288,6 +288,7 @@
spin_unlock_irqrestore(&orig_hash_lock, flags);
dropped:
priv->stats.tx_dropped++;
+ kfree_skb(skb);
end:
return NETDEV_TX_OK;
}
Author: simon
Date: 2010-04-12 21:02:42 +0200 (Mon, 12 Apr 2010)
New Revision: 1632
Modified:
trunk/batman-adv-kernelland/aggregation.c
trunk/batman-adv-kernelland/main.c
trunk/batman-adv-kernelland/main.h
trunk/batman-adv-kernelland/send.c
trunk/batman-adv-kernelland/send.h
trunk/batman-adv-kernelland/soft-interface.c
Log:
batman-adv: Limit queue lengths for batman and broadcast packets
This patch limits the queue lengths of batman and broadcast packets. BATMAN
packets are held back for aggregation and jittered to avoid interferences.
Broadcast packets are stored to be sent out multiple times to increase
the probability to be received by other nodes in lossy environments.
Especially in extreme cases like broadcast storms, the queues have been seen
to run full, eating up all the memory and triggering the infamous OOM killer.
With the queue length limits introduced in this patch, this problem is
avoided.
Each queue is limited to 256 entries for now, resulting in 1 MB of maximum
space available in total for typical setups (assuming one packet including
overhead does not require more than 2000 byte). This should also be reasonable
for smaller routers, otherwise the defines can be tweaked later.
This third version of the patch does not increase the local broadcast
sequence number when the queue is already full.
Signed-off-by: Simon Wunderlich <siwu(a)hrz.tu-chemnitz.de>
Modified: trunk/batman-adv-kernelland/aggregation.c
===================================================================
--- trunk/batman-adv-kernelland/aggregation.c 2010-04-12 18:52:47 UTC (rev 1631)
+++ trunk/batman-adv-kernelland/aggregation.c 2010-04-12 19:02:42 UTC (rev 1632)
@@ -95,6 +95,7 @@
return false;
}
+#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0)
/* create a new aggregated packet and add this packet to it */
static void new_aggregated_packet(unsigned char *packet_buff,
int packet_len,
@@ -106,13 +107,26 @@
struct forw_packet *forw_packet_aggr;
unsigned long flags;
+ /* own packet should always be scheduled */
+ if (!own_packet) {
+ if (!atomic_dec_not_zero(&batman_queue_left)) {
+ bat_dbg(DBG_BATMAN, "batman packet queue full\n");
+ return;
+ }
+ }
+
forw_packet_aggr = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC);
- if (!forw_packet_aggr)
+ if (!forw_packet_aggr) {
+ if (!own_packet)
+ atomic_inc(&batman_queue_left);
return;
+ }
forw_packet_aggr->packet_buff = kmalloc(MAX_AGGREGATION_BYTES,
GFP_ATOMIC);
if (!forw_packet_aggr->packet_buff) {
+ if (!own_packet)
+ atomic_inc(&batman_queue_left);
kfree(forw_packet_aggr);
return;
}
Modified: trunk/batman-adv-kernelland/main.c
===================================================================
--- trunk/batman-adv-kernelland/main.c 2010-04-12 18:52:47 UTC (rev 1631)
+++ trunk/batman-adv-kernelland/main.c 2010-04-12 19:02:42 UTC (rev 1632)
@@ -44,6 +44,9 @@
DEFINE_SPINLOCK(forw_bcast_list_lock);
atomic_t vis_interval;
+atomic_t bcast_queue_left;
+atomic_t batman_queue_left;
+
int16_t num_hna;
struct net_device *soft_device;
@@ -81,6 +84,8 @@
atomic_set(&vis_interval, 1000);/* TODO: raise this later, this is only
* for debugging now. */
+ atomic_set(&bcast_queue_left, BCAST_QUEUE_LEN);
+ atomic_set(&batman_queue_left, BATMAN_QUEUE_LEN);
/* the name should not be longer than 10 chars - see
* http://lwn.net/Articles/23634/ */
Modified: trunk/batman-adv-kernelland/main.h
===================================================================
--- trunk/batman-adv-kernelland/main.h 2010-04-12 18:52:47 UTC (rev 1631)
+++ trunk/batman-adv-kernelland/main.h 2010-04-12 19:02:42 UTC (rev 1632)
@@ -74,6 +74,8 @@
#define MODULE_ACTIVE 1
#define MODULE_DEACTIVATING 2
+#define BCAST_QUEUE_LEN 256
+#define BATMAN_QUEUE_LEN 256
/*
* Debug Messages
@@ -136,6 +138,8 @@
extern spinlock_t forw_bcast_list_lock;
extern atomic_t vis_interval;
+extern atomic_t bcast_queue_left;
+extern atomic_t batman_queue_left;
extern int16_t num_hna;
extern struct net_device *soft_device;
Modified: trunk/batman-adv-kernelland/send.c
===================================================================
--- trunk/batman-adv-kernelland/send.c 2010-04-12 18:52:47 UTC (rev 1631)
+++ trunk/batman-adv-kernelland/send.c 2010-04-12 19:02:42 UTC (rev 1632)
@@ -385,13 +385,28 @@
send_time);
}
-void add_bcast_packet_to_list(struct sk_buff *skb)
+#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0)
+/* add a broadcast packet to the queue and setup timers. broadcast packets
+ * are sent multiple times to increase probability for beeing received.
+ *
+ * This function returns NETDEV_TX_OK on success and NETDEV_TX_BUSY on
+ * errors.
+ *
+ * The skb is not consumed, so the caller should make sure that the
+ * skb is freed. */
+int add_bcast_packet_to_list(struct sk_buff *skb)
{
struct forw_packet *forw_packet;
+ if (!atomic_dec_not_zero(&bcast_queue_left)) {
+ bat_dbg(DBG_BATMAN, "bcast packet queue full\n");
+ goto out;
+ }
+
forw_packet = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC);
+
if (!forw_packet)
- goto out;
+ goto out_and_inc;
skb = skb_copy(skb, GFP_ATOMIC);
if (!skb)
@@ -406,12 +421,14 @@
forw_packet->num_packets = 0;
_add_bcast_packet_to_list(forw_packet, 1);
- return;
+ return NETDEV_TX_OK;
packet_free:
kfree(forw_packet);
+out_and_inc:
+ atomic_inc(&bcast_queue_left);
out:
- return;
+ return NETDEV_TX_BUSY;
}
void send_outstanding_bcast_packet(struct work_struct *work)
@@ -446,8 +463,10 @@
if ((forw_packet->num_packets < 3) &&
(atomic_read(&module_state) != MODULE_DEACTIVATING))
_add_bcast_packet_to_list(forw_packet, ((5 * HZ) / 1000));
- else
+ else {
forw_packet_free(forw_packet);
+ atomic_inc(&bcast_queue_left);
+ }
}
void send_outstanding_bat_packet(struct work_struct *work)
@@ -473,6 +492,10 @@
(atomic_read(&module_state) != MODULE_DEACTIVATING))
schedule_own_packet(forw_packet->if_incoming);
+ /* don't count own packet */
+ if (!forw_packet->own)
+ atomic_inc(&batman_queue_left);
+
forw_packet_free(forw_packet);
}
Modified: trunk/batman-adv-kernelland/send.h
===================================================================
--- trunk/batman-adv-kernelland/send.h 2010-04-12 18:52:47 UTC (rev 1631)
+++ trunk/batman-adv-kernelland/send.h 2010-04-12 19:02:42 UTC (rev 1632)
@@ -33,7 +33,7 @@
struct batman_packet *batman_packet,
uint8_t directlink, int hna_buff_len,
struct batman_if *if_outgoing);
-void add_bcast_packet_to_list(struct sk_buff *skb);
+int add_bcast_packet_to_list(struct sk_buff *skb);
void send_outstanding_bcast_packet(struct work_struct *work);
void send_outstanding_bat_packet(struct work_struct *work);
void purge_outstanding_packets(struct batman_if *batman_if);
Modified: trunk/batman-adv-kernelland/soft-interface.c
===================================================================
--- trunk/batman-adv-kernelland/soft-interface.c 2010-04-12 18:52:47 UTC (rev 1631)
+++ trunk/batman-adv-kernelland/soft-interface.c 2010-04-12 19:02:42 UTC (rev 1632)
@@ -225,10 +225,10 @@
/* set broadcast sequence number */
bcast_packet->seqno = htons(bcast_seqno);
- bcast_seqno++;
+ /* broadcast packet. on success, increase seqno. */
+ if (add_bcast_packet_to_list(skb) == NETDEV_TX_OK)
+ bcast_seqno++;
- /* broadcast packet */
- add_bcast_packet_to_list(skb);
/* a copy is stored in the bcast list, therefore removing
* the original skb. */
kfree_skb(skb);