r1641 - trunk/batman-adv-kernelland
by postmaster@open-mesh.net
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) {
12 years, 9 months
r1640 - trunk/batman-adv-kernelland
by postmaster@open-mesh.net
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);
}
12 years, 9 months
r1639 - trunk/batman-adv-kernelland
by postmaster@open-mesh.net
Author: marek
Date: 2010-04-20 14:46:57 +0200 (Tue, 20 Apr 2010)
New Revision: 1639
Modified:
trunk/batman-adv-kernelland/gateway_common.c
Log:
batman-adv: reset selected gw variable after switching to gateway mode
If a node was in client mode and chose a gateway this choice was not
unset after switching to gateway mode.
Signed-off-by: Marek Lindner <lindner_marek(a)yahoo.de>
Modified: trunk/batman-adv-kernelland/gateway_common.c
===================================================================
--- trunk/batman-adv-kernelland/gateway_common.c 2010-04-19 21:14:19 UTC (rev 1638)
+++ trunk/batman-adv-kernelland/gateway_common.c 2010-04-20 12:46:57 UTC (rev 1639)
@@ -255,6 +255,7 @@
gw_srv_class_to_kbit((uint8_t)gw_class_tmp,
(int *)&down, (int *)&up);
+ gw_deselect();
printk(KERN_INFO
"batman-adv: Changing gateway mode from: '%s' to: '%s' (gw_class: %ld -> propagating: %ld%s/%ld%s)\n",
gw_mode_curr_str, gw_mode_tmp_str, gw_class_tmp,
12 years, 9 months
r1638 - trunk/batman-adv-kernelland
by postmaster@open-mesh.net
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);
}
12 years, 9 months
r1637 - trunk/batman-adv-kernelland
by postmaster@open-mesh.net
Author: simon
Date: 2010-04-19 22:13:31 +0200 (Mon, 19 Apr 2010)
New Revision: 1637
Modified:
trunk/batman-adv-kernelland/aggregation.c
trunk/batman-adv-kernelland/bat_sysfs.c
trunk/batman-adv-kernelland/main.c
trunk/batman-adv-kernelland/main.h
trunk/batman-adv-kernelland/send.c
trunk/batman-adv-kernelland/types.h
Log:
batman-adv: move queue counters into bat_priv
to support multiple mesh devices later, we need to move global variables
like the queues into corresponding private structs bat_priv of the soft
devices.
Note that this patch still has a lot of FIXMEs and depends on the global
soft_device variable. This should be resolved later, e.g. by referencing
the parent soft device in batman_if.
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-15 08:37:15 UTC (rev 1636)
+++ trunk/batman-adv-kernelland/aggregation.c 2010-04-19 20:13:31 UTC (rev 1637)
@@ -106,10 +106,12 @@
{
struct forw_packet *forw_packet_aggr;
unsigned long flags;
+ /* FIXME: each batman_if will be attached to a softif */
+ struct bat_priv *bat_priv = netdev_priv(soft_device);
/* own packet should always be scheduled */
if (!own_packet) {
- if (!atomic_dec_not_zero(&batman_queue_left)) {
+ if (!atomic_dec_not_zero(&bat_priv->batman_queue_left)) {
bat_dbg(DBG_BATMAN, "batman packet queue full\n");
return;
}
@@ -118,7 +120,7 @@
forw_packet_aggr = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC);
if (!forw_packet_aggr) {
if (!own_packet)
- atomic_inc(&batman_queue_left);
+ atomic_inc(&bat_priv->batman_queue_left);
return;
}
@@ -126,7 +128,7 @@
GFP_ATOMIC);
if (!forw_packet_aggr->packet_buff) {
if (!own_packet)
- atomic_inc(&batman_queue_left);
+ atomic_inc(&bat_priv->batman_queue_left);
kfree(forw_packet_aggr);
return;
}
Modified: trunk/batman-adv-kernelland/bat_sysfs.c
===================================================================
--- trunk/batman-adv-kernelland/bat_sysfs.c 2010-04-15 08:37:15 UTC (rev 1636)
+++ trunk/batman-adv-kernelland/bat_sysfs.c 2010-04-19 20:13:31 UTC (rev 1637)
@@ -408,6 +408,9 @@
atomic_set(&bat_priv->gw_mode, GW_MODE_OFF);
atomic_set(&bat_priv->gw_class, 0);
atomic_set(&bat_priv->orig_interval, 1000);
+ atomic_set(&bat_priv->bcast_queue_left, BCAST_QUEUE_LEN);
+ atomic_set(&bat_priv->batman_queue_left, BATMAN_QUEUE_LEN);
+
bat_priv->primary_if = NULL;
bat_priv->num_ifaces = 0;
Modified: trunk/batman-adv-kernelland/main.c
===================================================================
--- trunk/batman-adv-kernelland/main.c 2010-04-15 08:37:15 UTC (rev 1636)
+++ trunk/batman-adv-kernelland/main.c 2010-04-19 20:13:31 UTC (rev 1637)
@@ -44,8 +44,6 @@
DEFINE_SPINLOCK(forw_bcast_list_lock);
atomic_t vis_interval;
-atomic_t bcast_queue_left;
-atomic_t batman_queue_left;
int16_t num_hna;
@@ -84,8 +82,6 @@
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-15 08:37:15 UTC (rev 1636)
+++ trunk/batman-adv-kernelland/main.h 2010-04-19 20:13:31 UTC (rev 1637)
@@ -138,8 +138,6 @@
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-15 08:37:15 UTC (rev 1636)
+++ trunk/batman-adv-kernelland/send.c 2010-04-19 20:13:31 UTC (rev 1637)
@@ -397,8 +397,10 @@
int add_bcast_packet_to_list(struct sk_buff *skb)
{
struct forw_packet *forw_packet;
+ /* FIXME: each batman_if will be attached to a softif */
+ struct bat_priv *bat_priv = netdev_priv(soft_device);
- if (!atomic_dec_not_zero(&bcast_queue_left)) {
+ if (!atomic_dec_not_zero(&bat_priv->bcast_queue_left)) {
bat_dbg(DBG_BATMAN, "bcast packet queue full\n");
goto out;
}
@@ -426,7 +428,7 @@
packet_free:
kfree(forw_packet);
out_and_inc:
- atomic_inc(&bcast_queue_left);
+ atomic_inc(&bat_priv->bcast_queue_left);
out:
return NETDEV_TX_BUSY;
}
@@ -440,6 +442,8 @@
container_of(delayed_work, struct forw_packet, delayed_work);
unsigned long flags;
struct sk_buff *skb1;
+ /* FIXME: each batman_if will be attached to a softif */
+ struct bat_priv *bat_priv = netdev_priv(soft_device);
spin_lock_irqsave(&forw_bcast_list_lock, flags);
hlist_del(&forw_packet->list);
@@ -465,7 +469,7 @@
_add_bcast_packet_to_list(forw_packet, ((5 * HZ) / 1000));
else {
forw_packet_free(forw_packet);
- atomic_inc(&bcast_queue_left);
+ atomic_inc(&bat_priv->bcast_queue_left);
}
}
@@ -476,6 +480,8 @@
struct forw_packet *forw_packet =
container_of(delayed_work, struct forw_packet, delayed_work);
unsigned long flags;
+ /* FIXME: each batman_if will be attached to a softif */
+ struct bat_priv *bat_priv = netdev_priv(soft_device);
spin_lock_irqsave(&forw_bat_list_lock, flags);
hlist_del(&forw_packet->list);
@@ -494,7 +500,7 @@
/* don't count own packet */
if (!forw_packet->own)
- atomic_inc(&batman_queue_left);
+ atomic_inc(&bat_priv->batman_queue_left);
forw_packet_free(forw_packet);
}
Modified: trunk/batman-adv-kernelland/types.h
===================================================================
--- trunk/batman-adv-kernelland/types.h 2010-04-15 08:37:15 UTC (rev 1636)
+++ trunk/batman-adv-kernelland/types.h 2010-04-19 20:13:31 UTC (rev 1637)
@@ -104,6 +104,8 @@
atomic_t gw_mode;
atomic_t gw_class;
atomic_t orig_interval;
+ atomic_t bcast_queue_left;
+ atomic_t batman_queue_left;
char num_ifaces;
struct batman_if *primary_if;
struct kobject *mesh_obj;
12 years, 9 months
r1636 - in trunk/batman-experimental/lib: bmx_gsf_map bmx_howto_plugin bmx_http_info bmx_uci_config
by postmaster@open-mesh.net
Author: axel
Date: 2010-04-15 10:37:15 +0200 (Thu, 15 Apr 2010)
New Revision: 1636
Modified:
trunk/batman-experimental/lib/bmx_gsf_map/Makefile
trunk/batman-experimental/lib/bmx_howto_plugin/Makefile
trunk/batman-experimental/lib/bmx_http_info/Makefile
trunk/batman-experimental/lib/bmx_uci_config/Makefile
Log:
batman-experimental/lib/bmx_*/Makefile use -Os instead of -O1
Modified: trunk/batman-experimental/lib/bmx_gsf_map/Makefile
===================================================================
--- trunk/batman-experimental/lib/bmx_gsf_map/Makefile 2010-04-15 08:24:44 UTC (rev 1635)
+++ trunk/batman-experimental/lib/bmx_gsf_map/Makefile 2010-04-15 08:37:15 UTC (rev 1636)
@@ -1,5 +1,5 @@
-CFLAGS += -fpic -pedantic -Wall -W -Wno-unused-parameter -O1 -g3 -std=gnu99 -I../../
+CFLAGS += -fpic -pedantic -Wall -W -Wno-unused-parameter -Os -g3 -std=gnu99 -I../../
LDFLAGS += -shared
#-Wl,-soname,bmxd_config
Modified: trunk/batman-experimental/lib/bmx_howto_plugin/Makefile
===================================================================
--- trunk/batman-experimental/lib/bmx_howto_plugin/Makefile 2010-04-15 08:24:44 UTC (rev 1635)
+++ trunk/batman-experimental/lib/bmx_howto_plugin/Makefile 2010-04-15 08:37:15 UTC (rev 1636)
@@ -1,5 +1,5 @@
-CFLAGS += -fpic -pedantic -Wall -W -Wno-unused-parameter -O1 -g3 -std=gnu99 -I../../
+CFLAGS += -fpic -pedantic -Wall -W -Wno-unused-parameter -Os -g3 -std=gnu99 -I../../
LDFLAGS += -shared
#-Wl,-soname,bmxd_config
Modified: trunk/batman-experimental/lib/bmx_http_info/Makefile
===================================================================
--- trunk/batman-experimental/lib/bmx_http_info/Makefile 2010-04-15 08:24:44 UTC (rev 1635)
+++ trunk/batman-experimental/lib/bmx_http_info/Makefile 2010-04-15 08:37:15 UTC (rev 1636)
@@ -1,5 +1,5 @@
-CFLAGS += -fpic -pedantic -Wall -W -Wno-unused-parameter -O1 -g3 -std=gnu99 -I../../
+CFLAGS += -fpic -pedantic -Wall -W -Wno-unused-parameter -Os -g3 -std=gnu99 -I../../
LDFLAGS += -shared
#-Wl,-soname,bmxd_config
Modified: trunk/batman-experimental/lib/bmx_uci_config/Makefile
===================================================================
--- trunk/batman-experimental/lib/bmx_uci_config/Makefile 2010-04-15 08:24:44 UTC (rev 1635)
+++ trunk/batman-experimental/lib/bmx_uci_config/Makefile 2010-04-15 08:37:15 UTC (rev 1636)
@@ -1,5 +1,5 @@
-CFLAGS += -fpic -pedantic -Wall -W -Wno-unused-parameter -O1 -g3 -std=gnu99 -I../../
+CFLAGS += -fpic -pedantic -Wall -W -Wno-unused-parameter -Os -g3 -std=gnu99 -I../../
LDFLAGS += -shared -luci
#-Wl,-soname,bmx_config
12 years, 9 months
r1635 - trunk/batman-experimental/lib/bmx_gsf_map
by postmaster@open-mesh.net
Author: axel
Date: 2010-04-15 10:24:44 +0200 (Thu, 15 Apr 2010)
New Revision: 1635
Modified:
trunk/batman-experimental/lib/bmx_gsf_map/Makefile
Log:
batman-experimental/lib/bmx_gsf_map/Makefile fix Makefile
Modified: trunk/batman-experimental/lib/bmx_gsf_map/Makefile
===================================================================
--- trunk/batman-experimental/lib/bmx_gsf_map/Makefile 2010-04-15 08:16:16 UTC (rev 1634)
+++ trunk/batman-experimental/lib/bmx_gsf_map/Makefile 2010-04-15 08:24:44 UTC (rev 1635)
@@ -1,5 +1,38 @@
-PLUGINS = $(shell find -maxdepth 1 -type d | grep -e '^./bmx_' | sort)
+CFLAGS += -fpic -pedantic -Wall -W -Wno-unused-parameter -O1 -g3 -std=gnu99 -I../../
+LDFLAGS += -shared
+#-Wl,-soname,bmxd_config
-%:
- for d in $(PLUGINS); do $(MAKE) -C $$d $@ || echo compiling $$d failed; echo;echo; done
+PLUGIN_NAME = bmx_gsf_map
+PLUGIN_VER = 1
+
+SRC_C = gsf_map.c
+SRC_H = gsf_map.h
+OBJS= $(SRC_C:.c=.o)
+
+PLUGIN_FULLNAME = $(PLUGIN_NAME).so.$(PLUGIN_VER)
+PLUGIN_SHORTNAME = $(PLUGIN_NAME).so
+
+LIBDIR = /usr/lib
+
+all: $(PLUGIN_FULLNAME) Makefile
+
+
+$(PLUGIN_FULLNAME): $(OBJS) Makefile
+ $(CC) $(LDFLAGS) $(EXTRA_LDFLAGS) $(OBJS) -o $(PLUGIN_FULLNAME)
+
+%.o: %.c %.h Makefile
+ $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@
+
+
+clean:
+ rm -f *.o *.so.$(PLUGIN_VER)
+
+
+install: all
+ mkdir -p $(LIBDIR)
+ install -D -m 755 $(PLUGIN_FULLNAME) $(LIBDIR)/$(PLUGIN_FULLNAME); /sbin/ldconfig -n $(LIBDIR); ln -f -s $(LIBDIR)/$(PLUGIN_FULLNAME) $(LIBDIR)/$(PLUGIN_SHORTNAME)
+
+
+strip: all
+ strip $(PLUGIN_FULLNAME)
12 years, 9 months
r1634 - in trunk/batman-experimental: . lib/bmx_gsf_map lib/bmx_howto_plugin lib/bmx_http_info lib/bmx_uci_config linux posix
by postmaster@open-mesh.net
Author: axel
Date: 2010-04-15 10:16:16 +0200 (Thu, 15 Apr 2010)
New Revision: 1634
Added:
trunk/batman-experimental/avl.c
trunk/batman-experimental/avl.h
Modified:
trunk/batman-experimental/CHANGELOG
trunk/batman-experimental/Makefile
trunk/batman-experimental/allocate.c
trunk/batman-experimental/batman.c
trunk/batman-experimental/batman.h
trunk/batman-experimental/control.c
trunk/batman-experimental/control.h
trunk/batman-experimental/hna.c
trunk/batman-experimental/hna.h
trunk/batman-experimental/lib/bmx_gsf_map/Makefile
trunk/batman-experimental/lib/bmx_gsf_map/gsf_map.c
trunk/batman-experimental/lib/bmx_howto_plugin/howto_plugin.c
trunk/batman-experimental/lib/bmx_http_info/http_info.c
trunk/batman-experimental/lib/bmx_uci_config/HOWTO
trunk/batman-experimental/lib/bmx_uci_config/uci_config.c
trunk/batman-experimental/lib/bmx_uci_config/uci_config.h
trunk/batman-experimental/linux/route.c
trunk/batman-experimental/list-batman.c
trunk/batman-experimental/list-batman.h
trunk/batman-experimental/metrics.c
trunk/batman-experimental/metrics.h
trunk/batman-experimental/originator.c
trunk/batman-experimental/originator.h
trunk/batman-experimental/os.h
trunk/batman-experimental/plugin.c
trunk/batman-experimental/plugin.h
trunk/batman-experimental/posix/posix.c
trunk/batman-experimental/posix/tunnel.c
trunk/batman-experimental/schedule.c
trunk/batman-experimental/schedule.h
Log:
binary avl-tree, --ogi_power_save (mode), better OGM aggregation, many 64bit OS fixes, many cleanups
- debug sorted originator lists (using a binary avl-tree instead of hash)
- ogi_power_save (mode) for energy-restriced devices
- many 64-bit fixes
- harded ogm-aggregation and more tolerant acceptance of late OGMs (old SQNs) with --path_lounge_size
- dead-path detection by concurrent path-quality observation using a long-term and short-term observation window
Modified: trunk/batman-experimental/CHANGELOG
===================================================================
--- trunk/batman-experimental/CHANGELOG 2010-04-12 19:06:37 UTC (rev 1633)
+++ trunk/batman-experimental/CHANGELOG 2010-04-15 08:16:16 UTC (rev 1634)
@@ -3,7 +3,20 @@
Important changes should be listed in the following, most recent changes on top:
+---------------------------------------------------------------------------------------------------
+2010-04-15 -
+ - debug sorted originator lists (using a binary avl-tree instead of hash)
+
+ - ogi_power_save (mode) for energy-restriced devices
+
+ - many 64-bit fixes
+
+ - harded ogm-aggregation and more tolerant acceptance of late OGMs (old SQNs) with --path_lounge_size
+
+ - dead-path detection by concurrent path-quality observation using a long-term and short-term observation window
+
+
---------------------------------------------------------------------------------------------------
2009-08-18 - bmx_http_info and bmx_gsf_map plugin, ...
Modified: trunk/batman-experimental/Makefile
===================================================================
--- trunk/batman-experimental/Makefile 2010-04-12 19:06:37 UTC (rev 1633)
+++ trunk/batman-experimental/Makefile 2010-04-15 08:16:16 UTC (rev 1634)
@@ -20,17 +20,17 @@
REVISION_VERSION = \"\ rv$(REVISION)\"
-CFLAGS += -pedantic -Wall -W -Wno-unused-parameter -O1 -g3 -std=gnu99 -I./ -DREVISION_VERSION=$(REVISION_VERSION) -DDEBUG_MALLOC -DMEMORY_USAGE
+CFLAGS += -pedantic -Wall -W -Wno-unused-parameter -Os -g3 -std=gnu99 -I./ -DREVISION_VERSION=$(REVISION_VERSION) -DDEBUG_MALLOC -DMEMORY_USAGE
+#EXTRA_CFLAGS += -DTESTDEBUG
+#EXTRA_CFLAGS += -DNODEBUGALL
+
# Recommended defines and approximate binary sizes with gcc-x86
# -static
# -pedantic -Wall -W -Wno-unused-parameter -O1 -g3 -std=gnu99
# -pg # "-pg" with openWrt toolchain results in "gcrt1.o: No such file" ?!
#
-# compared to -O1 stripped:
-# -Os - ~29k
-#
# -DDEBUG_MALLOC + ~0k
# -DMEMORY_USAGE + ~1k
# -DPROFILE_DATA (some realtime profiling) + ~3k
@@ -38,6 +38,7 @@
# optional defines (you may disable these features if you dont need it):
# -DNOTRAILER - ~3K
# -DNODEBUGALL - ~13k
+# -DLESS_OPTIONS - ~7K
#
# -DNOTUNNEL (only affects this node) - ~23k
# -DNOSRV (only affects this node) - ~3k
@@ -72,8 +73,8 @@
SRC_FILES= "\(\.c\)\|\(\.h\)\|\(Makefile\)\|\(INSTALL\)\|\(LIESMICH\)\|\(README\)\|\(THANKS\)\|\(./posix\)\|\(./linux\)\|\(./man\)\|\(./doc\)"
-SRC_C= batman.c originator.c hna.c schedule.c plugin.c list-batman.c allocate.c hash.c profile.c control.c metrics.c $(OS_C)
-SRC_H= batman.h originator.h hna.h schedule.h plugin.h list-batman.h allocate.h hash.h profile.h control.h metrics.h vis-types.h os.h
+SRC_C= batman.c originator.c hna.c schedule.c plugin.c list-batman.c allocate.c avl.c profile.c control.c metrics.c $(OS_C)
+SRC_H= batman.h originator.h hna.h schedule.h plugin.h list-batman.h allocate.h avl.h profile.h control.h metrics.h vis-types.h os.h
OBJS= $(SRC_C:.c=.o)
#PACKAGE_NAME= batmand-exp
@@ -99,7 +100,7 @@
all:
$(MAKE) $(BINARY_NAME)
- $(MAKE) help
+ # further make targets: help, libs, build_all, strip[_libs|_all], install[_libs|_all], clean[_libs|_all]
libs: all
$(MAKE) -C lib all
@@ -148,7 +149,7 @@
help:
- # make targets:
+ # further make targets:
# help show this help
# all compile bmxd core only
# libs compile bmx plugins
Modified: trunk/batman-experimental/allocate.c
===================================================================
--- trunk/batman-experimental/allocate.c 2010-04-12 19:06:37 UTC (rev 1633)
+++ trunk/batman-experimental/allocate.c 2010-04-15 08:16:16 UTC (rev 1634)
@@ -193,8 +193,7 @@
for (walker = chunkList; walker != NULL; walker = walker->next) {
syslog( LOG_ERR, "Memory leak detected, malloc tag = %d\n", walker->tag );
- if (debug_level >= 0)
- fprintf( stderr, "Memory leak detected, malloc tag = %d \n", walker->tag );
+ fprintf( stderr, "Memory leak detected, malloc tag = %d \n", walker->tag );
}
Added: trunk/batman-experimental/avl.c
===================================================================
--- trunk/batman-experimental/avl.c (rev 0)
+++ trunk/batman-experimental/avl.c 2010-04-15 08:16:16 UTC (rev 1634)
@@ -0,0 +1,316 @@
+/* Copyright (C) 2006 B.A.T.M.A.N. contributors:
+ * Axel Neumann
+ *
+ * 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
+ *
+ */
+
+/*
+ * avl code inspired by:
+ * http://eternallyconfuzzled.com/tuts/datastructures/jsw_tut_avl.aspx
+ * where Julienne Walker said ( 28. 2. 2010 12:55):
+ * ...Once again, all of the code in this tutorial is in the public domain.
+ * You can do whatever you want with it, but I assume no responsibility
+ * for any damages from improper use. ;-)
+ */
+
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+
+#include "batman.h"
+#include "os.h"
+
+#include "avl.h"
+
+
+void *avl_find( struct avl_tree *tree, void *key )
+{
+
+ struct avl_node *it = tree->root;
+ int cmp;
+
+ // Search for a dead path or a matching entry
+ while ( it && ( cmp = memcmp(it->key, key, tree->key_size) ) )
+ it = it->link[ cmp < 0 ];
+
+
+ return it ? it->key : NULL;
+}
+
+
+
+void *avl_next(struct avl_tree *tree, void *key)
+{
+ struct avl_node *it = tree->root;
+ void *best = NULL;
+
+ if ( !it )
+ return NULL;
+
+ while (it) {
+
+ if ( memcmp(it->key, key, tree->key_size) <= 0 ) {
+
+ if (it->link[1]) {
+ it = it->link[1];
+ continue;
+ } else {
+ return best;
+ }
+
+ } else {
+
+ if (it->link[0]) {
+ best = it->key;
+ it = it->link[0];
+ continue;
+ } else {
+ return it->key;
+ }
+
+ }
+
+ }
+
+ paranoia( -500177, 1 );
+ return NULL;
+}
+
+
+
+static struct avl_node *avl_create_node(void *key)
+{
+ struct avl_node *an = debugMalloc(sizeof (struct avl_node), 327);
+
+ paranoia( -500189, !an );
+ memset( an, 0, sizeof( struct avl_node) );
+ an->key = key;
+
+ return an;
+}
+
+static struct avl_node *avl_rotate_single(struct avl_node *root, int dir)
+{
+ struct avl_node *save = root->link[!dir];
+ int rlh, rrh, slh;
+
+ /* Rotate */
+ root->link[!dir] = save->link[dir];
+ save->link[dir] = root;
+
+ /* Update balance factors */
+ rlh = avl_height(root->link[0]);
+ rrh = avl_height(root->link[1]);
+ slh = avl_height(save->link[!dir]);
+
+ root->balance = avl_max(rlh, rrh) + 1;
+ save->balance = avl_max(slh, root->balance) + 1;
+
+ return save;
+}
+
+static struct avl_node *avl_rotate_double(struct avl_node *root, int dir)
+{
+ root->link[!dir] = avl_rotate_single(root->link[!dir], !dir);
+ return avl_rotate_single(root, dir);
+}
+
+
+void avl_insert(struct avl_tree *tree, void *key) {
+
+ if (tree->root) {
+
+ struct avl_node *it = tree->root;
+ struct avl_node *up[AVL_MAX_HEIGHT];
+ int upd[AVL_MAX_HEIGHT], top = 0;
+ int done = 0;
+
+ /* Search for an empty link, save the path */
+ for (;;) {
+ /* Push direction and node onto stack */
+ upd[top] = memcmp(it->key, key, tree->key_size) < 0;
+ up[top++] = it;
+
+ if (it->link[upd[top - 1]] == NULL)
+ break;
+
+ it = it->link[upd[top - 1]];
+ }
+
+ /* Insert a new node at the bottom of the tree */
+ it->link[upd[top - 1]] = avl_create_node(key);
+
+ paranoia(-500178, (it->link[upd[top - 1]] == NULL));
+
+ /* Walk back up the search path */
+ while (--top >= 0 && !done) {
+
+ int lh, rh, max;
+
+ lh = avl_height(up[top]->link[upd[top]]);
+ rh = avl_height(up[top]->link[!upd[top]]);
+
+ /* Terminate or rebalance as necessary */
+ if (lh - rh == 0)
+ done = 1;
+ if (lh - rh >= 2) {
+ struct avl_node *a = up[top]->link[upd[top]]->link[upd[top]];
+ struct avl_node *b = up[top]->link[upd[top]]->link[!upd[top]];
+
+ if (avl_height(a) >= avl_height(b))
+ up[top] = avl_rotate_single(up[top], !upd[top]);
+ else
+ up[top] = avl_rotate_double(up[top], !upd[top]);
+
+ /* Fix parent */
+ if (top != 0)
+ up[top - 1]->link[upd[top - 1]] = up[top];
+ else
+ tree->root = up[0];
+
+ done = 1;
+ }
+
+ /* Update balance factors */
+ lh = avl_height(up[top]->link[upd[top]]);
+ rh = avl_height(up[top]->link[!upd[top]]);
+ max = avl_max(lh, rh);
+
+ up[top]->balance = max + 1;
+ }
+
+ } else {
+
+ tree->root = avl_create_node(key);
+ paranoia( -500179, (tree->root==NULL));
+
+ }
+
+ return;
+}
+
+
+
+void avl_remove(struct avl_tree *tree, void *key)
+{
+ struct avl_node *it = tree->root;
+ struct avl_node *up[AVL_MAX_HEIGHT];
+ int upd[AVL_MAX_HEIGHT], top = 0, cmp;
+
+ paranoia(-500182, !it); // paranoia if not found
+
+ while ((cmp = memcmp(it->key, key, tree->key_size))) {
+
+ // Push direction and node onto stack
+ upd[top] = (cmp < 0);
+ up[top] = it;
+
+ it = it->link[(cmp < 0)];
+ top++;
+ paranoia(-500180, !it); // paranoia if not found
+ }
+
+ // Remove the node:
+ if (!(it->link[0] && it->link[1])) { // at least one child is NULL:
+
+ // Which child is not null?
+ int dir = !(it->link[0]);
+
+ /* Fix parent */
+ if (top)
+ up[top - 1]->link[upd[top - 1]] = it->link[dir];
+ else
+ tree->root = it->link[dir];
+
+ debugFree(it, 1327);
+
+ } else { // both childs NOT NULL:
+
+ // Find the inorder successor
+ struct avl_node *heir = it->link[1];
+
+ // Save the path
+ upd[top] = 1;
+ up[top] = it;
+ top++;
+
+ while (heir->link[0]) {
+ upd[top] = 0;
+ up[top] = heir;
+ top++;
+ heir = heir->link[0];
+ }
+
+ // Swap data
+ it->key = heir->key;
+
+ // Unlink successor and fix parent
+ up[top - 1]->link[ (up[top - 1] == it) ] = heir->link[1];
+
+ debugFree(heir, 2327);
+ }
+
+ // Walk back up the search path
+ while (--top >= 0) {
+ int lh = avl_height(up[top]->link[upd[top]]);
+ int rh = avl_height(up[top]->link[!upd[top]]);
+ int max = avl_max(lh, rh);
+
+ /* Update balance factors */
+ up[top]->balance = max + 1;
+
+
+ // Terminate or re-balance as necessary:
+ if (lh - rh >= 0) // re-balance upper path...
+ continue;
+
+ if (lh - rh == -1) // balance for upper path unchanged!
+ break;
+
+ if (!(up[top]) || !(up[top]->link[!upd[top]])) {
+ dbgf(DBGL_SYS, DBGT_ERR, "up(top) %p link %p lh %d rh %d",
+ (void*)(up[top]), (void*)((up[top]) ? (up[top]->link[!upd[top]]) : NULL), lh, rh);
+
+ paranoia(-500187, (!(up[top])));
+ paranoia(-500188, (!(up[top]->link[!upd[top]])));
+ }
+/*
+ paranoia(-500183, (lh - rh <= -3) );
+ paranoia(-500185, (lh - rh == 2) );
+ paranoia(-500186, (lh - rh >= 3) );
+*/
+
+ // if (lh - rh <= -2): rebalance here and upper path
+
+ struct avl_node *a = up[top]->link[!upd[top]]->link[upd[top]];
+ struct avl_node *b = up[top]->link[!upd[top]]->link[!upd[top]];
+
+ if (avl_height(a) <= avl_height(b))
+ up[top] = avl_rotate_single(up[top], upd[top]);
+ else
+ up[top] = avl_rotate_double(up[top], upd[top]);
+
+ // Fix parent:
+ if (top)
+ up[top - 1]->link[upd[top - 1]] = up[top];
+ else
+ tree->root = up[0];
+ }
+
+}
+
Added: trunk/batman-experimental/avl.h
===================================================================
--- trunk/batman-experimental/avl.h (rev 0)
+++ trunk/batman-experimental/avl.h 2010-04-15 08:16:16 UTC (rev 1634)
@@ -0,0 +1,63 @@
+/* Copyright (C) 2006 B.A.T.M.A.N. contributors:
+ * Axel Neumann
+ *
+ * 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
+ *
+ */
+
+/*
+ * avl code based on:
+ * http://eternallyconfuzzled.com/tuts/datastructures/jsw_tut_avl.aspx
+ * where Julienne Walker said ( 28. 2. 2010 12:55):
+ * ...Once again, all of the code in this tutorial is in the public domain.
+ * You can do whatever you want with it, but I assume no responsibility
+ * for any damages from improper use. ;-)
+ */
+
+#ifndef _AVL_H
+#define _AVL_H
+
+#include <stdint.h>
+
+
+struct avl_node {
+ void *key;
+ int balance;
+ struct avl_node * link[2];
+};
+
+struct avl_tree {
+ uint16_t key_size;
+ struct avl_node *root;
+};
+
+
+#define AVL_INIT_TREE(tree, size) do { tree.root = NULL; tree.key_size = (size); } while (0)
+#define AVL_TREE(tree, size) struct avl_tree (tree) = { (size), NULL }
+
+
+#define AVL_MAX_HEIGHT 128
+
+#define avl_height(p) ((p) == NULL ? -1 : (p)->balance)
+#define avl_max(a,b) ((a) > (b) ? (a) : (b))
+
+void *avl_find( struct avl_tree *tree, void *key );
+void *avl_next( struct avl_tree *tree, void *key );
+void avl_insert(struct avl_tree *tree, void *key);
+void avl_remove(struct avl_tree *tree, void *key);
+
+
+
+#endif
\ No newline at end of file
Modified: trunk/batman-experimental/batman.c
===================================================================
--- trunk/batman-experimental/batman.c 2010-04-12 19:06:37 UTC (rev 1633)
+++ trunk/batman-experimental/batman.c 2010-04-15 08:16:16 UTC (rev 1634)
@@ -33,6 +33,7 @@
#include "metrics.h"
#include "plugin.h"
#include "schedule.h"
+//#include "avl.h"
@@ -65,7 +66,7 @@
int32_t Gateway_class = 0;
-uint8_t Link_flags = 0;
+//uint8_t Link_flags = 0;
uint32_t batman_time = 0;
uint32_t batman_time_sec = 0;
@@ -74,8 +75,6 @@
uint32_t s_curr_avg_cpu_load = 0;
-int Trash;
-
void batman( void ) {
struct list_head *list_pos;
@@ -206,7 +205,7 @@
((struct vis_packet *)vis_packet)->sender_ip = primary_addr;
((struct vis_packet *)vis_packet)->version = VIS_COMPAT_VERSION;
((struct vis_packet *)vis_packet)->gw_class = Gateway_class;
- ((struct vis_packet *)vis_packet)->seq_range = my_lws;
+ ((struct vis_packet *)vis_packet)->seq_range = local_lws;
/* iterate link list */
@@ -552,22 +551,22 @@
static int32_t opt_srvs ( uint8_t cmd, uint8_t _save, struct opt_type *opt, struct opt_parent *patch, struct ctrl_node *cn ) {
- struct hash_it_t *hashit = NULL;
-
int dbg_ogm_out = 0;
static char dbg_ogm_str[MAX_DBG_STR_SIZE + 1]; // TBD: must be checked for overflow when
-
+ struct orig_node *on;
uint16_t srv_count = 0;
if ( cmd != OPT_APPLY )
return SUCCESS;
dbg_printf( cn, "Originator Announced services ip:port:seqno ...\n");
-
- while ( (hashit = hash_iterate( orig_hash, hashit )) ) {
- struct orig_node *on = hashit->bucket->data;
+ uint32_t orig_ip = 0;
+ while ((on = (struct orig_node*) avl_next(&orig_avl, &orig_ip))) {
+
+ orig_ip = on->orig;
+
if ( on->router == NULL || srv_orig_registry < 0 || on->plugin_data[srv_orig_registry] == NULL )
continue;
@@ -618,10 +617,8 @@
static int32_t send_my_srv_ext( unsigned char* ext_buff ) {
- if ( my_srv_list_enabled )
- memcpy( ext_buff,
- (unsigned char *)my_srv_ext_array,
- my_srv_list_enabled * sizeof(struct ext_packet) );
+ if ( my_srv_list_enabled)
+ memcpy(ext_buff, (unsigned char *) my_srv_ext_array, my_srv_list_enabled * sizeof (struct ext_packet));
return my_srv_list_enabled * sizeof(struct ext_packet);
Modified: trunk/batman-experimental/batman.h
===================================================================
--- trunk/batman-experimental/batman.h 2010-04-12 19:06:37 UTC (rev 1633)
+++ trunk/batman-experimental/batman.h 2010-04-15 08:16:16 UTC (rev 1634)
@@ -28,10 +28,10 @@
#include <linux/if.h>
#include "list-batman.h"
-#include "hash.h"
#include "control.h"
#include "allocate.h"
#include "profile.h"
+#include "avl.h"
/***
@@ -61,9 +61,8 @@
* Global Variables and definitions
*/
+#define SOURCE_VERSION "0.3-rc1" //put exactly one distinct word inside the string like "0.3-pre-alpha" or "0.3-rc1" or "0.3"
-#define SOURCE_VERSION "0.3-alpha" //put exactly one distinct word inside the string like "0.3-pre-alpha" or "0.3-rc1" or "0.3"
-
#define COMPAT_VERSION 10
@@ -108,8 +107,9 @@
#define MAX_GW_UNAVAIL_FACTOR 10 /* 10 */
#define GW_UNAVAIL_TIMEOUT 10000
-#define CHOOSE_GW_DELAY_DIVISOR 1
+#define COMMON_OBSERVATION_WINDOW (DEF_OGI*DEF_PWS)
+
#define MAX_SELECT_TIMEOUT_MS 400 /* MUST be smaller than (1000/2) to fit into max tv_usec */
//#define TYPE_OF_WORD unsigned long /* you should choose something big, if you don't want to waste cpu */
@@ -137,13 +137,9 @@
#define MAX( a, b ) ( (a>b) ? (a) : (b) )
#define MIN( a, b ) ( (a<b) ? (a) : (b) )
+#define MAX_SQ( a, b ) ( (GREAT_SQ( (a), (b) )) ? (a) : (b) )
-#ifdef NOPARANOIA
-#define paranoia( ... )
-#else
-#define paranoia( code , problem ); do { if ( problem ) { cleanup_all( code ); } }while(0)
-#endif
#define WARNING_PERIOD 20000
@@ -157,8 +153,7 @@
could not be send by nodes with the old MAX_PACKET_SIZE = 256 */
#define MIN_UDPD_SIZE 24
#define DEF_UDPD_SIZE 256
-/* which is the maximum packet size which could be defined with the bat_header->size field */
-#define MAX_UDPD_SIZE 1024
+#define MAX_UDPD_SIZE (255<<2) //the maximum packet size which could be defined with the bat_header->size field
#define ARG_UDPD_SIZE "udp_data_size"
#define MAX_MTU 1500
@@ -257,8 +252,6 @@
extern uint32_t s_curr_avg_cpu_load;
-extern int Trash;
-
#define SQ_TYPE uint16_t
@@ -272,24 +265,27 @@
#define CLONED_FLAG 0x04 /* set when (re-)broadcasting a OGM not-for-the-first time or re-broadcasting a OGM with this flag */
-extern uint8_t Link_flags;
+//extern uint8_t Link_flags;
-#define UNICAST_PROBES_CAP 0x01 /* set on bat_header->link_flags to announce capability for unidirectional UDP link measurements */
+#define BAT_CAPAB_UNICAST_PROBES 0x01 /* set on bat_header->link_flags to announce capability for unidirectional UDP link measurements */
+#define BAT_CAPAB_ ...
struct bat_header
{
uint8_t version;
- uint8_t link_flags; // UNICAST_PROBES_CAP, ...
+ uint8_t link_flags; // BAT_CAPAB_UNICAST_PROBES, ...
uint8_t reserved;
uint8_t size; // the relevant data size in 4 oktets blocks of the packet (including the bat_header)
} __attribute__((packed));
-#define BAT_TYPE_OGM 0x00 // originator message
-#define BAT_TYPE_UPM 0x01 // unicast link-probe message
+#define BAT_TYPE_OGM 0x00 // originator message
+#define BAT_TYPE_UPM 0x01 // unicast link-probe message
+#define BAT_TYPE_ ...
+
struct bat_packet_common
{
#if __BYTE_ORDER == __LITTLE_ENDIAN
@@ -426,7 +422,6 @@
uint32_t neigh;
char neigh_str[ADDR_STR_LEN];
int16_t total_length;
- uint8_t link_flags;
uint8_t unicast;
//filled by strip_packet()
@@ -460,10 +455,11 @@
uint8_t own_if;
int32_t ogm_buff_len;
struct batman_if *if_outgoing;
+ struct bat_packet_ogm *ogm;
// the following ogm_buff array MUST be aligned with bit-range of the OS (64bit for 64-bit OS)
// having a pointer right before ensures this alignment.
- unsigned char ogm_buff[]; // this is to access following ogm data
+ unsigned char _attached_ogm_buff[]; // this is to access attached ogm data (only if allocated) !!!
};
@@ -483,21 +479,22 @@
char dev_phy[IFNAMSIZ+1];
char if_ip_str[ADDR_STR_LEN];
- int32_t if_index;
uint8_t if_active;
uint8_t if_scheduling;
-
- uint8_t if_reserved;
-
- uint8_t if_prefix_length;
+
+ uint16_t if_prefix_length;
+
+ int32_t if_index;
+ uint32_t if_netaddr;
+ uint32_t if_addr;
+ uint32_t if_broad;
+
+
uint32_t if_netmask;
- uint32_t if_netaddr;
int32_t if_rp_filter_orig;
int32_t if_send_redirects_orig;
- uint32_t if_addr;
- uint32_t if_broad;
struct sockaddr_in if_unicast_addr;
struct sockaddr_in if_netwbrc_addr;
@@ -508,13 +505,18 @@
SQ_TYPE if_seqno;
uint32_t if_seqno_schedule;
-
- struct send_node *own_send_node;
+ uint32_t if_last_link_activity;
+ uint32_t if_next_pwrsave_hardbeat;
+
+ /*
+ struct send_node own_send_struct;
struct bat_packet_ogm *own_ogm_out;
- unsigned char own_send_buff[MAX_UDPD_SIZE + 1 + sizeof(struct send_node)];
+ */
+
+ // having a pointer right before the following array ensures 32/64 bit alignment.
+ unsigned char *aggregation_out;
+ unsigned char aggregation_out_buff[MAX_UDPD_SIZE + 1];
- unsigned char aggregation_out[MAX_UDPD_SIZE + 1];
-
int16_t aggregation_len;
int8_t send_own;
@@ -527,6 +529,7 @@
int8_t if_linklayer;
int16_t if_ttl_conf;
+ int16_t if_ttl;
int16_t if_send_clones_conf;
int16_t if_send_clones;
@@ -542,13 +545,15 @@
struct orig_node /* structure for orig_list maintaining nodes of mesh */
{
- uint32_t orig; /* this must be the first four bytes! otherwise the hash functionality does not work */
+ uint32_t orig; /* this must be the first four bytes! otherwise avl or hash functionality do not work */
struct neigh_node *router; /* the neighbor which is the currently best_next_hop */
char orig_str[ADDR_STR_LEN];
struct list_head_first neigh_list;
+ struct avl_tree neigh_avl;
+
uint32_t last_aware; /* when last valid ogm via this node was received */
uint32_t last_valid_time; /* when last valid ogm from this node was received */
@@ -558,22 +563,32 @@
SQ_TYPE last_decided_sqn;
SQ_TYPE last_accepted_sqn; /* last squence number acceppted for metric */
SQ_TYPE last_valid_sqn; /* last and best known squence number */
-
+ SQ_TYPE last_wavg_sqn; /* last sequence number used for estimating ogi */
+
// From nodes with several interfaces we may know several originators,
// this points to the originator structure of the primary interface of a node
struct orig_node *primary_orig_node;
- //struct list_head_first pog_referrer_list;
int16_t pog_refcnt;
// uint8_t last_accept_largest_ttl; /* largest (best) TTL received with last sequence number */
uint8_t last_path_ttl;
-
+
uint8_t ogx_flag;
uint8_t pws;
- uint8_t path_lounge;
+// uint8_t path_lounge;
uint8_t ogm_misc;
-
+
+// uint8_t path_hystere;
+// uint8_t late_penalty;
+// uint8_t hop_penalty;
+// uint8_t asym_weight;
+
+// uint8_t rcnt_pws;
+// uint8_t rcnt_lounge;
+// uint8_t rcnt_hystere;
+// uint8_t rcnt_fk;
+
uint32_t ogi_wavg;
uint32_t rt_changes;
@@ -595,25 +610,18 @@
};
-/*
-struct pog_referrer_node
-{
- struct list_head list;
- uint32_t addr;
-};
-*/
#define SQN_LOUNGE_SIZE (8*sizeof(uint32_t)) /* must correspond to bits of neigh_node->considered_seqnos */
struct sq_record {
SQ_TYPE wa_clr_sqn; // SQN upto which waightedAverageVal has been purged
- SQ_TYPE wa_set_sqn; // SQN which has been applied (if equals wa_pos) then wa_unscaled MUST NO be set again!
+ SQ_TYPE wa_set_sqn; // SQN which has been applied (if equals wa_pos) then wa_unscaled MUST NOT be set again!
uint32_t wa_unscaled; // unscaled summary value of processed SQNs
uint32_t wa_val; // scaled and representative value of processed SQNs
- uint8_t sqn_entry_queue[SQN_LOUNGE_SIZE]; // cache for greatest rcvd SQNs waiting to be processed
- SQ_TYPE sqn_entry_queue_tip; // the greatest SQN rcvd so fare
+// uint8_t sqn_entry_queue[SQN_LOUNGE_SIZE]; // cache for greatest rcvd SQNs waiting to be processed
+// SQ_TYPE sqn_entry_queue_tip; // the greatest SQN rcvd so fare
};
@@ -638,32 +646,39 @@
*/
struct link_node
{
+ uint32_t orig_addr;
+
struct list_head list;
-
+
struct orig_node *orig_node;
- uint8_t link_flags;
struct list_head_first lndev_list; // list with one link_node_dev element per link
};
+struct neigh_node_key {
+ uint32_t addr;
+ struct batman_if *iif;
+};
-
-
/* Path statistics per neighbor via which OGMs of the parent orig_node have been received */
/* Every OG has one ore several neigh_nodes. */
struct neigh_node
{
+
+ struct neigh_node_key key;
+#define nnkey_addr key.addr
+#define nnkey_iif key.iif
+// uint32_t nnkey_addr;
+// struct batman_if *nnkey_iif;
+
struct list_head list;
- uint32_t addr;
uint32_t last_aware; /* when last packet via this neighbour was received */
- uint32_t considered_seqnos; //MUST have SQN_LOUNGE_SIZE bits
SQ_TYPE last_considered_seqno;
- struct batman_if *iif;
-
- struct sq_record accepted_sqr;
+ struct sq_record longtm_sqr;
+ struct sq_record recent_sqr;
};
Modified: trunk/batman-experimental/control.c
===================================================================
--- trunk/batman-experimental/control.c 2010-04-12 19:06:37 UTC (rev 1633)
+++ trunk/batman-experimental/control.c 2010-04-15 08:16:16 UTC (rev 1634)
@@ -41,12 +41,20 @@
static char run_dir[MAX_PATH_SIZE] = DEF_RUN_DIR;
-int32_t debug_level = -1;
+static int32_t debug_level = -1;
static int32_t dbg_mute_to;
-static int32_t loop_period;
+
+#define MIN_LOOP_PERIOD 100
+#define MAX_LOOP_PERIOD 10000
+#define DEF_LOOP_PERIOD 1000
+static int32_t loop_period = DEF_LOOP_PERIOD;
+
static int32_t loop_mode;
-static int32_t pedantic_cmd_check;
+#define MIN_PEDANT_CHK NO
+#define MAX_PEDANT_CHK YES
+#define DEF_PEDANT_CHK NO
+static int32_t pedantic_check = DEF_PEDANT_CHK;
int unix_sock = 0;
@@ -246,7 +254,8 @@
void close_ctrl_node( uint8_t cmd, struct ctrl_node *ctrl_node ) {
struct list_head* list_pos, *list_prev, *list_tmp;
-
+ int trash;
+
list_prev = (struct list_head *)&ctrl_list;
list_for_each_safe( list_pos, list_tmp, &ctrl_list ) {
@@ -265,7 +274,7 @@
if ( cmd == CTRL_CLOSE_SUCCESS )
- Trash = write( cn->fd, CONNECTION_END_STR, strlen(CONNECTION_END_STR) );
+ trash=write( cn->fd, CONNECTION_END_STR, strlen(CONNECTION_END_STR) );
if ( cmd != CTRL_CLOSE_DELAY ) {
close( cn->fd );
@@ -935,7 +944,7 @@
* call given function for each applied option
* thus: if several hna are active func() is called once for each
*/
-int8_t func_for_each_opt( struct ctrl_node *cn, void *data, struct opt_type *opt_tmpl, char* func_name,
+int8_t func_for_each_opt( struct ctrl_node *cn, void *data, char* func_name,
int8_t (*func) ( struct ctrl_node *cn, void *data, struct opt_type *opt, struct opt_parent *p, struct opt_child *c ) )
{
@@ -947,46 +956,33 @@
if ( /* !opt->help || we are also interested in uncommented configurations*/ !opt->long_name )
continue;
-
- if ( !( /*proceed if:*/ !opt_tmpl || opt_tmpl == opt || !list_empty(&opt->d.childs_type_list) ) )
- continue;
-
-
+
struct list_head *p_pos;
list_for_each( p_pos, &(opt->d.parents_instance_list) ) {
struct opt_parent *p = (struct opt_parent*)list_entry( p_pos, struct opt_parent, list );
- if ( !opt_tmpl || opt_tmpl == opt ) {
-
- if ( (*func)( cn, data, opt, p, NULL ) == FAILURE ) {
-
- dbgf_cn( cn, DBGL_SYS, DBGT_ERR,
- "%s func()=%s with %s %s failed",
- opt_tmpl->long_name, func_name, opt->long_name, p->p_val );
-
- return FAILURE;
- }
- }
+ if ( (*func)( cn, data, opt, p, NULL ) == FAILURE ) {
+
+ dbgf_cn( cn, DBGL_SYS, DBGT_ERR,
+ "func()=%s with %s %s failed",
+ func_name, opt->long_name, p->p_val );
+
+ return FAILURE;
+ }
struct list_head *c_pos;
list_for_each( c_pos, &p->childs_instance_list ) {
- struct opt_child *c =
- (struct opt_child*)list_entry( c_pos, struct opt_child, list );
+ struct opt_child *c = (struct opt_child*)list_entry( c_pos, struct opt_child, list );
- if ( !( /*proceed if:*/ !opt_tmpl || opt_tmpl == c->c_opt ) )
- continue;
-
-
if ( (*func)( cn, data, opt, p, c ) == FAILURE ) {
dbgf_cn( cn, DBGL_SYS, DBGT_ERR,
- "%s func()=%s with %s %s %s %s failed",
- opt_tmpl->long_name, func_name,
- opt->long_name, p->p_val, c->c_opt->long_name, c->c_val );
+ "func()=%s with %s %s %s %s failed",
+ func_name, opt->long_name, p->p_val, c->c_opt->long_name, c->c_val );
return FAILURE;
}
@@ -1004,12 +1000,14 @@
return;
dbg_printf(cn, "\n");
- dbg_printf(cn, "Usage: %s [LONGOPT [%c]VAL] | [-SHORTOPT[SHORTOPT...] [%c]VAL] ...\n",
+ dbg_printf(cn, "Usage: %s [LONGOPT[=[%c]VAL]] | [-SHORTOPT[SHORTOPT...] [[%c]VAL]] ...\n",
prog_name, ARG_RESET_CHAR , ARG_RESET_CHAR);
- dbg_printf(cn, " e.g. %s -cid8\n", prog_name);
- dbg_printf(cn, " e.g. %s -c a 192.200.200.1/24\n", prog_name);
- dbg_printf(cn, " e.g. %s -c %s my-vpn /n=192.168.115.0 /m=24\n", prog_name, ARG_THROW);
- dbg_printf(cn, " e.g. %s -c %s -my-vpn \n", prog_name, ARG_THROW);
+ dbg_printf(cn, " e.g. %s dev=eth0 dev=wlan0 # to start daemon on interface eth0 and wlan0\n", prog_name);
+ dbg_printf(cn, " e.g. %s plugin=bmx_http_info.so -X # to show verbose help of bmxd and its' plugin\n", prog_name);
+
+ dbg_printf(cn, " e.g. %s -c -a 192.200.200.1/24 # to connect to running bmxd and announce given network\n", prog_name);
+ dbg_printf(cn, " e.g. %s -c -a -192.200.200.1/24 # to connect and stop announcing given network\n", prog_name);
+ dbg_printf(cn, " e.g. %s -cid8 # to connect and show configured options and connevtivity\n", prog_name);
dbg_printf(cn, "\n");
//dbg_printf(cn, "\nValid options are:\n" );
@@ -1019,6 +1017,7 @@
struct list_head *pos;
struct opt_type *opt = (struct opt_type *)list_entry( list_pos, struct opt_data, list );
+ char sn[5], st[3 * MAX_ARG_SIZE], defaults[100];
if ( !( all_opts || opt->short_name ) )
continue;
@@ -1030,25 +1029,25 @@
if ( opt->long_name && opt->help && !opt->parent_name ) {
- char sn[5];
+
if ( opt->short_name )
snprintf( sn,5, ", -%c", opt->short_name );
-
else
*sn = '\0';
+ sprintf( st, "--%s%s %s ", opt->long_name, sn, opt->syntax ? opt->syntax: "" );
+
+ if ( opt->opt_t != A_PS0 && opt->imin != opt->imax )
+ sprintf( defaults, "def: %-6d range: [ %d %s %d ]",
+ opt->idef, opt->imin, opt->imin+1 == opt->imax ? ",": "...", opt->imax );
+ else
+ defaults[0]='\0';
+
+ dbg_printf( cn, "\n%-40s %s\n", st, defaults );
- char ln[MAX_ARG_SIZE];
- snprintf( ln,MAX_ARG_SIZE, "--%s", opt->long_name );
-
- dbg_printf( cn, "\n%s%s %s \n", ln, sn, opt->syntax ? opt->syntax: "" );
-
if ( verbose )
dbg_printf( cn, " %s\n", opt->help );
- if ( verbose && opt->opt_t != A_PS0 && opt->imin != opt->imax )
- dbg_printf( cn, " default: %5d, valid range: [ %d %s %d ] \n",
- opt->idef, opt->imin, opt->imin+1 == opt->imax ? ",": "...", opt->imax );
} else if ( !opt->long_name && opt->help ) {
@@ -1062,36 +1061,32 @@
struct opt_type *c_opt = (struct opt_type *)list_entry( pos, struct opt_data, list );
- if ( !c_opt->parent_name )
+ if ( !c_opt->parent_name || !c_opt->help )
continue;
- if ( !c_opt->help )
- continue;
-
#ifndef NODEPRECATED
if ( c_opt->call_custom_option == opt_deprecated )
continue;
#endif
-
- char sn[5];
- if ( c_opt->short_name )
- snprintf( sn,5, " ,/%c", c_opt->short_name );
-
- else
+
+ if ( c_opt->short_name )
+ snprintf( sn,5, ", /%c", c_opt->short_name );
+ else
*sn = '\0';
-
- char ln[MAX_ARG_SIZE];
- snprintf( ln,MAX_ARG_SIZE, "/%s", c_opt->long_name );
-
- dbg_printf( cn, "\n %s%s %s \n", ln, sn, c_opt->syntax ? c_opt->syntax: "" );
-
+
+ sprintf( st, " /%s%s %s ", c_opt->long_name, sn, c_opt->syntax ? c_opt->syntax: "" );
+
+ if ( c_opt->opt_t != A_PS0 && c_opt->imin != c_opt->imax )
+ sprintf( defaults, "def: %-6d range: [ %d %s %d ]",
+ c_opt->idef, c_opt->imin, c_opt->imin+1 == c_opt->imax ? ",": "...", c_opt->imax );
+ else
+ defaults[0]='\0';
+
+ dbg_printf( cn, "%-40s %s\n", st, defaults );
+
if ( verbose )
- dbg_printf( cn, " %s\n", c_opt->help );
-
- if ( verbose && c_opt->opt_t != A_PS0 && c_opt->imin != c_opt->imax )
- dbg_printf( cn, " default: %5d, valid range: [ %d %s %d ] \n",
- c_opt->idef, c_opt->imin, c_opt->imin+1 == c_opt->imax ? ",": "...", c_opt->imax );
-
+ dbg_printf( cn, " %s\n", c_opt->help );
+
}
}
@@ -1773,6 +1768,7 @@
char tmp_path[MAX_PATH_SIZE+20] = "";
char unix_buff[MAX_UNIX_MSG_SIZE+1] = "";
+ int trash;
dbgf_all( DBGT_INFO, "cmd %s, opt_name %s, stream %s",
opt_cmd2str[cmd], opt->long_name, curr_strm_pos );
@@ -1856,7 +1852,7 @@
//printf("::::::::::::::::: from %s begin :::::::::::::::::::\n", tmp_path );
if ( loop_mode )
- Trash = system( "clear" );
+ trash=system( "clear" );
int32_t recv_buff_len = 0;
@@ -2243,7 +2239,7 @@
}
// be pedantic only after startup (!on_the_fly) and not reload-config (!save)
- if ( !changed && on_the_fly && save && pedantic_cmd_check ) {
+ if ( !changed && on_the_fly && save && pedantic_check ) {
dbg_cn( cn, DBGL_SYS, DBGT_ERR, "--%s %s already configured",
p_opt->long_name, p_patch->p_val );
@@ -2278,7 +2274,8 @@
return FAILURE;
}
- if ( ad == DEL && ( !on_the_fly /*|| opt->dyn_t == A_INI this is what conf-reload tries */ || opt->cfg_t == A_ARG ) ) {
+ if ( ad == DEL && ( /*!on_the_fly this is what concurrent -r and -g configurations do || */
+ /* opt->dyn_t == A_INI this is what conf-reload tries ||*/ opt->cfg_t == A_ARG ) ) {
dbg( DBGL_SYS, DBGT_ERR, "option %s can not be resetted during startup!", opt->long_name );
return FAILURE;
}
@@ -2457,7 +2454,7 @@
LONG_OPT_ARG_VAL, // 7
};
- char *state2str[] = {"NEXT_OPT","NEW_OPT","SHORT_OPT","LONG_OPT","LONG_OPT_VAL","LONG_OPT_WHAT","LONG_OPT_ARG","LONG_OPT_ARG_VAL"};
+ //char *state2str[] = {"NEXT_OPT","NEW_OPT","SHORT_OPT","LONG_OPT","LONG_OPT_VAL","LONG_OPT_WHAT","LONG_OPT_ARG","LONG_OPT_ARG_VAL"};
int8_t state = NEW_OPT;
@@ -2481,8 +2478,8 @@
while ( s && strlen(s) >= 1 ) {
- dbgf_all( DBGT_INFO, "cmd: %-10s, state: %s opt: %s, wordlen: %d rest: %s",
- opt_cmd2str[cmd], state2str[state], opt?opt->long_name:"null", wordlen(s), s );
+ dbgf_all( DBGT_INFO, "cmd: %-10s, state: 0x%X opt: %s, wordlen: %d rest: %s",
+ opt_cmd2str[cmd], state, opt?opt->long_name:"null", wordlen(s), s );
if ( Testing ) {
Testing = 0;
@@ -3049,7 +3046,7 @@
dbg_printf(cn, "\n");
*/
- func_for_each_opt( cn, NULL, NULL, "opt_show_info()", show_info );
+ func_for_each_opt( cn, NULL, "opt_show_info()", show_info );
if ( !on_the_fly )
cleanup_all(CLEANUP_SUCCESS);
@@ -3285,34 +3282,31 @@
{ODI,3,0,"loop_mode", 'l',A_PS0,A_ADM,A_INI,A_ARG,A_ANY, &loop_mode, 0, 1, 0, 0,
0, "put client daemon in loop mode to periodically refresh debug information"},
- {ODI,3,0,"loop_period", 0, A_PS1,A_ADM,A_INI,A_ARG,A_ANY, &loop_period, 100, 10000, 1000, 0,
+#ifndef LESS_OPTIONS
+ {ODI,3,0,"loop_period", 0, A_PS1,A_ADM,A_INI,A_ARG,A_ANY, &loop_period, MIN_LOOP_PERIOD,MAX_LOOP_PERIOD,DEF_LOOP_PERIOD,0,
ARG_VALUE_FORM, "periodicity in ms with which client daemon in loop-mode refreshes debug information"},
+#endif
-//config.c
#ifndef NODEPRECATED
{ODI,3,0,"batch_mode", 'b',A_PS0,A_ADM,A_INI,A_ARG,A_ANY, 0, 0, 0, 0, opt_deprecated,0,0},
#endif
-//control.c
{ODI,3,0,ARG_CONNECT, 'c',A_PS0,A_ADM,A_INI,A_ARG,A_EAT, 0, 0, 0, 0, opt_connect,
0, "set client mode. Connect and forward remaining args to main routing daemon"},
-//config.c
//order=5: so when used during startup it also shows the config-file options
{ODI,5,0,ARG_SHOW_CHANGED, 'i',A_PS0,A_ADM,A_DYI,A_ARG,A_ANY, 0, 0, 0, 0, opt_show_info,
0, "inform about configured options" },
-
-//config.c
- {ODI,5,0,ARG_PEDANTIC_CMDCHECK, 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &pedantic_cmd_check,0, 1, 0, 0,
+#ifndef LESS_OPTIONS
+ {ODI,5,0,ARG_PEDANTIC_CMDCHECK, 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &pedantic_check,MIN_PEDANT_CHK, MAX_PEDANT_CHK, DEF_PEDANT_CHK, 0,
ARG_VALUE_FORM, "disable/enable pedantic checking of command-line parameters and context -\n"
" ( e.g. fail setting a parameter without changing it)" },
-
- //control.c
+#endif
{ODI,5,0,"dbg_mute_timeout", 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &dbg_mute_to, 0, 10000000, 100000, 0,
ARG_VALUE_FORM, "set timeout in ms for muting frequent messages"},
-
+
#ifndef NODEPRECATED
-//batman.c
+
{ODI,5,0,"fake_uptime", 0, A_PS1,A_ADM,A_DYN,A_ARG,A_ANY, 0, MIN_UPTIME, MAX_UPTIME, 0, opt_uptime,0,0},
{ODI,5,0,"bmx_defaults", 0, A_PS0,A_ADM,A_INI,A_ARG,A_ANY, 0, 0, 0, 0, opt_deprecated,0,0},
@@ -3321,7 +3315,6 @@
{ODI,5,0,"24c3", 0, A_PS0,A_ADM,A_INI,A_ARG,A_ANY, 0, 0, 0, 0, opt_deprecated,0,0},
#endif
-//config.c
{ODI,5,0,ARG_QUIT,EOS_DELIMITER, A_PS0,A_USR,A_DYN,A_ARG,A_END, 0, 0, 0, 0, opt_quit,0,0}
};
@@ -3331,6 +3324,10 @@
int i;
+ char *d = getenv(BMX_ENV_DEBUG);
+ if ( d && strtol(d, NULL , 10) >= DBGL_MIN && strtol(d, NULL , 10) <= DBGL_MAX )
+ debug_level = strtol(d, NULL , 10);
+
for ( i = DBGL_MIN; i <= DBGL_MAX; i++ )
INIT_LIST_HEAD_FIRST( dbgl_clients[i] );
Modified: trunk/batman-experimental/control.h
===================================================================
--- trunk/batman-experimental/control.h 2010-04-12 19:06:37 UTC (rev 1633)
+++ trunk/batman-experimental/control.h 2010-04-15 08:16:16 UTC (rev 1634)
@@ -28,7 +28,7 @@
#define DBGT_ERR 3
-extern int debug_level;
+//extern int debug_level;
#define DBGL_MIN 0
#define DBGL_SYS 0
#define DBGL_ROUTES 1
@@ -325,7 +325,7 @@
OPT_CHECK,
- // to test a give patch (type-value pair) !
+ // to test a given patch (type-value pair) !
// Returns FAILURE or n>=0 of processed bytes-1
@@ -378,7 +378,7 @@
-int8_t func_for_each_opt( struct ctrl_node *cn, void *data, struct opt_type *opt_tmpl, char* func_name,
+int8_t func_for_each_opt( struct ctrl_node *cn, void *data, char* func_name,
int8_t (*func) ( struct ctrl_node *cn, void *data, struct opt_type *opt, struct opt_parent *p, struct opt_child *c ) );
int respect_opt_order( uint8_t test, int8_t last, int8_t next, struct opt_type *on, uint8_t load_config, uint8_t cmd, struct ctrl_node *cn );
Modified: trunk/batman-experimental/hna.c
===================================================================
--- trunk/batman-experimental/hna.c 2010-04-12 19:06:37 UTC (rev 1633)
+++ trunk/batman-experimental/hna.c 2010-04-15 08:16:16 UTC (rev 1634)
@@ -22,12 +22,17 @@
#include <string.h>
#include <stdio.h>
+#include <asm/types.h>
+#include <sys/socket.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
#include "batman.h"
#include "os.h"
#include "originator.h"
#include "plugin.h"
#include "hna.h"
+//#include "avl.h"
static int32_t hna_orig_registry = FAILURE;
@@ -35,52 +40,42 @@
static struct ext_type_hna *my_hna_ext_array = NULL;
static uint16_t my_hna_list_enabled = 0;
-static struct hashtable_t *hna_hash = NULL;
+//static struct avl_tree hna_avl = { sizeof(struct hna_key), NULL};
+static AVL_TREE( hna_avl, sizeof(struct hna_key) );
-
// this function finds (or if it does not exits and create is true it creates)
// an hna entry for the given hna address, anetmask, and atype
-static struct hna_hash_node *get_hna_node( struct hna_key *hk, uint8_t create ) {
+static struct hna_node *get_hna_node( struct hna_key *hk, uint8_t create ) {
- struct hna_hash_node *hash_node;
- struct hashtable_t *swaphash;
+ struct hna_node *hn;
+ hn = ((struct hna_node *)avl_find( &hna_avl, hk ));
- hash_node = ((struct hna_hash_node *)hash_find( hna_hash, hk ));
-
- if ( hash_node ) {
+ if ( hn ) {
- paranoia( -500022, ( memcmp( hk, &hash_node->key, sizeof( struct hna_key ) ) ) );// found incorrect key
+ paranoia( -500022, ( memcmp( hk, &hn->key, sizeof( struct hna_key ) ) ) );// found incorrect key
- return hash_node;
+ return hn;
}
if ( !create )
return NULL;
- dbgf_all( DBGT_INFO, " creating new and empty hna_hash_node: %s/%d, type %d",
+ dbgf_all( DBGT_INFO, " creating new and empty hna_node: %s/%d, type %d",
ipStr(hk->addr), hk->KEY_FIELD_ANETMASK, hk->KEY_FIELD_ATYPE );
- hash_node = debugMalloc( sizeof(struct hna_hash_node), 401 );
- memset(hash_node, 0, sizeof(struct hna_hash_node));
+ hn = debugMalloc( sizeof(struct hna_node), 401 );
+ memset(hn, 0, sizeof(struct hna_node));
- hash_node->key.addr = hk->addr;
- hash_node->key.KEY_FIELD_ATYPE = hk->KEY_FIELD_ATYPE;
- hash_node->key.KEY_FIELD_ANETMASK = hk->KEY_FIELD_ANETMASK;
- hash_node->status = HNA_HASH_NODE_EMPTY;
+ hn->key.addr = hk->addr;
+ hn->key.KEY_FIELD_ATYPE = hk->KEY_FIELD_ATYPE;
+ hn->key.KEY_FIELD_ANETMASK = hk->KEY_FIELD_ANETMASK;
+ hn->status = HNA_HASH_NODE_EMPTY;
- hash_add( hna_hash, hash_node );
+ avl_insert( &hna_avl, hn );
- if ( hna_hash->elements * 4 > hna_hash->size ) {
-
- if ( !(swaphash = hash_resize( hna_hash, hna_hash->size * 2 )) )
- cleanup_all( -500095 );
-
- hna_hash = swaphash;
- }
+ paranoia( -500022, ( memcmp( hk, &hn->key, sizeof( struct hna_key ) ) ) );// found incorrect key
- paranoia( -500022, ( memcmp( hk, &hash_node->key, sizeof( struct hna_key ) ) ) );// found incorrect key
-
- return hash_node;
+ return hn;
}
@@ -91,14 +86,14 @@
if ( atype > A_TYPE_MAX ) // NOT YET supported!
return SUCCESS;
- uint8_t err = !del && other_orig && ( !router || !router->addr || !router->iif );
+ uint8_t err = !del && other_orig && ( !router || !router->nnkey_addr || !router->nnkey_iif );
- dbgf( ( err ? DBGL_SYS : DBGL_CHANGES ), ( err ? DBGT_ERR : DBGT_INFO ),
+ dbgf( ( err ? DBGL_SYS : DBGL_ALL ), ( err ? DBGT_ERR : DBGT_INFO ),
"%s %s %s %s %s/%d %d",
del?"DEL":"ADD",
other_orig?ipStr(other_orig->orig):"myself",
- ipStr( router&&router->addr ? router->addr : 0 ),
- ( router&&router->iif ? router->iif->dev : "???" ),
+ ipStr( router&&router->nnkey_addr ? router->nnkey_addr : 0 ),
+ ( router&&router->nnkey_iif ? router->nnkey_iif->dev : "???" ),
ipStr(ip), mask, atype );
paranoia( -500023, err );
@@ -107,77 +102,73 @@
key.addr = ip;
key.KEY_FIELD_ANETMASK = mask;
key.KEY_FIELD_ATYPE = atype;
+
+ int16_t rt_table = (atype == A_TYPE_INTERFACE || atype == A_TYPE_NETWORK) ? RT_TABLE_NETWORKS : 0;
- uint8_t rt_table = ( atype == A_TYPE_INTERFACE ? RT_TABLE_INTERFACES :
- (atype == A_TYPE_NETWORK ? RT_TABLE_NETWORKS : 0 ) );
-
- struct hna_hash_node *hhn = get_hna_node( &key, NO/*create*/);
-
+ struct hna_node *hn = get_hna_node( &key, NO/*create*/);
+
+
if ( del ) {
- if ( !other_orig && hhn && hhn->status == HNA_HASH_NODE_MYONE ) {
+ if ( !other_orig && hn && hn->status == HNA_HASH_NODE_MYONE ) {
/* del throw routing entries for own hna */
- add_del_route( ip, mask, 0,0,0, "unknown", RT_TABLE_HOSTS, RT_THROW, DEL, TRACK_MY_HNA );
- add_del_route( ip, mask, 0,0,0, "unknown", RT_TABLE_INTERFACES, RT_THROW, DEL, TRACK_MY_HNA );
- add_del_route( ip, mask, 0,0,0, "unknown", RT_TABLE_NETWORKS, RT_THROW, DEL, TRACK_MY_HNA );
- add_del_route( ip, mask, 0,0,0, "unknown", RT_TABLE_TUNNEL, RT_THROW, DEL, TRACK_MY_HNA );
+ add_del_route( ip, mask, 0,0,0, "unknown", RT_TABLE_HOSTS, RTN_THROW, DEL, TRACK_MY_HNA );
+ add_del_route( ip, mask, 0,0,0, "unknown", RT_TABLE_NETWORKS, RTN_THROW, DEL, TRACK_MY_HNA );
+ add_del_route( ip, mask, 0,0,0, "unknown", RT_TABLE_TUNNEL, RTN_THROW, DEL, TRACK_MY_HNA );
my_hna_list_enabled--;
- } else if ( other_orig && hhn && hhn->status == HNA_HASH_NODE_OTHER && hhn->orig == other_orig ) {
+ } else if ( other_orig && hn && hn->status == HNA_HASH_NODE_OTHER && hn->orig == other_orig ) {
- add_del_route( ip, mask, 0, primary_addr, 0, 0, rt_table, RT_UNICAST, DEL, TRACK_OTHER_HNA );
+ add_del_route( ip, mask, 0, primary_addr, 0, 0, rt_table, RTN_UNICAST, DEL, TRACK_OTHER_HNA );
- } else if ( !hhn ) {
-
- dbgf( DBGL_SYS, DBGT_WARN, "get_hna_hash() requested to remove non-existing hna registry");
- return FAILURE;
-
} else {
-
- return FAILURE;
- }
+ // paranoia( -500181, 1 );
+ if (!hn) {
+ dbgf(DBGL_SYS, DBGT_WARN, "get_hna_node() requested to remove non-existing hna registry");
+ }
+ return FAILURE;
+ }
+
+ avl_remove(&hna_avl, hn);
- hash_remove( hna_hash, hhn );
+ debugFree( hn, 1401 );
- debugFree( hhn, 1401 );
-
} else {
- if ( other_orig && !hhn ) {
+ if ( other_orig && !hn ) {
- hhn = get_hna_node( &key, YES/*create*/);
- hhn->status = HNA_HASH_NODE_OTHER;
- hhn->orig = other_orig;
+ hn = get_hna_node( &key, YES/*create*/);
+ hn->status = HNA_HASH_NODE_OTHER;
+ hn->orig = other_orig;
// we checked for err = !del && ( !router || !router->addr || !router->iif ) at beginning:
- add_del_route( ip, mask, router->addr, primary_addr,
- router->iif->if_index,
- router->iif->dev,
- rt_table, RT_UNICAST, ADD, TRACK_OTHER_HNA );
+ add_del_route( ip, mask, router->nnkey_addr, primary_addr,
+ router->nnkey_iif->if_index,
+ router->nnkey_iif->dev,
+ rt_table, RTN_UNICAST, ADD, TRACK_OTHER_HNA );
- } else if ( other_orig && hhn && hhn->status == HNA_HASH_NODE_OTHER && hhn->orig == other_orig ) {
+ } else if ( other_orig && hn && hn->status == HNA_HASH_NODE_OTHER && hn->orig == other_orig ) {
dbgf( DBGL_SYS, DBGT_WARN, "requested to add already-existing hna registry");
cleanup_all ( -500092 );
- } else if ( !other_orig && !hhn ) {
+ } else if ( !other_orig && !hn ) {
- hhn = get_hna_node( &key, YES/*create*/);
- hhn->status = HNA_HASH_NODE_MYONE;
- hhn->orig = NULL;
+ hn = get_hna_node( &key, YES/*create*/);
+ hn->status = HNA_HASH_NODE_MYONE;
+ hn->orig = NULL;
/* add throw routing entries for own hna */
- add_del_route( ip, mask, 0,0,0, "unknown", RT_TABLE_HOSTS, RT_THROW, ADD, TRACK_MY_HNA );
- add_del_route( ip, mask, 0,0,0, "unknown", RT_TABLE_INTERFACES, RT_THROW, ADD, TRACK_MY_HNA );
- add_del_route( ip, mask, 0,0,0, "unknown", RT_TABLE_NETWORKS, RT_THROW, ADD, TRACK_MY_HNA );
- add_del_route( ip, mask, 0,0,0, "unknown", RT_TABLE_TUNNEL, RT_THROW, ADD, TRACK_MY_HNA );
+ add_del_route( ip, mask, 0,0,0, "unknown", RT_TABLE_HOSTS, RTN_THROW, ADD, TRACK_MY_HNA );
+ add_del_route( ip, mask, 0,0,0, "unknown", RT_TABLE_NETWORKS, RTN_THROW, ADD, TRACK_MY_HNA );
+ add_del_route( ip, mask, 0,0,0, "unknown", RT_TABLE_TUNNEL, RTN_THROW, ADD, TRACK_MY_HNA );
my_hna_list_enabled++;
- } else if ( !other_orig && hhn && hhn->status == HNA_HASH_NODE_MYONE ) {
+ } else if ( !other_orig && hn && hn->status == HNA_HASH_NODE_MYONE ) {
dbgf( DBGL_SYS, DBGT_WARN, "requested to add already registered own hna %s/%d",
ipStr(ip), mask );
@@ -205,22 +196,19 @@
}
uint16_t array_len = 0;
-
- struct hash_it_t *hashit = NULL;
-
- /* for all hna_hash_nodes... */
- while ( (hashit = hash_iterate( hna_hash, hashit )) ) {
+
+ struct hna_key hk = {0,{0,0}};
+ while ( (hn = avl_next( &hna_avl, &hk))) {
+ hk = hn->key;
- hhn = hashit->bucket->data;
-
- if ( hhn->status == HNA_HASH_NODE_MYONE ) {
+ if ( hn->status == HNA_HASH_NODE_MYONE ) {
my_hna_ext_array[array_len].EXT_FIELD_MSG = YES;
my_hna_ext_array[array_len].EXT_FIELD_TYPE = EXT_TYPE_64B_HNA;
- my_hna_ext_array[array_len].EXT_HNA_FIELD_ADDR = hhn->key.addr;
- my_hna_ext_array[array_len].EXT_HNA_FIELD_NETMASK = hhn->key.KEY_FIELD_ANETMASK;
- my_hna_ext_array[array_len].EXT_HNA_FIELD_TYPE = hhn->key.KEY_FIELD_ATYPE;
+ my_hna_ext_array[array_len].EXT_HNA_FIELD_ADDR = hn->key.addr;
+ my_hna_ext_array[array_len].EXT_HNA_FIELD_NETMASK = hn->key.KEY_FIELD_ANETMASK;
+ my_hna_ext_array[array_len].EXT_HNA_FIELD_TYPE = hn->key.KEY_FIELD_ATYPE;
array_len++;
}
@@ -245,9 +233,9 @@
( !len && ( array || !orig_hna ) ) )
{
dbgf( DBGL_SYS, DBGT_ERR,
- "invalid hna information on %d, hal %d, ha %d, ohna_data %d ohal %d, oha %d!",
- on, len, array, orig_hna,
- orig_hna?orig_hna->hna_array_len:0, (orig_hna?orig_hna->hna_array:0) );
+ "invalid hna information on %p, hal %d, ha %p, ohna_data %p ohal %d, oha %p!",
+ (void*)on, len, (void*)array, (void*)orig_hna,
+ orig_hna?orig_hna->hna_array_len:0, (void*)(orig_hna?orig_hna->hna_array:0) );
cleanup_all( -500024 );
}
@@ -298,7 +286,7 @@
uint32_t ip;
int32_t mask;
- struct hna_hash_node *hhn;
+ struct hna_node *hhn;
struct hna_key key;
char new[30];
@@ -345,7 +333,8 @@
return FAILURE;
// 3. remove the old HNA and hope to not mess it up...
- if ( cmd == OPT_APPLY && add_del_hna( DEL, NULL, NULL, ip, mask, A_TYPE_NETWORK ) == FAILURE )
+ if ( cmd == OPT_APPLY &&
+ add_del_hna( DEL, NULL, NULL, ip, mask, A_TYPE_NETWORK ) == FAILURE )
cleanup_all( -500110 );
}
@@ -390,25 +379,26 @@
static int32_t opt_show_hnas ( uint8_t cmd, uint8_t _save, struct opt_type *opt, struct opt_parent *patch, struct ctrl_node *cn ) {
- struct hash_it_t *hashit = NULL;
-
int dbg_ogm_out = 0;
char dbg_ogm_str[MAX_DBG_STR_SIZE + 1];
uint8_t blocked;
uint16_t hna_count = 0;
struct hna_key key;
- struct hna_hash_node *hash_node;
+ struct hna_node *hn;
+ struct orig_node *orig_node;
-
if ( cmd == OPT_APPLY ) {
dbg_printf( cn, "Originator Announced networks HNAs: network/netmask or interface/IF (B:blocked)...\n");
-
- while ( (hashit = hash_iterate( orig_hash, hashit )) ) {
+
+ uint32_t orig_ip = 0;
+
+ while ((orig_node = (struct orig_node*) avl_next(&orig_avl, &orig_ip))) {
+
+ orig_ip = orig_node->orig;
+
+ struct hna_orig_data *orig_hna = orig_node->plugin_data[hna_orig_registry];
- struct orig_node *orig_node = hashit->bucket->data;
- struct hna_orig_data *orig_hna = orig_node->plugin_data[hna_orig_registry];
-
if ( !orig_node->router || !orig_hna )
continue;
@@ -424,9 +414,9 @@
key.KEY_FIELD_ATYPE = orig_hna->hna_array[hna_count].EXT_HNA_FIELD_TYPE;
// check if HNA was blocked
- hash_node = get_hna_node( &key, NO/*create*/ );
+ hn = get_hna_node( &key, NO/*create*/ );
- if ( hash_node && hash_node->status == HNA_HASH_NODE_OTHER && hash_node->orig == orig_node )
+ if ( hn && hn->status == HNA_HASH_NODE_OTHER && hn->orig == orig_node )
blocked = NO;
else
blocked = YES;
@@ -544,7 +534,7 @@
while ( hna_count < hna_array_len ) {
struct hna_key key;
- struct hna_hash_node *hash_node;
+ struct hna_node *hn;
key.addr = ((hna_array)[hna_count]).EXT_HNA_FIELD_ADDR;
key.KEY_FIELD_ANETMASK = ((hna_array)[hna_count]).EXT_HNA_FIELD_NETMASK;
@@ -555,25 +545,38 @@
key.addr != ( key.addr & htonl( 0xFFFFFFFF<<(32 - key.KEY_FIELD_ANETMASK ) ) ) )
{
- dbg_mute( 45, DBGL_SYS, DBGT_WARN,
- "drop OGM: purging originator %15s "
- "hna: %s/%i, type %d -> ignoring (invalid netmask or type)",
- orig_node->orig_str, ipStr( key.addr ), key.KEY_FIELD_ANETMASK, key.KEY_FIELD_ATYPE );
+ dbg_mute( 45, DBGL_SYS, DBGT_WARN,
+ "drop OGM: purging originator %15s "
+ "hna: %s/%i, type %d -> ignoring (invalid netmask or type)",
+ orig_node->orig_str, ipStr(key.addr),
+ key.KEY_FIELD_ANETMASK, key.KEY_FIELD_ATYPE);
return CB_OGM_REJECT;
- } else if ( (hash_node = get_hna_node( &key, NO /*create*/ )) &&
- !(hash_node->status == HNA_HASH_NODE_OTHER && hash_node->orig == orig_node) &&
- (key.KEY_FIELD_ATYPE == A_TYPE_INTERFACE || key.KEY_FIELD_ATYPE == A_TYPE_NETWORK) )
- {
+ } else if ( (hn = get_hna_node( &key, NO /*create*/ )) &&
+ !(hn->status == HNA_HASH_NODE_OTHER && hn->orig == orig_node) &&
+ (key.KEY_FIELD_ATYPE <= A_TYPE_MAX) ) {
+
+ dbg_mute(45, DBGL_SYS, DBGT_WARN,
+ "DAD-alert! ignoring %15s "
+ "hna: %s/%d type %d is blocked by %s "
+ "which may be purged in %d secs ( check --%s=%d )!",
+ orig_node->orig_str,
+ ipStr(key.addr), key.KEY_FIELD_ANETMASK, key.KEY_FIELD_ATYPE,
+ (hn->status == HNA_HASH_NODE_OTHER ? hn->orig->orig_str : "myself"),
+ (hn->status == HNA_HASH_NODE_OTHER ?
+ (int) (dad_to - (((uint32_t) (batman_time - hn->orig->last_valid_time)) / 1000)) :
+ -1),
+ ARG_PURGE_TO, dad_to);
+
+ if (hn->status == HNA_HASH_NODE_OTHER) {
+ // if HNA is blocked by other node which has ńot bean heard of for
+ // dad-timeout secs,
+ // then its' HNAs should be removed before purge-timeout expires
+ if (LSEQ_U32(dad_to, (((uint32_t) (batman_time - hn->orig->last_valid_time)) / 1000)))
+ update_other_hna(hn->orig, 0, NULL, 0);
+ }
- dbg_mute( 45, DBGL_SYS, DBGT_WARN,
- "drop OGM: purging originator %15s "
- "hna: %s/%d type %d is blocked by %s",
- orig_node->orig_str,
- ipStr( key.addr ), key.KEY_FIELD_ANETMASK, key.KEY_FIELD_ATYPE,
- ( hash_node->status == HNA_HASH_NODE_OTHER ? hash_node->orig->orig_str : "myself" ) );
-
return CB_OGM_REJECT;
} else {
@@ -637,7 +640,6 @@
set_snd_ext_hook( EXT_TYPE_64B_HNA, send_my_hna_ext, DEL );
- hash_destroy( hna_hash );
}
@@ -646,10 +648,6 @@
paranoia( -500061, ( sizeof(struct ext_type_hna) != sizeof(struct ext_packet) ) );
- if ( NULL == ( hna_hash = hash_new( 128, compare_key, choose_key, 5 ) ) )
- cleanup_all( -500066 );
-
-
register_options_array( hna_options, sizeof( hna_options ) );
if ( (hna_orig_registry = reg_plugin_data( PLUGIN_DATA_ORIG )) < 0 )
Modified: trunk/batman-experimental/hna.h
===================================================================
--- trunk/batman-experimental/hna.h 2010-04-12 19:06:37 UTC (rev 1633)
+++ trunk/batman-experimental/hna.h 2010-04-15 08:16:16 UTC (rev 1634)
@@ -27,7 +27,7 @@
// my HNA extension messages (attached to all primary OGMs)
-#define A_TYPE_INTERFACE 0x00
+#define A_TYPE_INTERFACE 0x00 //unused
#define A_TYPE_NETWORK 0x01
#define A_TYPE_MAX 0x01
@@ -90,7 +90,7 @@
#define HNA_HASH_NODE_MYONE 0x01
#define HNA_HASH_NODE_OTHER 0x02
-struct hna_hash_node
+struct hna_node
{
struct hna_key key;
Modified: trunk/batman-experimental/lib/bmx_gsf_map/Makefile
===================================================================
--- trunk/batman-experimental/lib/bmx_gsf_map/Makefile 2010-04-12 19:06:37 UTC (rev 1633)
+++ trunk/batman-experimental/lib/bmx_gsf_map/Makefile 2010-04-15 08:16:16 UTC (rev 1634)
@@ -1,38 +1,5 @@
-CFLAGS += -fpic -pedantic -Wall -W -Wno-unused-parameter -O1 -g3 -std=gnu99 -I../../
-LDFLAGS += -shared
-#-Wl,-soname,bmxd_config
+PLUGINS = $(shell find -maxdepth 1 -type d | grep -e '^./bmx_' | sort)
-PLUGIN_NAME = bmx_gsf_map
-PLUGIN_VER = 1
-
-SRC_C = gsf_map.c
-SRC_H = gsf_map.h
-OBJS= $(SRC_C:.c=.o)
-
-PLUGIN_FULLNAME = $(PLUGIN_NAME).so.$(PLUGIN_VER)
-PLUGIN_SHORTNAME = $(PLUGIN_NAME).so
-
-LIBDIR = /usr/lib
-
-all: $(PLUGIN_FULLNAME) Makefile
-
-
-$(PLUGIN_FULLNAME): $(OBJS) Makefile
- $(CC) $(LDFLAGS) $(EXTRA_LDFLAGS) $(OBJS) -o $(PLUGIN_FULLNAME)
-
-%.o: %.c %.h Makefile
- $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@
-
-
-clean:
- rm -f *.o *.so.$(PLUGIN_VER)
-
-
-install: all
- mkdir -p $(LIBDIR)
- install -D -m 755 $(PLUGIN_FULLNAME) $(LIBDIR)/$(PLUGIN_FULLNAME); /sbin/ldconfig -n $(LIBDIR); ln -f -s $(LIBDIR)/$(PLUGIN_FULLNAME) $(LIBDIR)/$(PLUGIN_SHORTNAME)
-
-
-strip: all
- strip $(PLUGIN_FULLNAME)
+%:
+ for d in $(PLUGINS); do $(MAKE) -C $$d $@ || echo compiling $$d failed; echo;echo; done
Modified: trunk/batman-experimental/lib/bmx_gsf_map/gsf_map.c
===================================================================
--- trunk/batman-experimental/lib/bmx_gsf_map/gsf_map.c 2010-04-12 19:06:37 UTC (rev 1633)
+++ trunk/batman-experimental/lib/bmx_gsf_map/gsf_map.c 2010-04-15 08:16:16 UTC (rev 1634)
@@ -34,6 +34,7 @@
#include "plugin.h"
#include "metrics.h"
//#include "schedule.h"
+//#include "avl.h"
#define GSF_MAP_MYNAME "gsf_map_name"
@@ -94,7 +95,7 @@
if ( !orig_node->router || !orig_node->primary_orig_node )
continue;
- struct orig_node *onn = get_orig_node( orig_node->router->addr, NO/*create*/ );
+ struct orig_node *onn = get_orig_node( orig_node->router->nnkey_addr, NO/*create*/ );
if ( !onn || !onn->last_valid_time || !onn->router )
continue;
@@ -116,7 +117,7 @@
"'rtq' : %3i, 'rq' : %3i, 'tq' : %3i} ",
count_neigh++,
orig_node->primary_orig_node->orig_str,
- orig_node->router->accepted_sqr.wa_val/PROBE_TO100,
+ orig_node->router->longtm_sqr.wa_val/PROBE_TO100,
orig_node->last_valid_sqn,
( batman_time - orig_node->last_valid_time)/1000,
lndev->bif->if_ip_str,
@@ -143,23 +144,25 @@
if ( cmd == OPT_APPLY && cn ) {
- struct hash_it_t *hashit = NULL;
struct orig_node *orig_node;
uint32_t count=0;
dbg_printf( cn, "\nall_nodes = {\n" " '%s' : {\n", ipStr(primary_addr) );
- while ( (hashit = hash_iterate( orig_hash, hashit )) ) {
+ uint32_t orig_ip = 0;
- orig_node = hashit->bucket->data;
+ while ((orig_node = (struct orig_node*) avl_next(&orig_avl, &orig_ip))) {
+ orig_ip = orig_node->orig;
+
+
if ( orig_node->router == NULL )
continue;
if ( orig_node->primary_orig_node != orig_node )
continue;
- struct orig_node *onn = get_orig_node( orig_node->router->addr, NO );
+ struct orig_node *onn = get_orig_node( orig_node->router->nnkey_addr, NO );
if ( !onn || !onn->last_valid_time || !onn->router || !onn->primary_orig_node )
continue;
@@ -174,15 +177,15 @@
" "
"'dev' : '%s', 'via' : '%s', 'viaPub' : '%s', 'pq' : %i, 'ut' : '%s', "
"'lseq' : %i, 'lvld' : %i, 'pwd' : %i, 'ogi' : %i, 'hop' : %i, 'chng' : %i }",
- orig_node->router->iif->dev,
- ipStr( orig_node->router->addr ),
+ orig_node->router->nnkey_iif->dev,
+ ipStr( orig_node->router->nnkey_addr ),
ipStr( onn->primary_orig_node->orig ),
- orig_node->router->accepted_sqr.wa_val/PROBE_TO100,
+ orig_node->router->longtm_sqr.wa_val/PROBE_TO100,
get_human_uptime( orig_node->first_valid_sec ),
orig_node->last_valid_sqn,
( batman_time - orig_node->last_valid_time)/1000,
orig_node->pws,
- get_wavg( orig_node->ogi_wavg, OGI_WAVG_EXP ),
+ WAVG( orig_node->ogi_wavg, OGI_WAVG_EXP ),
(Ttl+1 - orig_node->last_path_ttl),
orig_node->rt_changes
);
@@ -272,13 +275,13 @@
};
-void gsf_map_cleanup( void ) {
+static void gsf_map_cleanup( void ) {
// remove_options_array( gsf_map_options );
}
-int32_t gsf_map_init( void ) {
+static int32_t gsf_map_init( void ) {
register_options_array( gsf_map_options, sizeof( gsf_map_options ) );
Modified: trunk/batman-experimental/lib/bmx_howto_plugin/howto_plugin.c
===================================================================
--- trunk/batman-experimental/lib/bmx_howto_plugin/howto_plugin.c 2010-04-12 19:06:37 UTC (rev 1633)
+++ trunk/batman-experimental/lib/bmx_howto_plugin/howto_plugin.c 2010-04-15 08:16:16 UTC (rev 1634)
@@ -115,13 +115,13 @@
};
-void howto_plugin_cleanup( void ) {
+static void howto_plugin_cleanup( void ) {
dbgf( DBGL_CHANGES, DBGT_INFO, "cleanung up plugin %s", HOWTO_PLUGIN );
}
-int32_t howto_plugin_init( void ) {
+static int32_t howto_plugin_init( void ) {
dbgf( DBGL_CHANGES, DBGT_INFO, "init plugin %s", HOWTO_PLUGIN );
Modified: trunk/batman-experimental/lib/bmx_http_info/http_info.c
===================================================================
--- trunk/batman-experimental/lib/bmx_http_info/http_info.c 2010-04-12 19:06:37 UTC (rev 1633)
+++ trunk/batman-experimental/lib/bmx_http_info/http_info.c 2010-04-15 08:16:16 UTC (rev 1634)
@@ -70,7 +70,10 @@
struct opt_type *opt;
char *request = &(tcp_req_data[HTTP_PREAMBLE_LEN]);
-
+// dbg_printf( cn, "Content-type: text/plain\n\n" );
+ dbg_printf( cn, "\n" );
+
+
if ( wordlen( request ) <= MAX_ARG_SIZE &&
(opt = get_option(0,0,request)) &&
opt->auth_t == A_USR &&
@@ -83,7 +86,7 @@
tcp_req_len, cn->fd, opt->long_name );
check_apply_parent_option( ADD, OPT_APPLY, 0, opt, 0, cn );
-
+
} else {
dbg( DBGL_CHANGES, DBGT_INFO, "rcvd illegal %d bytes long HTTP request via fd %d",
@@ -259,13 +262,13 @@
};
-void http_info_cleanup( void ) {
+static void http_info_cleanup( void ) {
// remove_options_array( http_info_options );
}
-int32_t http_info_init( void ) {
+static int32_t http_info_init( void ) {
register_options_array( http_info_options, sizeof( http_info_options ) );
Modified: trunk/batman-experimental/lib/bmx_uci_config/HOWTO
===================================================================
--- trunk/batman-experimental/lib/bmx_uci_config/HOWTO 2010-04-12 19:06:37 UTC (rev 1633)
+++ trunk/batman-experimental/lib/bmx_uci_config/HOWTO 2010-04-15 08:16:16 UTC (rev 1634)
@@ -1,4 +1,15 @@
-_very_ short HOWTO for the bmx_uci_config.so plugin
+2009-08-10 - bmx_uci_config plugin for openWrt universial configuraton interface (UCI)
+- plugin for dynamic interaction with uci
+ ( http://downloads.openwrt.org/sources/uci-0.7.3.tar.gz )
-please check etc_config/bmx and etc_config/bmx-advanced
\ No newline at end of file
+- to compile first install uci:
+ wget http://downloads.openwrt.org/sources/uci-0.7.3.tar.gz
+ tar xzvf uci-0.7.3.tar.gz; cd uci-0.7.3; make; sudo make install
+
+- default configuration backend is: /etc/config/bmx
+
+- see lib/bmx_uci_config/etc_config for a simple (bmx)
+ and an advanced (bmx-advanced) example
+
+
Modified: trunk/batman-experimental/lib/bmx_uci_config/uci_config.c
===================================================================
--- trunk/batman-experimental/lib/bmx_uci_config/uci_config.c 2010-04-12 19:06:37 UTC (rev 1633)
+++ trunk/batman-experimental/lib/bmx_uci_config/uci_config.c 2010-04-15 08:16:16 UTC (rev 1634)
@@ -563,9 +563,6 @@
return FAILURE;
}
- // remove all (re)loaded opts from the cached list. They dont have to be resetted later on
- if ( (p_tmp=get_opt_parent_ref(&tmp_conf_opt, config_sect_val)) || (p_tmp=get_opt_parent_val(&tmp_conf_opt, config_sect_val)) )
- del_opt_parent( &tmp_conf_opt, p_tmp );
list_for_each( pos, &opt->d.childs_type_list ) {
@@ -621,6 +618,12 @@
del_opt_parent( &Patch_opt, patch );
return FAILURE;
}
+
+ // remove all (re)loaded opts from the cached list. They dont have to be resetted later on
+ if ((p_tmp = get_opt_parent_ref(&tmp_conf_opt, config_sect_val)) ||
+ (p_tmp = get_opt_parent_val(&tmp_conf_opt, patch->p_val)))
+ del_opt_parent(&tmp_conf_opt, p_tmp);
+
del_opt_parent( &Patch_opt, patch );
}
@@ -699,7 +702,7 @@
if ( wordlen(f)+1 +strlen(UCI_CONFDIR)+1 >= MAX_PATH_SIZE )
return FAILURE;
- if ( f[0] == '0' ) {
+ if ( wordsEqual( f, ARG_NO_CONFIG_FILE ) ) {
if ( cmd == OPT_APPLY )
bmx_conf_name = NULL;
@@ -829,9 +832,9 @@
dbg_printf( cn, "config '%s' '%s'\n", DEF_SECT_TYPE, DEF_SECT_NAME );
show_conf_general = YES;
- func_for_each_opt( cn, NULL, NULL, "show_conf()", show_conf );
+ func_for_each_opt( cn, NULL, "show_conf()", show_conf );
show_conf_general = NO;
- func_for_each_opt( cn, NULL, NULL, "show_conf()", show_conf );
+ func_for_each_opt( cn, NULL, "show_conf()", show_conf );
dbg_printf( cn, "\n" );
@@ -848,7 +851,8 @@
{ODI,1,0,ARG_CONFIG_FILE, 'f',A_PS1,A_ADM,A_INI,A_ARG,A_ANY, 0, 0, 0, 0, opt_conf_file,
- ARG_FILE_FORM, "use non-default config file. If defined, this must be the first given option!" },
+ ARG_FILE_FORM, "use non-default config file. If defined, this must be the first given option.\n"
+ " use --" ARG_CONFIG_FILE "=" ARG_NO_CONFIG_FILE " or -f" ARG_NO_CONFIG_FILE " to disable"},
{ODI,1,0,ARG_RELOAD_CONFIG, 0, A_PS0,A_ADM,A_DYN,A_ARG,A_ANY, 0, 0, 0, 0, opt_conf_reload,
0, "dynamically reload config file"},
Modified: trunk/batman-experimental/lib/bmx_uci_config/uci_config.h
===================================================================
--- trunk/batman-experimental/lib/bmx_uci_config/uci_config.h 2010-04-12 19:06:37 UTC (rev 1633)
+++ trunk/batman-experimental/lib/bmx_uci_config/uci_config.h 2010-04-15 08:16:16 UTC (rev 1634)
@@ -26,3 +26,4 @@
#define ARG_SHOW_CONFIG "show_config"
#define ARG_RELOAD_CONFIG "reload_config"
+#define ARG_NO_CONFIG_FILE "0"
\ No newline at end of file
Modified: trunk/batman-experimental/linux/route.c
===================================================================
--- trunk/batman-experimental/linux/route.c 2010-04-12 19:06:37 UTC (rev 1633)
+++ trunk/batman-experimental/linux/route.c 2010-04-15 08:16:16 UTC (rev 1634)
@@ -41,28 +41,56 @@
#include "schedule.h"
-int32_t base_port;
+int32_t base_port = DEF_BASE_PORT;
-int32_t Rt_table;
-int32_t Rt_prio;
+#define ARG_RT_TABLE "rt_table_offset"
+#define DEF_RT_TABLE 64
+#define MIN_RT_TABLE 0
+#define MAX_RT_TABLE 254
+#define RT_TABLE_HOSTS_OFFS 0
+#define RT_TABLE_NETS_OFFS 1
+#define RT_TABLE_TUNS_OFFS 2
+#define RT_TABLE_MAX_OFFS 2
+static int32_t Rt_table = DEF_RT_TABLE;
-static int32_t Lo_rule;
-int32_t prio_rules;
+#define ARG_RT_PRIO "prio_rules_offset"
+#define MIN_RT_PRIO 3
+#define MAX_RT_PRIO 32765
+#define DEF_RT_PRIO 6400
+#define RT_PRIO_HOSTS (Rt_prio + 0)
+#define RT_PRIO_NETWORKS (Rt_prio + 1)
+#define RT_PRIO_TUNNEL (Rt_prio + 2)
+static int32_t Rt_prio = DEF_RT_PRIO;
-static int32_t throw_rules;
-static int32_t Pedantic_cleanup;
+#define ARG_PRIO_RULES "prio_rules"
+#define ARG_THROW_RULES "throw_rules"
+#define ARG_NO_POLICY_RT "no_policy_routing"
+#define ARG_PEDANTIC_CLEANUP "pedantic_cleanup"
+#define DEF_PRIO_RULES 1
+static int32_t prio_rules = DEF_PRIO_RULES;
-static uint8_t touched_systen_config = NO;
+#define DEF_THROW_RULES 1
+static int32_t throw_rules = DEF_THROW_RULES;
+#define DEF_PEDANT_CLNUP NO
+static int32_t Pedantic_cleanup = DEF_PEDANT_CLNUP;
-static int netlink_sock = -1;
+#define DEF_LO_RULE 1
+static int32_t Lo_rule = DEF_LO_RULE;
+#define DEF_METRIC 0
+static int32_t metric = DEF_METRIC;
+static uint8_t touched_systen_config = NO;
+
+static int nl_sk = -1;
+static int flush_sk = -1;
+
static int rt_sock = 0;
@@ -79,15 +107,34 @@
int Mtu_min = MAX_MTU;
+
+static struct {
+ struct nlmsghdr nlh;
+ struct rtmsg rtm;
+ char buff[ 256 ];
+} req;
+
+static void add_rtattr( int rta_type, char *data, int data_len ) {
+
+ struct rtattr *rta = (struct rtattr *)(((char *) &req) + NLMSG_ALIGN(req.nlh.nlmsg_len));
+
+ req.nlh.nlmsg_len = NLMSG_ALIGN( req.nlh.nlmsg_len ) + RTA_LENGTH(data_len);
+
+ paranoia( -50173, (NLMSG_ALIGN( req.nlh.nlmsg_len ) > sizeof( req )) );
+ // if this fails then double req buff size !!
+
+ rta->rta_type = rta_type;
+ rta->rta_len = RTA_LENGTH(data_len);
+ memcpy( RTA_DATA(rta), data, data_len );
+}
+
static char *rt2str( uint8_t t ) {
- if ( t == RT_UNICAST )
- return "RT_UNICAST";
- else if ( t == RT_THROW )
- return "RT_THROW ";
- else if ( t == RT_UNREACH )
- return "RT_UNREACH";
+ if ( t == RTN_UNICAST )
+ return "RTN_UNICAST";
+ else if ( t == RTN_THROW )
+ return "RTN_THROW ";
- return "RT_ILLEGAL";
+ return "RTN_ILLEGAL";
}
@@ -116,53 +163,314 @@
static int open_netlink_socket( void ) {
-
- if ( ( netlink_sock = socket( PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE ) ) < 0 ) {
+ int sock = 0;
+ if ( ( sock = socket( AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE ) ) < 0 ) {
+
dbg( DBGL_SYS, DBGT_ERR, "can't create netlink socket for routing table manipulation: %s",
strerror(errno) );
- netlink_sock = 0;
+
return -1;
}
- if ( fcntl( netlink_sock, F_SETFL, O_NONBLOCK) < 0 ) {
+ if ( fcntl( sock, F_SETFL, O_NONBLOCK) < 0 ) {
dbg( DBGL_SYS, DBGT_ERR, "can't set netlink socket nonblocking : (%s)", strerror(errno));
- close(netlink_sock);
- netlink_sock = 0;
+ close(sock);
return -1;
}
- return netlink_sock;
+ return sock;
}
-static void close_netlink_socket( void ) {
+
+static int rt_macro_to_table( int rt_macro ) {
+
+ dbgf_all( DBGT_INFO, "rt_macro %d", rt_macro );
+
+ if ( rt_macro == RT_TABLE_HOSTS )
+ return Rt_table + RT_TABLE_HOSTS_OFFS;
+
+ else if ( rt_macro == RT_TABLE_NETWORKS )
+ return Rt_table + RT_TABLE_NETS_OFFS;
+
+ else if ( rt_macro == RT_TABLE_TUNNEL )
+ return Rt_table + RT_TABLE_TUNS_OFFS;
+
+ else if ( rt_macro > MAX_RT_TABLE )
+ cleanup_all( -500170 );
+
+ else if ( rt_macro >= 0 )
+ return rt_macro;
+
+ cleanup_all( -500171 );
+
+ return 0;
+
+}
+
+static int8_t track_rule_and_proceed( uint32_t network, int16_t mask, int16_t rt_table, uint32_t prio, char* iif,
+ int16_t rule_type, int8_t del, int8_t track_t)
+{
- if ( netlink_sock > 0 )
- close( netlink_sock );
+ struct list_head *list_pos, *tmp_pos, *first_found_pos=NULL, *first_found_prev=NULL;
+ struct list_head *prev_pos = (struct list_head*)&rules_list;
+ struct rules_node *first_found_rn=NULL;
+ uint32_t found_rns=0;
+
+ paranoia( -500176, ( !del && track_t == TRACK_NO ) );
+
+
+ list_for_each_safe( list_pos, tmp_pos, &rules_list ) {
- netlink_sock = 0;
+ struct rules_node *tmp_rn = list_entry( list_pos, struct rules_node, list );
+
+ if ( tmp_rn->network == network &&
+ tmp_rn->netmask == mask &&
+ tmp_rn->rt_table == rt_table &&
+ tmp_rn->prio == prio &&
+ tmp_rn->iif == iif &&
+ tmp_rn->rta_type == rule_type )
+ {
+
+ // the kernel-ip-stack does not care about my track_t when adding the same rule twice
+ // but found_rns is evaluated for this
+ if ( !first_found_rn && (tmp_rn->track_t == track_t || track_t == TRACK_NO) ) {
+ first_found_rn = tmp_rn;
+ first_found_pos = list_pos;
+ first_found_prev = prev_pos;
+ }
+
+ found_rns++;
+
+ }
+
+ prev_pos = &tmp_rn->list;
+
+ }
+
+ if ( (track_t == TRACK_NO) ||
+ ( del && !first_found_rn ) ||
+ ( del && found_rns != 1 ) ||
+ ( !del && found_rns > 0 ) )
+ {
+
+ dbg( (track_t == TRACK_NO || (del && !first_found_rn)) ? DBGL_SYS : DBGL_CHANGES,
+ (track_t == TRACK_NO || (del && !first_found_rn)) ? DBGT_ERR : DBGT_INFO,
+ " %s rule from %s/%d table %d prio %d iif %s type %d "
+ "%s exists %d tims with at least %d exact match",
+ del?"del":"add", ipStr(network), mask, rt_table, prio, iif, rule_type,
+ trackt2str(track_t), found_rns, (first_found_rn?1:0) );
+ }
+
+ if ( track_t == TRACK_NO )
+ return YES;
+
+ if ( del ) {
+
+ if ( first_found_rn ) {
+
+ list_del(first_found_prev, first_found_pos, &rules_list);
+ debugFree(first_found_rn, 1741);
+
+ if (found_rns > 1)
+ return NO;
+
+ } else {
+ return NO;
+ }
+
+ } else {
+
+ struct rules_node *tmp_rn = debugMalloc( sizeof( struct rules_node ), 741 );
+ memset( tmp_rn, 0, sizeof( struct rules_node ) );
+ INIT_LIST_HEAD( &tmp_rn->list );
+
+ tmp_rn->network = network;
+ tmp_rn->netmask = mask;
+ tmp_rn->rt_table = rt_table;
+ tmp_rn->prio = prio;
+ tmp_rn->iif = iif;
+ tmp_rn->rta_type = rule_type;
+ tmp_rn->track_t = track_t;
+
+ list_add_tail( &tmp_rn->list, &rules_list );
+
+ if ( found_rns > 0 )
+ return NO;
+
+ }
+
+ return YES;
}
+static void add_del_rule( uint32_t network, int16_t mask, int16_t rt_table_macro, uint32_t prio, char* iif,
+ int16_t rta_type, int8_t del, int8_t track_t)
+{
+
+ char buf[4096], str1[16];
+ struct sockaddr_nl nladdr;
+ struct iovec iov = { buf, sizeof(buf) };
+ struct msghdr msg;
+ struct nlmsghdr *nh;
+
+ uint16_t rt_table = rt_macro_to_table(rt_table_macro);
+
+ inet_ntop( AF_INET, &network, str1, sizeof (str1) );
+
+ if ( track_rule_and_proceed( network, mask, rt_table, prio, iif, rta_type, del, track_t ) == NO )
+ return;
+
+
+ dbg( DBGL_CHANGES, DBGT_INFO, "%s rule from %s/%d table %d prio %d iif %s type %d",
+ del?"del":"add", str1, mask, rt_table, prio, iif, rta_type );
+
+
+ memset( &nladdr, 0, sizeof(struct sockaddr_nl) );
+ memset( &req, 0, sizeof(req) );
+ memset( &msg, 0, sizeof(struct msghdr) );
+
+ nladdr.nl_family = AF_NETLINK;
+
+ req.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
+ req.nlh.nlmsg_pid = My_pid;
+
+ req.rtm.rtm_family = AF_INET;
+ req.rtm.rtm_table = rt_table;
+
+ dbgf_all( DBGT_INFO, "%s ip rule pref %d iif %s %d %s/%d lookup table %d",
+ (del?"del":"add"), prio, iif, rta_type, str1, mask, rt_table );
+
+
+ if ( del ) {
+
+ req.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
+ req.nlh.nlmsg_type = RTM_DELRULE;
+
+ req.rtm.rtm_scope = RT_SCOPE_NOWHERE;
+
+ } else {
+
+ req.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_CREATE | NLM_F_EXCL;
+ req.nlh.nlmsg_type = RTM_NEWRULE;
+
+ req.rtm.rtm_scope = RT_SCOPE_UNIVERSE;
+ req.rtm.rtm_protocol = RTPROT_STATIC;
+ req.rtm.rtm_type = RTN_UNICAST;
+
+ }
+
+
+ if (rta_type == RTA_DST) {
+
+ req.rtm.rtm_dst_len = mask;
+ add_rtattr( rta_type, (char*)&network, sizeof(network) );
+
+ } else if ( rta_type == RTA_SRC ) {
+
+ req.rtm.rtm_src_len = mask;
+ add_rtattr( rta_type, (char*)&network, sizeof(network) );
+ }
+
+
+ if ( iif )
+ add_rtattr( RTA_IIF, iif, strlen(iif)+1 );
+
+
+ if ( prio )
+ add_rtattr( RTA_PRIORITY, (char*)&prio, sizeof(prio) );
+
+
+ if ( sendto( nl_sk, &req, req.nlh.nlmsg_len, 0, (struct sockaddr *)&nladdr, sizeof(struct sockaddr_nl) ) < 0 ) {
+
+ dbg( DBGL_SYS, DBGT_ERR,
+ "can't send message to kernel via netlink socket for routing rule manipulation: %s",
+ strerror(errno) );
+ return;
+
+ }
+
+
+ while ( 1 ) {
+
+ msg.msg_name = (void *)&nladdr;
+ msg.msg_namelen = sizeof(nladdr);
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = 0;
+
+ int32_t len = recvmsg( nl_sk, &msg, 0 );
+
+
+ if ( len < 0 ) {
+
+ if ( errno == EINTR ) {
+ dbgf( DBGL_SYS, DBGT_WARN, "(EINTR) %s", strerror(errno) );
+ continue;
+ }
+
+ if ( errno == EWOULDBLOCK || errno == EAGAIN ) {
+ //dbgf( DBGL_SYS, DBGT_WARN, "(EWOULDBLOCK || EAGAIN) %s", strerror(errno) );
+ break;
+ }
+
+ dbgf( DBGL_SYS, DBGT_ERR, "%s", strerror(errno) );
+
+ continue;
+
+ }
+
+ if ( len == 0 ) {
+ dbgf( DBGL_SYS, DBGT_ERR, "netlink EOF" );
+ }
+
+ nh = (struct nlmsghdr *)buf;
+
+ while ( NLMSG_OK(nh, (uint32_t)len) ) {
+
+ if ( nh->nlmsg_type == NLMSG_DONE )
+ return;
+
+ if ( ( nh->nlmsg_type == NLMSG_ERROR ) && ( ((struct nlmsgerr*)NLMSG_DATA(nh))->error != 0 ) ) {
+
+ dbg( DBGL_SYS, DBGT_WARN, "can't %s rule %s %s/%i iif %s table %d, prio %d: %s "
+ "(if busy: Help me! Howto avoid this ERROR message?)",
+ del ? "delete" : "add",
+ ( rta_type == RTA_DST ? "to" :
+ ( rta_type == RTA_SRC ? "from" :
+ ( rta_type == RTA_IIF ? "iif" : "???") ) ),
+ str1, mask, iif, rt_table, prio,
+ strerror(-((struct nlmsgerr*)NLMSG_DATA(nh))->error) );
+ }
+
+ nh = NLMSG_NEXT( nh, len );
+
+ }
+ }
+}
+
+
static void flush_tracked_rules( int8_t track_type ) {
dbgf_all( DBGT_INFO, "%s", trackt2str(track_type) );
struct list_head *list_pos;
struct rules_node *rn, *p_rn=NULL;
+
-
list_for_each( list_pos, &rules_list ) {
rn = list_entry( list_pos, struct rules_node, list );
if ( p_rn )
add_del_rule( p_rn->network, p_rn->netmask,
- p_rn->rt_table, p_rn->prio, p_rn->iif, p_rn->rule_t, DEL, p_rn->track_t );
+ p_rn->rt_table, p_rn->prio, p_rn->iif, p_rn->rta_type, DEL, p_rn->track_t );
if ( track_type == rn->track_t || track_type == TRACK_NO )
p_rn = rn;
@@ -173,7 +481,7 @@
if ( p_rn )
add_del_rule( p_rn->network, p_rn->netmask,
- p_rn->rt_table, p_rn->prio, p_rn->iif, p_rn->rule_t, DEL, p_rn->track_t );
+ p_rn->rt_table, p_rn->prio, p_rn->iif, p_rn->rta_type, DEL, p_rn->track_t );
}
@@ -191,7 +499,7 @@
if ( p_rn )
add_del_route( p_rn->dest, p_rn->netmask, 0, 0, 0, 0,
- p_rn->rt_table, p_rn->route_t, DEL, p_rn->track_t );
+ p_rn->rt_table, p_rn->rta_type, DEL, p_rn->track_t );
if ( track_type == rn->track_t || track_type == TRACK_NO )
p_rn = rn;
@@ -202,20 +510,17 @@
if ( p_rn )
add_del_route( p_rn->dest, p_rn->netmask, 0, 0, 0, 0,
- p_rn->rt_table, p_rn->route_t, DEL, p_rn->track_t );
+ p_rn->rt_table, p_rn->rta_type, DEL, p_rn->track_t );
}
-static int flush_routes_rules( int8_t is_rule ) {
+static void flush_routes_rules( int8_t is_rule ) {
dbgf_all( DBGT_INFO, "is_rule %d", is_rule);
size_t len;
int rtl;
- int32_t dest = 0, router = 0, ifi = 0;
- uint32_t prio = 0;
- int8_t rule_type = RTA_SRC;
- char buf[8192], *dev = NULL;
+ char buf[8192];
struct sockaddr_nl nladdr;
struct iovec iov = { buf, sizeof(buf) };
struct msghdr msg;
@@ -226,144 +531,163 @@
struct rtmsg rtm;
} req;
struct rtattr *rtap;
-
+
memset( &nladdr, 0, sizeof(struct sockaddr_nl) );
memset( &req, 0, sizeof(req) );
- memset( &msg, 0, sizeof(struct msghdr) );
nladdr.nl_family = AF_NETLINK;
-
- req.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(req));
+
+ req.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
req.nlh.nlmsg_pid = My_pid;
- req.rtm.rtm_family = AF_INET;
-
req.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
req.nlh.nlmsg_type = ( is_rule ? RTM_GETRULE : RTM_GETROUTE );
+
+ req.rtm.rtm_family = AF_INET;
req.rtm.rtm_scope = RTN_UNICAST;
- if ( sendto( netlink_sock, &req, req.nlh.nlmsg_len, 0,
+ if ( sendto( flush_sk, &req, req.nlh.nlmsg_len, 0,
(struct sockaddr *)&nladdr, sizeof(struct sockaddr_nl) ) < 0 )
{
dbg( DBGL_SYS, DBGT_ERR,
"can't send message to kernel via netlink socket for flushing the routing table: %s",
strerror(errno) );
-
- return -1;
-
- }
-
- msg.msg_name = (void *)&nladdr;
- msg.msg_namelen = sizeof(nladdr);
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = NULL;
-
- len = recvmsg( netlink_sock, &msg, 0 );
- nh = (struct nlmsghdr *)buf;
-
- while ( NLMSG_OK(nh, len) ) {
-
- if ( nh->nlmsg_type == NLMSG_DONE )
- break;
-
- if ( ( nh->nlmsg_type == NLMSG_ERROR ) && ( ((struct nlmsgerr*)NLMSG_DATA(nh))->error != 0 ) ) {
-
- dbg( DBGL_SYS, DBGT_ERR, "can't flush %s: %s",
- ( is_rule ? "routing rules" : "routing table" ),
- strerror(-((struct nlmsgerr*)NLMSG_DATA(nh))->error) );
-
- return -1;
-
- }
-
- rtm = (struct rtmsg *)NLMSG_DATA(nh);
- rtap = (struct rtattr *)RTM_RTA(rtm);
- rtl = RTM_PAYLOAD(nh);
-
- nh = NLMSG_NEXT( nh, len );
-
- if ( ( rtm->rtm_table != RT_TABLE_INTERFACES ) &&
- ( rtm->rtm_table != RT_TABLE_NETWORKS ) &&
- ( rtm->rtm_table != RT_TABLE_HOSTS ) &&
- ( rtm->rtm_table != RT_TABLE_TUNNEL ) )
- continue;
-
- while ( RTA_OK(rtap, rtl) ) {
-
- switch( rtap->rta_type ) {
-
- case RTA_DST:
- dest = *((int32_t *)RTA_DATA(rtap));
- rule_type = RTA_DST;
- break;
-
- case RTA_SRC:
- dest = *((int32_t *)RTA_DATA(rtap));
- rule_type = RTA_SRC;
- break;
-
- case RTA_GATEWAY:
- router = *((int32_t *)RTA_DATA(rtap));
- break;
-
- case RTA_OIF:
- ifi = *((int32_t *)RTA_DATA(rtap));
- break;
-
- case RTA_PRIORITY:
- prio = *((uint32_t *)RTA_DATA(rtap));
- break;
-
- case RTA_IIF:
- dev = ((char *)RTA_DATA(rtap));
- rule_type = RTA_IIF;
- break;
-
- case 15: /* FIXME: RTA_TABLE is not always available - not needed but avoid warning */
- break;
-
- case RTA_PREFSRC: /* rta_type 7 - not needed but avoid warning */
- break;
-
- default:
- dbg( DBGL_SYS, DBGT_ERR, "unknown rta type: %i", rtap->rta_type );
- break;
-
- }
-
- rtap = RTA_NEXT(rtap,rtl);
-
- }
-
- char str1[16], str2[16];
-
- if ( is_rule ) {
-
- add_del_rule( ( rule_type == RTA_IIF ? 0 : dest ),
- ( rule_type == RTA_IIF ? 0 : ( rule_type == RTA_DST ? rtm->rtm_dst_len : rtm->rtm_src_len ) ),
- rtm->rtm_table, prio,
- ( rule_type == RTA_IIF ? dev : 0 ),
- rule_type, DEL, TRACK_NO );
-
- inet_ntop( AF_INET, &dest, str1, sizeof (str1) );
-
- dbg( DBGL_SYS, DBGT_WARN, "flushing orphan rule type dest? %s %d table %d prio %d",
- rule_type == RTA_IIF ? "none" : str1, rule_type, rtm->rtm_table, prio );
-
- } else {
-
- inet_ntop( AF_INET, &dest, str1, sizeof (str1) );
- inet_ntop( AF_INET, &router, str2, sizeof (str2) );
-
- add_del_route( dest, rtm->rtm_dst_len, router, 0, ifi, "unknown", rtm->rtm_table, rtm->rtm_type, DEL, TRACK_NO );
-
- dbg( DBGL_SYS, DBGT_WARN, "flushing orphan route to %s via %s type %d table %d",
- str1, str2, rtm->rtm_type, rtm->rtm_table );
- }
- }
-
- return 1;
+
+ cleanup_all( CLEANUP_FAILURE );
+ }
+
+ uint8_t nlm_f_multi = NO;
+
+ do {
+ memset(&msg, 0, sizeof(struct msghdr));
+ memset(&nladdr, 0, sizeof(struct sockaddr_nl));
+
+ nladdr.nl_family = AF_NETLINK;
+
+ msg.msg_name = (void *) & nladdr;
+ msg.msg_namelen = sizeof(nladdr);
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = NULL;
+
+ len = recvmsg(flush_sk, &msg, 0);
+ nh = (struct nlmsghdr *) buf;
+
+ dbgf_all( DBGT_INFO, "searching: %s NLMSG_OK: %d len: %d",
+ is_rule ? "rules" : "routes", NLMSG_OK(nh, len), (int)len);
+
+
+ while (NLMSG_OK(nh, len)) {
+
+ if ( nh->nlmsg_flags & NLM_F_MULTI )
+ nlm_f_multi = YES;
+
+ if (nh->nlmsg_type == NLMSG_DONE) {
+ dbgf_all( DBGT_INFO, "found NLMSG_DONE");
+ break;
+ }
+
+ if ((nh->nlmsg_type == NLMSG_ERROR) && (((struct nlmsgerr*) NLMSG_DATA(nh))->error != 0)) {
+
+ dbg(DBGL_SYS, DBGT_ERR, "can't flush %s: %s",
+ (is_rule ? "routing rules" : "routing table"),
+ strerror(-((struct nlmsgerr*) NLMSG_DATA(nh))->error));
+
+ cleanup_all( CLEANUP_FAILURE );
+ }
+
+ rtm = (struct rtmsg *) NLMSG_DATA(nh);
+ rtap = (struct rtattr *) RTM_RTA(rtm);
+ rtl = RTM_PAYLOAD(nh);
+
+ nh = NLMSG_NEXT(nh, len);
+
+ if ( /* rtm->rtm_table == 0 || */
+ rtm->rtm_table == Rt_table + RT_TABLE_NETS_OFFS ||
+ rtm->rtm_table == Rt_table + RT_TABLE_HOSTS_OFFS ||
+ rtm->rtm_table == Rt_table + RT_TABLE_TUNS_OFFS ) {
+
+ int8_t rule_type = RTA_UNSPEC;
+ uint32_t dest = 0;
+ uint32_t router = 0;
+ uint16_t mask = 0;
+ int32_t oif = 0;
+ int32_t prio = 0;
+ char *iif = NULL;
+
+ while (RTA_OK(rtap, rtl)) {
+
+ dbgf_all( DBGT_INFO, "found rtm_table %d, rta_type %d rta_len %d",
+ rtm->rtm_table, rtap->rta_type, rtap->rta_len);
+
+
+ switch (rtap->rta_type) {
+
+ case RTA_DST:
+ dest = *((int32_t *) RTA_DATA(rtap));
+ mask = rtm->rtm_dst_len;
+ rule_type = RTA_DST;
+ break;
+
+ case RTA_SRC:
+ dest = *((int32_t *) RTA_DATA(rtap));
+ mask = rtm->rtm_src_len;
+ rule_type = RTA_SRC;
+ break;
+
+ case RTA_GATEWAY:
+ router = *((int32_t *) RTA_DATA(rtap));
+ break;
+
+ case RTA_OIF:
+ oif = *((int32_t *) RTA_DATA(rtap));
+ break;
+
+ case RTA_PRIORITY:
+ prio = *((uint32_t *) RTA_DATA(rtap));
+ break;
+
+ case RTA_IIF:
+ iif = ((char *) RTA_DATA(rtap));
+ break;
+
+ case 15: // FIXME: RTA_TABLE is not always available - not needed but avoid warning
+ break;
+
+ case RTA_PREFSRC: // rta_type 7 - not needed but avoid warning
+ break;
+
+ default:
+ dbg(DBGL_SYS, DBGT_ERR, "unknown rta type: %i", rtap->rta_type);
+ break;
+
+ }
+
+ rtap = RTA_NEXT(rtap, rtl);
+
+ }
+
+
+ if (is_rule) {
+
+ add_del_rule( dest, mask, rtm->rtm_table, prio, iif, rule_type, DEL, TRACK_NO);
+
+
+ dbg(DBGL_SYS, DBGT_WARN, "flushing orphan rule type %d dest? %s/%d table %d prio %d",
+ rule_type, ipStr(dest), mask , rtm->rtm_table, prio);
+
+ } else {
+
+ add_del_route(dest, mask, router, 0, oif, "unknown", rtm->rtm_table, rtm->rtm_type, DEL, TRACK_NO);
+
+ dbg(DBGL_SYS, DBGT_WARN, "flushing orphan route to %s via %s type %d table %d",
+ ipStr(dest), ipStr(router), rtm->rtm_type, rtm->rtm_table);
+ }
+ }
+ }
+
+ } while ( !( nlm_f_multi == NO || ( ( NLMSG_OK(nh, len) && (nh->nlmsg_type == NLMSG_DONE) ) ) ) );
+
}
static void check_proc_sys( char *file, int32_t desired, int32_t *backup ) {
@@ -371,9 +695,9 @@
FILE *f;
int32_t state = 0;
char filename[MAX_PATH_SIZE];
+ int trash;
-
sprintf( filename, "/proc/sys/%s", file );
if((f = fopen(filename, "r" )) == NULL) {
@@ -386,7 +710,7 @@
return;
}
- Trash=fscanf(f, "%d", &state);
+ trash=fscanf(f, "%d", &state);
fclose(f);
if ( backup )
@@ -482,20 +806,28 @@
}
+static int8_t get_if_req( char* dev_name, struct ifreq *int_req, int siocgi_req ) {
+ memset( int_req, 0, sizeof (struct ifreq) );
+ strncpy( int_req->ifr_name, dev_name, IFNAMSIZ - 1 );
+
+ if ( ioctl( rt_sock, siocgi_req, int_req ) < 0 ) {
+
+ dbg( DBGL_SYS, DBGT_ERR, "can't get SIOCGI %d of interface %s: %s", siocgi_req, dev_name, strerror(errno) );
+ return FAILURE;
+ }
+
+ return SUCCESS;
+
+}
+
static int8_t if_validate( uint8_t set, struct batman_if *bif, char* dev_name, uint8_t reduced ) {
struct ifreq int_req;
- memset( &int_req, 0, sizeof (struct ifreq) );
- strncpy( int_req.ifr_name, dev_name, IFNAMSIZ - 1 );
-
- if ( ioctl( rt_sock, SIOCGIFADDR, &int_req ) < 0 ) {
-
- dbg( DBGL_SYS, DBGT_WARN, "can't get IP address of %s: %s", dev_name, strerror(errno) );
+ if ( get_if_req( dev_name, &int_req, SIOCGIFADDR ) == FAILURE )
goto if_validate_failure;
- }
if ( set ) {
@@ -517,12 +849,9 @@
}
- if ( ioctl( rt_sock, SIOCGIFNETMASK, &int_req ) < 0 ) {
-
- dbg( DBGL_SYS, DBGT_WARN, "can't get netmask address of %s: %s", dev_name, strerror(errno) );
+ if ( get_if_req( dev_name, &int_req, SIOCGIFNETMASK ) == FAILURE )
goto if_validate_failure;
- }
-
+
if ( set ) {
bif->if_netaddr = ( ((struct sockaddr_in *)&int_req.ifr_addr)->sin_addr.s_addr & bif->if_addr );
@@ -557,11 +886,8 @@
return SUCCESS;
- if ( ioctl( rt_sock, SIOCGIFINDEX, &int_req ) < 0 ) {
-
- dbg( DBGL_SYS, DBGT_ERR, "can't get index of interface %s: %s", dev_name, strerror(errno) );
+ if ( get_if_req( dev_name, &int_req, SIOCGIFINDEX ) == FAILURE )
goto if_validate_failure;
- }
if ( set ) {
@@ -577,12 +903,8 @@
- if ( ioctl( rt_sock, SIOCGIFBRDADDR, &int_req ) < 0 ) {
-
- dbg( DBGL_SYS, DBGT_WARN, "Can't get broadcast address of %s: %s",
- dev_name, strerror(errno) );
+ if ( get_if_req( dev_name, &int_req, SIOCGIFBRDADDR ) == FAILURE )
goto if_validate_failure;
- }
if ( set ) {
@@ -603,11 +925,8 @@
- if ( ioctl( rt_sock, SIOCGIFMTU, &int_req ) < 0 ) {
-
- dbg( DBGL_SYS, DBGT_WARN, "can't get SIOCGIFMTU from device %s: %s", dev_name, strerror(errno) );
+ if ( get_if_req( dev_name, &int_req, SIOCGIFMTU ) == FAILURE )
goto if_validate_failure;
- }
if ( set ) {
@@ -625,13 +944,19 @@
if_validate_failure:
- bif->if_addr = ((struct sockaddr_in *)&int_req.ifr_addr)->sin_addr.s_addr = 0;
+ bif->if_addr = 0;
addr_to_str( 0, bif->if_ip_str );
return FAILURE;
}
-static char *get_ifconf_buffer ( struct ifconf *ifc ) {
-
+
+
+static char *get_ip4conf_buffer ( struct ifconf *ifc ) {
+
+ /* use netlink, netdevice and rtnetlink (7)
+ * to resolve ipv6 addresses. SIOCGIFCONF will only resolv ipv4 addresses !!!
+ */
+
char *buf;
int32_t len = 10 * sizeof(struct ifreq); /* initial buffer size guess (10 interfaces) */
@@ -639,6 +964,9 @@
while ( 1 ) {
buf = debugMalloc( len, 601 );
+ memset( buf, 0, len);
+ memset( ifc, 0, sizeof( struct ifconf ));
+
ifc->ifc_len = len;
ifc->ifc_buf = buf;
@@ -707,7 +1035,7 @@
static void if_reconfigure_soft( struct batman_if *bif) {
-
+
if ( !bif->if_active ) {
dbg( DBGL_SYS, DBGT_INFO,
@@ -740,17 +1068,15 @@
if ( bif == primary_if ) {
- bif->own_ogm_out->ogm_ttl = Ttl;
+ bif->if_ttl = Ttl;
bif->if_singlehomed = NO;
} else {
- bif->own_ogm_out->ogm_ttl = 1;
+ bif->if_ttl = 1;
bif->if_singlehomed = YES;
}
- bif->own_ogm_out->ogm_pws = my_pws;
- //bif->own_ogm_out->ogm_path_lounge = Signal_lounge;
bif->if_ant_diversity = 1;
@@ -761,10 +1087,13 @@
bif->if_ant_diversity = bif->if_ant_diversity_conf;
if ( bif->if_ttl_conf != -1 )
- bif->own_ogm_out->ogm_ttl = bif->if_ttl_conf;
+ bif->if_ttl = bif->if_ttl_conf;
if ( bif->if_singlehomed_conf != -1 )
bif->if_singlehomed = bif->if_singlehomed_conf;
+
+ bif->if_last_link_activity = batman_time;
+ bif->if_next_pwrsave_hardbeat = batman_time;
bif->if_conf_soft_changed = NO;
@@ -784,8 +1113,7 @@
static void if_activate( struct batman_if *bif ) {
-
-
+
if ( if_validate( YES/*set*/, bif, bif->dev, NO/*reduced check*/ ) == FAILURE )
goto error;
@@ -937,7 +1265,6 @@
check_kernel_config( bif );
- bif->own_ogm_out->orig = bif->if_addr;
if ( bif == primary_if ) {
@@ -977,170 +1304,153 @@
}
+static int8_t track_route_and_proceed( uint32_t dest, int16_t mask, uint32_t gw, uint32_t src, int32_t ifi, char *dev,
+ int16_t rt_table, int16_t rta_type, int8_t del, int8_t track_t )
+{
-
-void add_del_route( uint32_t dest, uint8_t netmask, uint32_t router, uint32_t source, int32_t ifi, char *dev,
- uint8_t rt_table, int8_t route_type, int8_t del, int8_t track_t )
-{
-
- uint32_t my_router;
- char buf[4096], dsts[16], vias[16], srcs[16];
- struct rtattr *rta;
- struct sockaddr_nl nladdr;
- struct iovec iov = { buf, sizeof(buf) };
- struct msghdr msg;
- struct nlmsghdr *nh;
- struct {
- struct nlmsghdr nlh;
- struct rtmsg rtm;
- char buff[4 * ( sizeof(struct rtattr) + 4 )];
- } req;
-
- if ( !rt_table ) {
- dbgf( DBGL_SYS, DBGT_ERR, "NO rt_table %s", ILLEGAL_STATE );
- return;
- }
-
-
- if ( !del && track_t == TRACK_NO ) {
- dbgf( DBGL_SYS, DBGT_ERR, "ADD and TRACK_NO %s", ILLEGAL_STATE );
- return;
- }
-
- dest = dest & htonl( 0xFFFFFFFF<<(32 - netmask ) ); // ToBeDone in add_del_route()...
-
- if ( ( !throw_rules ) && ( route_type == RT_THROW ) )
- return;
-
- inet_ntop( AF_INET, &dest, dsts, sizeof (dsts) );
- inet_ntop( AF_INET, &router, vias, sizeof (vias) );
- inet_ntop( AF_INET, &source, srcs, sizeof (srcs) );
-
-
- struct list_head *list_pos, *tmp_pos, *prev_pos = (struct list_head*)&routes_list;
+ struct list_head *list_pos, *tmp_pos, *prev_pos = (struct list_head*)&routes_list;
struct list_head *first_found_pos=NULL, *first_found_prev=NULL;
struct routes_node *first_found_rn=NULL;
uint32_t found_rns=0;
-
+
+ paranoia(-500177, (!del && track_t == TRACK_NO));
+
list_for_each_safe( list_pos, tmp_pos, &routes_list ) {
-
+
struct routes_node *tmp_rn = list_entry( list_pos, struct routes_node, list );
-
- if ( tmp_rn->dest == dest &&
- tmp_rn->netmask == netmask &&
+
+ if ( tmp_rn->dest == dest &&
+ tmp_rn->netmask == mask &&
tmp_rn->rt_table == rt_table &&
- tmp_rn->route_t == route_type )
+ tmp_rn->rta_type == rta_type )
{
-
- // the kernel-ip-stack does not care about my track_t when adding the same route twice
+
+ // the kernel-ip-stack does not care about my track_t when adding the same route twice
// but found_rns is evaluated for this
if ( !first_found_rn && (tmp_rn->track_t == track_t || track_t == TRACK_NO ) ) {
-
+
first_found_rn = tmp_rn;
first_found_pos = list_pos;
first_found_prev = prev_pos;
}
-
+
found_rns++;
-
+
}
-
+
prev_pos = &tmp_rn->list;
-
+
}
-
+
if ( track_t == TRACK_NO ||
( del && !first_found_rn ) ||
( del && found_rns != 1 ) ||
- ( !del && found_rns > 0 ) )
+ ( !del && found_rns > 0 ) )
{
- dbg( (track_t == TRACK_NO || (del && !first_found_rn)) ? DBGL_SYS : DBGL_ALL,
- (track_t == TRACK_NO || (del && !first_found_rn)) ? DBGT_ERR : DBGT_INFO,
+ dbg( (track_t == TRACK_NO || (del && !first_found_rn)) ? DBGL_SYS : DBGL_ALL,
+ (track_t == TRACK_NO || (del && !first_found_rn)) ? DBGT_ERR : DBGT_INFO,
" %s route to %-15s via %-15s src %s dev %s table %d %s "
- "%s has %d (%d exact) matches",
- del?"del":"add", dsts, vias, srcs, dev, rt_table,
- rt2str(route_type), trackt2str(track_t), found_rns, (first_found_rn?1:0) );
- }
-
-
+ "%s has %d (%d exact) matches",
+ del?"del":"add", ipStr(dest), ipStr(gw), ipStr(src), dev, rt_table,
+ rt2str(rta_type), trackt2str(track_t), found_rns, (first_found_rn?1:0) );
+ }
+
+ if ( track_t == TRACK_NO )
+ return YES;
+
+
if ( del && !first_found_rn) {
-
+
dbgf_all( DBGT_WARN, "removing orphan route");
- // continue to remove, maybe an orphan route
-
+ return NO;
+
} else if ( del && first_found_rn ) {
-
+
list_del( first_found_prev, first_found_pos, &routes_list );
debugFree( first_found_rn, 1742 );
-
+
if ( found_rns > 1 )
- return;
-
-
+ return NO;
+
+
} else if ( !del ) {
-
+
struct routes_node *tmp_rn = debugMalloc( sizeof( struct routes_node ), 742 );
memset( tmp_rn, 0, sizeof( struct routes_node ) );
INIT_LIST_HEAD( &tmp_rn->list );
-
+
tmp_rn->dest = dest;
- tmp_rn->netmask = netmask;
+ tmp_rn->netmask = mask;
tmp_rn->rt_table = rt_table;
- tmp_rn->route_t = route_type;
+ tmp_rn->rta_type = rta_type;
tmp_rn->track_t = track_t;
-
+
list_add_tail( &tmp_rn->list, &routes_list );
-
+
if ( found_rns > 0 )
- return;
-
+ return NO;
+
}
+
+ return YES;
+}
+
+
+
+void add_del_route( uint32_t dest, int16_t mask, uint32_t gw, uint32_t src, int32_t ifi, char *dev,
+ int16_t rt_table_macro, int16_t rta_type, int8_t del, int8_t track_t )
+{
+ uint32_t my_router;
+ char buf[4096];
+ struct sockaddr_nl nladdr;
+ struct iovec iov = { buf, sizeof(buf) };
+ struct msghdr msg;
+ struct nlmsghdr *nh;
+ uint16_t rt_table = rt_macro_to_table(rt_table_macro);
+
+ dest = dest & htonl( 0xFFFFFFFF<<(32 - mask ) );
+
+ if ( ( !throw_rules ) && ( rta_type == RTN_THROW ) )
+ return;
+
+
+
+ if ( track_route_and_proceed(dest, mask, gw, src, ifi, dev, rt_table, rta_type, del, track_t) == NO )
+ return;
+
if ( track_t != TRACK_OTHER_HOST )
dbg( DBGL_CHANGES, DBGT_INFO,
" %s route to %15s/%-2d table %d via %-15s dev %-10s ifi %2d %s %s",
- del?"del":"add", dsts, netmask, rt_table, vias, dev, ifi, rt2str(route_type), trackt2str(track_t) );
-
-
-
- if ( router == dest ) {
-
+ del?"del":"add",
+ ipStr(dest), mask, rt_table, ipStr(gw), dev, ifi, rt2str(rta_type), trackt2str(track_t));
+
+
+ if ( gw == dest )
my_router = 0;
-
- if ( dest == 0 ) {
-
- dbgf_all( DBGT_INFO, "%s default route via %s src %s (table %i)",
- del ? "del" : "add", dev, srcs, rt_table );
-
- } else {
-
- dbgf_all( DBGT_INFO, "%s route to %s via %s (table %i - %s src %s )",
- del ? "del" : "add", dsts, vias, rt_table, dev, srcs );
-
- }
-
- } else {
-
- my_router = router;
-
- dbgf_all( DBGT_INFO, "%s %s to %s/%i via %s (table %i - %s src %s )",
- del ? "del" : "add", rt2str(route_type), dsts, netmask, vias, rt_table, dev, srcs );
-
-
- }
+
+ else
+ my_router = gw;
+
+
+ dbgf_all( DBGT_INFO, "%s %s to %s/%i via %s (table %i - %s src %s )",
+ del ? "del" : "add",
+ rt2str(rta_type), ipStr(dest), mask, ipStr(gw), rt_table, dev, ipStr(src));
+
-
memset( &nladdr, 0, sizeof(struct sockaddr_nl) );
memset( &req, 0, sizeof(req) );
memset( &msg, 0, sizeof(struct msghdr) );
nladdr.nl_family = AF_NETLINK;
-
+
+ req.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
req.nlh.nlmsg_pid = My_pid;
- req.rtm.rtm_family = AF_INET;
+
+ req.rtm.rtm_family = AF_INET;
req.rtm.rtm_table = rt_table;
- req.rtm.rtm_dst_len = netmask;
+ req.rtm.rtm_dst_len = mask;
if ( del ) {
@@ -1150,63 +1460,41 @@
} else {
- req.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_CREATE | NLM_F_EXCL;
+ req.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_CREATE | NLM_F_EXCL/* | NLM_F_REPLACE*/;
req.nlh.nlmsg_type = RTM_NEWROUTE;
- if ( /* source != 0 && */ route_type == RT_UNICAST && my_router == 0 ) {
+ if ( /* source != 0 && */ rta_type == RTN_UNICAST && my_router == 0 ) {
req.rtm.rtm_scope = RT_SCOPE_LINK;
} else {
req.rtm.rtm_scope = RT_SCOPE_UNIVERSE;
}
req.rtm.rtm_protocol = RTPROT_STATIC; // may be changed to some batman specific value - see <linux/rtnetlink.h>
- req.rtm.rtm_type = ( route_type == RT_THROW ? RTN_THROW : RTN_UNICAST );
+ req.rtm.rtm_type = ( rta_type == RTN_THROW ? RTN_THROW : RTN_UNICAST );
}
-
- int i=0;
-
- rta = (struct rtattr *)(req.buff + (i * sizeof(struct rtattr)) + (i*4));
- rta->rta_type = RTA_DST;
- rta->rta_len = sizeof(struct rtattr) + 4;
- memcpy( ((char *)&req.buff) + ((i+1) * sizeof(struct rtattr)) + (i*4), (char *)&dest, 4 );
- i++;
-
- if ( route_type == RT_UNICAST ) {
+
+ add_rtattr( RTA_DST, (char*)&dest, sizeof(dest) );
+
+ if ( rta_type == RTN_UNICAST ) {
- if ( my_router != 0 ) {
- rta = (struct rtattr *)(req.buff + (i * sizeof(struct rtattr)) + (i*4));
- rta->rta_type = RTA_GATEWAY;
- rta->rta_len = sizeof(struct rtattr) + 4;
- memcpy( ((char *)&req.buff) + ((i+1) * sizeof(struct rtattr)) + (i*4), (char *)&my_router, 4 );
- i++;
- }
+ if ( my_router )
+ add_rtattr( RTA_GATEWAY, (char*)&my_router, sizeof(my_router) );
- if ( ifi != 0 ) {
- rta = (struct rtattr *)(req.buff + (i * sizeof(struct rtattr)) + (i*4));
- rta->rta_type = RTA_OIF;
- rta->rta_len = sizeof(struct rtattr) + 4;
- memcpy( ((char *)&req.buff) + ((i+1) * sizeof(struct rtattr)) + (i*4), (char *)&ifi, 4 );
- i++;
- }
-
- if( source != 0 /* && my_router == 0 */ ) {
- rta = (struct rtattr *)(req.buff + (i * sizeof(struct rtattr)) + (i*4));
- rta->rta_type = RTA_PREFSRC;
- rta->rta_len = sizeof(struct rtattr) + 4;
- memcpy( ((char *)&req.buff) + ((i+1) * sizeof(struct rtattr)) + (i*4), (char *)&source, 4 );
- i++;
-
-
- }
- }
+ if ( ifi )
+ add_rtattr ( RTA_OIF, (char*)&ifi, sizeof(ifi) );
+
+ if ( src /* && my_router == 0 */)
+ add_rtattr( RTA_PREFSRC, (char*)&src, sizeof(src) );
+
+ if ( metric )
+ add_rtattr( RTA_PRIORITY, (char*)&metric, sizeof(metric) );
+
+ }
-
- req.nlh.nlmsg_len = NLMSG_LENGTH( sizeof(struct rtmsg) + (i * (sizeof(struct rtattr) + 4)) );
-
errno=0;
- if ( sendto( netlink_sock, &req, req.nlh.nlmsg_len, 0, (struct sockaddr *)&nladdr, sizeof(struct sockaddr_nl) ) < 0 ) {
+ if ( sendto( nl_sk, &req, req.nlh.nlmsg_len, 0, (struct sockaddr *)&nladdr, sizeof(struct sockaddr_nl) ) < 0 ) {
dbg( DBGL_SYS, DBGT_ERR,
"can't send message to kernel via netlink socket for routing table manipulation: %s",
@@ -1228,7 +1516,7 @@
msg.msg_flags = 0;
errno=0;
- int32_t len = recvmsg( netlink_sock, &msg, 0 );
+ int32_t len = recvmsg( nl_sk, &msg, 0 );
if ( len < 0 ) {
@@ -1265,7 +1553,7 @@
if ( ( nh->nlmsg_type == NLMSG_ERROR ) && ( ((struct nlmsgerr*)NLMSG_DATA(nh))->error != 0 ) )
{
dbg( DBGL_CHANGES, DBGT_WARN, "can't %s %s to %s/%i via %s (table %i): %s",
- del ? "delete" : "add", rt2str(route_type), dsts, netmask, vias, rt_table,
+ del ? "delete" : "add", rt2str(rta_type), ipStr(dest), mask, ipStr(gw), rt_table,
strerror(-((struct nlmsgerr*)NLMSG_DATA(nh))->error) );
}
@@ -1278,281 +1566,6 @@
-void add_del_rule( uint32_t network, uint8_t netmask, uint8_t rt_table, uint32_t prio, char *iif, int8_t rule_type, int8_t del, int8_t track_t ) {
-
- int32_t len;
- char buf[4096], str1[16];
- struct rtattr *rta;
- struct sockaddr_nl nladdr;
- struct iovec iov = { buf, sizeof(buf) };
- struct msghdr msg;
- struct nlmsghdr *nh;
- struct {
- struct nlmsghdr nlh;
- struct rtmsg rtm;
- char buff[2 * ( sizeof(struct rtattr) + 4 )];
- } req;
-
- if ( !rt_table ) {
- dbgf( DBGL_SYS, DBGT_ERR, "NO rt_table %s", ILLEGAL_STATE );
- return;
- }
-
-
- if ( !del && track_t == TRACK_NO ) {
- dbgf( DBGL_SYS, DBGT_ERR, "ADD and TRACK_NO %s", ILLEGAL_STATE );
- return;
- }
-
- inet_ntop( AF_INET, &network, str1, sizeof (str1) );
-
-
- struct list_head *list_pos, *tmp_pos, *first_found_pos=NULL, *first_found_prev=NULL;
- struct list_head *prev_pos = (struct list_head*)&rules_list;
- struct rules_node *first_found_rn=NULL;
- uint32_t found_rns=0;
-
-
- list_for_each_safe( list_pos, tmp_pos, &rules_list ) {
-
- struct rules_node *tmp_rn = list_entry( list_pos, struct rules_node, list );
-
- if ( tmp_rn->network == network &&
- tmp_rn->netmask == netmask &&
- tmp_rn->rt_table == rt_table &&
- tmp_rn->prio == prio &&
- tmp_rn->iif == iif &&
- tmp_rn->rule_t == rule_type )
- {
-
- // the kernel-ip-stack does not care about my track_t when adding the same rule twice
- // but found_rns is evaluated for this
- if ( !first_found_rn && (tmp_rn->track_t == track_t || track_t == TRACK_NO) ) {
- first_found_rn = tmp_rn;
- first_found_pos = list_pos;
- first_found_prev = prev_pos;
- }
-
- found_rns++;
-
- }
-
- prev_pos = &tmp_rn->list;
-
- }
-
- if ( (track_t == TRACK_NO) ||
- ( del && !first_found_rn ) ||
- ( del && found_rns != 1 ) ||
- ( !del && found_rns > 0 ) )
- {
-
- dbg( (track_t == TRACK_NO || (del && !first_found_rn)) ? DBGL_SYS : DBGL_CHANGES,
- (track_t == TRACK_NO || (del && !first_found_rn)) ? DBGT_ERR : DBGT_INFO,
- " %s rule from %s/%d table %d prio %d if %s type %d "
- "%s exists %d tims with at least %d exact match",
- del?"del":"add", str1, netmask, rt_table, prio, iif, rule_type,
- trackt2str(track_t), found_rns, (first_found_rn?1:0) );
- }
-
- if ( del && !first_found_rn) {
- return;
-
- } else if ( del && first_found_rn ) {
-
- list_del( first_found_prev, first_found_pos, &rules_list );
- debugFree( first_found_rn, 1741 );
-
- if ( found_rns > 1 )
- return;
-
- } else if ( !del ) {
-
- struct rules_node *tmp_rn = debugMalloc( sizeof( struct rules_node ), 741 );
- memset( tmp_rn, 0, sizeof( struct rules_node ) );
- INIT_LIST_HEAD( &tmp_rn->list );
-
- tmp_rn->network = network;
- tmp_rn->netmask = netmask;
- tmp_rn->rt_table = rt_table;
- tmp_rn->prio = prio;
- tmp_rn->iif = iif;
- tmp_rn->rule_t = rule_type;
- tmp_rn->track_t = track_t;
-
- list_add_tail( &tmp_rn->list, &rules_list );
-
- if ( found_rns > 0 )
- return;
-
- }
-
- dbg( DBGL_CHANGES, DBGT_INFO, "%s rule from %s/%d table %d prio %d if %s type %d",
- del?"del":"add", str1, netmask, rt_table, prio, iif, rule_type );
-
-
-
- memset( &nladdr, 0, sizeof(struct sockaddr_nl) );
- memset( &req, 0, sizeof(req) );
- memset( &msg, 0, sizeof(struct msghdr) );
-
- nladdr.nl_family = AF_NETLINK;
-
- len = sizeof(struct rtmsg) + sizeof(struct rtattr) + 4;
-
- if ( prio != 0 )
- len += sizeof(struct rtattr) + 4;
-
- req.nlh.nlmsg_len = NLMSG_LENGTH(len);
- req.nlh.nlmsg_pid = My_pid;
- req.rtm.rtm_family = AF_INET;
- req.rtm.rtm_table = rt_table;
-
- dbgf_all( DBGT_INFO, "%s ip rule pref %d %s %s/%d lookup table %d",
- (del ? "Deleting" : "Adding"),
- prio,
- (rule_type == RTA_SRC ? "from" : (rule_type == RTA_DST ? "to" : "dev" ) ),
- ((rule_type == RTA_SRC || rule_type == RTA_DST) ? str1: ( rule_type == RTA_IIF ? iif : "??" )),
- netmask,
- rt_table );
-
-
- if ( del ) {
-
- req.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
- req.nlh.nlmsg_type = RTM_DELRULE;
- req.rtm.rtm_scope = RT_SCOPE_NOWHERE;
-
- } else {
-
- req.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_CREATE | NLM_F_EXCL;
- req.nlh.nlmsg_type = RTM_NEWRULE;
- req.rtm.rtm_scope = RT_SCOPE_UNIVERSE;
- req.rtm.rtm_protocol = RTPROT_STATIC;
- req.rtm.rtm_type = RTN_UNICAST;
-
- }
-
-
- if ( rule_type == RTA_IIF ) {
-
- if ( del ) {
-
- rta = (struct rtattr *)req.buff;
- rta->rta_type = RTA_SRC;
- rta->rta_len = sizeof(struct rtattr) + 4;
- memcpy( ((char *)&req.buff) + sizeof(struct rtattr), (char *)&network, 4 );
-
- } else {
-
- rta = (struct rtattr *)req.buff;
- rta->rta_type = RTA_IIF;
- rta->rta_len = sizeof(struct rtattr) + 4;
- memcpy( ((char *)&req.buff) + sizeof(struct rtattr), iif, 4 );
-
- }
-
- } else {
-
- rta = (struct rtattr *)req.buff;
-
- if ( rule_type == RTA_DST ) {
-
- req.rtm.rtm_dst_len = netmask;
-
- rta->rta_type = RTA_DST;
-
- } else {
-
- req.rtm.rtm_src_len = netmask;
-
- rta->rta_type = RTA_SRC;
-
- }
-
- rta->rta_len = sizeof(struct rtattr) + 4;
- memcpy( ((char *)&req.buff) + sizeof(struct rtattr), (char *)&network, 4 );
-
- }
-
-
- if ( prio != 0 ) {
-
- rta = (struct rtattr *)(req.buff + sizeof(struct rtattr) + 4);
- rta->rta_type = RTA_PRIORITY;
- rta->rta_len = sizeof(struct rtattr) + 4;
- memcpy( ((char *)&req.buff) + 2 * sizeof(struct rtattr) + 4, (char *)&prio, 4 );
-
- }
-
-
- if ( sendto( netlink_sock, &req, req.nlh.nlmsg_len, 0, (struct sockaddr *)&nladdr, sizeof(struct sockaddr_nl) ) < 0 ) {
-
- dbg( DBGL_SYS, DBGT_ERR,
- "can't send message to kernel via netlink socket for routing rule manipulation: %s",
- strerror(errno) );
- return;
-
- }
-
-
- while ( 1 ) {
-
- msg.msg_name = (void *)&nladdr;
- msg.msg_namelen = sizeof(nladdr);
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_control = NULL;
- msg.msg_controllen = 0;
- msg.msg_flags = 0;
-
- len = recvmsg( netlink_sock, &msg, 0 );
-
-
- if ( len < 0 ) {
-
- if ( errno == EINTR ) {
- dbgf( DBGL_SYS, DBGT_WARN, "(EINTR) %s", strerror(errno) );
- continue;
- }
-
- if ( errno == EWOULDBLOCK || errno == EAGAIN ) {
- //dbgf( DBGL_SYS, DBGT_WARN, "(EWOULDBLOCK || EAGAIN) %s", strerror(errno) );
- break;
- }
-
- dbgf( DBGL_SYS, DBGT_ERR, "%s", strerror(errno) );
-
- continue;
-
- }
-
- if ( len == 0 ) {
- dbgf( DBGL_SYS, DBGT_ERR, "netlink EOF" );
- }
-
- nh = (struct nlmsghdr *)buf;
-
- while ( NLMSG_OK(nh, (uint32_t)len) ) {
-
- if ( nh->nlmsg_type == NLMSG_DONE )
- return;
-
- if ( ( nh->nlmsg_type == NLMSG_ERROR ) && ( ((struct nlmsgerr*)NLMSG_DATA(nh))->error != 0 ) ) {
-
- dbg( DBGL_SYS, DBGT_WARN, "can't %s rule %s %s/%i table %d, prio %d: %s "
- "(if busy: Help me! Howto avoid this ERROR message?)",
- del ? "delete" : "add",
- ( rule_type == RTA_DST ? "to" : "from" ),
- str1, netmask, rt_table, prio,
- strerror(-((struct nlmsgerr*)NLMSG_DATA(nh))->error) );
- }
-
- nh = NLMSG_NEXT( nh, len );
-
- }
- }
-}
int update_interface_rules( uint8_t cmd ) {
@@ -1560,9 +1573,10 @@
static uint8_t setup_tunnel = NO;
static uint8_t setup_networks = NO;
- static uint32_t checksum = 0;
+
+ static uint64_t checksum = 0;
- uint32_t old_checksum = checksum;
+ uint64_t old_checksum = checksum;
checksum = 0;
uint8_t if_count = 1;
@@ -1605,19 +1619,18 @@
}
- if ( !(buf = get_ifconf_buffer( &ifc )) )
+ if ( !(buf = get_ip4conf_buffer( &ifc )) )
return FAILURE;
for ( buf_ptr = buf; buf_ptr < buf + ifc.ifc_len; ) {
struct batman_if bif;
+// memset( &bif, 0, sizeof(struct batman_if));
ifr = (struct ifreq *)buf_ptr;
- buf_ptr += sizeof(ifr->ifr_name) +
- ( ifr->ifr_addr.sa_family == AF_INET6 ?
- sizeof(struct sockaddr_in6) :
- sizeof(struct sockaddr) );
+ buf_ptr += sizeof(struct ifreq);
+
/* ignore if not IPv4 interface */
if ( ifr->ifr_addr.sa_family != AF_INET )
continue;
@@ -1627,15 +1640,27 @@
if ( if_validate( YES/*set*/, &bif, ifr->ifr_name, YES/*reduced check only*/ ) == FAILURE )
continue;
+
+ size_t i;
+ struct key {
+ uint32_t if_prefix_length;
+ uint32_t if_netaddr;
+ uint32_t if_addr;
+ } key = { bif.if_prefix_length, /*bif.if_index,*/ bif.if_netaddr, bif.if_addr };
+
+ for (i = 0; i < sizeof( struct key); i++) {
+ checksum += ((unsigned char*)(&key))[i];
+ checksum += (checksum << 10);
+ checksum ^= (checksum >> 6);
+ }
+
+ dbgf_ext( DBGT_INFO, "%15ju %15ju %10s %15s %15s %2d ",
+ old_checksum, checksum,
+// ((uint32_t*)&(old_checksum))[0], ((uint32_t*)&(old_checksum))[1],
+// ((uint32_t*)&(checksum))[0], ((uint32_t*)&(checksum))[1],
+ ifr->ifr_name, ipStr(bif.if_addr), ipStr(bif.if_netaddr), bif.if_prefix_length);
- checksum += bif.if_addr + bif.if_netaddr + bif.if_prefix_length;
-
- dbgf_all( DBGT_INFO, "%15d %10s %15s %15s %2d",
- checksum, ifr->ifr_name,
- ipStr(bif.if_addr), ipStr(bif.if_netaddr), bif.if_prefix_length );
-
-
if ( cmd == IF_RULE_CHK_IPS )
continue;
@@ -1667,15 +1692,16 @@
if_count++;
}
- if ( Lo_rule && strncmp( ifr->ifr_name, "lo", IFNAMSIZ - 1 ) == 0 )
- add_del_rule( 0, 0,
- RT_TABLE_TUNNEL, RT_PRIO_TUNNEL, "lo", RTA_IIF, ADD, TRACK_MY_NET );
+ if ( Lo_rule && strncmp( ifr->ifr_name, "lo", IFNAMSIZ - 1 ) == 0 ) {
+ add_del_rule( 0, 0, RT_TABLE_TUNNEL, RT_PRIO_TUNNEL, "lo", RTA_IIF, ADD, TRACK_MY_NET );
+ }
+
}
if( throw_rules && setup_tunnel == YES )
add_del_route( bif.if_netaddr, bif.if_prefix_length,
- 0, 0, 0, ifr->ifr_name, RT_TABLE_TUNNEL, RT_THROW, ADD, TRACK_MY_NET );
+ 0, 0, 0, ifr->ifr_name, RT_TABLE_TUNNEL, RTN_THROW, ADD, TRACK_MY_NET );
if ( is_batman_if( ifr->ifr_name, &batman_if ) )
@@ -1684,7 +1710,7 @@
if( throw_rules && setup_networks == YES )
add_del_route( bif.if_netaddr, bif.if_prefix_length,
- 0, 0, 0, ifr->ifr_name, RT_TABLE_NETWORKS, RT_THROW, ADD, TRACK_MY_NET );
+ 0, 0, 0, ifr->ifr_name, RT_TABLE_NETWORKS, RTN_THROW, ADD, TRACK_MY_NET );
}
@@ -1700,20 +1726,18 @@
throw_node = list_entry(throw_pos, struct throw_node, list);
add_del_route( throw_node->addr, throw_node->netmask,
- 0, 0, 0, "unknown", RT_TABLE_HOSTS, RT_THROW, ADD, TRACK_MY_NET );
+ 0, 0, 0, "unknown", RT_TABLE_HOSTS, RTN_THROW, ADD, TRACK_MY_NET );
add_del_route( throw_node->addr, throw_node->netmask,
- 0, 0, 0, "unknown", RT_TABLE_INTERFACES, RT_THROW, ADD, TRACK_MY_NET );
+ 0, 0, 0, "unknown", RT_TABLE_NETWORKS, RTN_THROW, ADD, TRACK_MY_NET );
add_del_route( throw_node->addr, throw_node->netmask,
- 0, 0, 0, "unknown", RT_TABLE_NETWORKS, RT_THROW, ADD, TRACK_MY_NET );
- add_del_route( throw_node->addr, throw_node->netmask,
- 0, 0, 0, "unknown", RT_TABLE_TUNNEL, RT_THROW, ADD, TRACK_MY_NET );
+ 0, 0, 0, "unknown", RT_TABLE_TUNNEL, RTN_THROW, ADD, TRACK_MY_NET );
}
}
- if ( cmd == IF_RULE_CHK_IPS && (checksum-old_checksum) ) {
+ if ( cmd == IF_RULE_CHK_IPS && (checksum != old_checksum) ) {
dbg( DBGL_CHANGES, DBGT_INFO,
"systems' IP configuration changed! Going to re-init interface rules...");
update_interface_rules( IF_RULE_UPD_ALL );
@@ -1858,6 +1882,9 @@
}
}
+
+ if (if_conf_soft_changed )
+ bif->if_conf_soft_changed = YES; // to be considered in if_activate()->if_reconfigure_soft()
if ( (!bif->if_active) && (is_interface_up(bif->dev)) ) {
@@ -1886,7 +1913,7 @@
}
}
- if ( /*bif->if_active &&*/ (if_conf_soft_changed || bif->if_conf_soft_changed) ) {
+ if ( /*bif->if_active &&*/ ( /*if_conf_soft_changed ||*/ bif->if_conf_soft_changed) ) {
if ( on_the_fly )
dbg( DBGL_CHANGES, DBGT_INFO, "%s soft interface configuration changed", bif->dev );
@@ -1965,38 +1992,28 @@
check_apply_parent_option( ADD, OPT_APPLY, _save, get_option( 0, 0, ARG_THROW_RULES ), "0", cn );
} else if ( cmd == OPT_SET_POST && !on_the_fly ) {
-
- // flush orphan routes must be before flushing rules, otherwise orphan routes are not found !
- if ( flush_routes_rules(0 /* flush routes */) < 0 )
- cleanup_all( CLEANUP_FAILURE );
-
-
+
+ // flush orphan routes must be before flushing rules, otherwise orphan routes are not found !
+ flush_routes_rules( 0 /* flush routes */);
+
/* add rule for hosts and announced interfaces and networks */
- if ( prio_rules ) {
+ if ( prio_rules )
+ flush_routes_rules( 1 /* flush rules */);
+
+
+ } else if ( cmd == OPT_POST && !on_the_fly ) {
- if ( flush_routes_rules(1 /* flush rules */) < 0 )
- cleanup_all( CLEANUP_FAILURE );
-
- }
-
- }
- /*
- else if ( cmd == OPT_POST && !on_the_fly ) {
-
// add rule for hosts and announced interfaces and networks
if ( prio_rules ) {
- add_del_rule( 0, 0, RT_TABLE_INTERFACES, RT_PRIO_INTERFACES, 0, RTA_DST, ADD, TRACK_STANDARD );
add_del_rule( 0, 0, RT_TABLE_HOSTS, RT_PRIO_HOSTS, 0, RTA_DST, ADD, TRACK_STANDARD );
add_del_rule( 0, 0, RT_TABLE_NETWORKS, RT_PRIO_NETWORKS, 0, RTA_DST, ADD, TRACK_STANDARD );
}
-
+
// add rules and routes for interfaces
if ( update_interface_rules( IF_RULE_SET_NETWORKS ) < 0 )
cleanup_all( CLEANUP_FAILURE );
-
-
+
}
- */
return SUCCESS;
}
@@ -2127,21 +2144,26 @@
{ODI,4,0,ARG_RT_PRIO, 0, A_PS1,A_ADM,A_INI,A_CFA,A_ANY, &Rt_prio, MIN_RT_PRIO, MAX_RT_PRIO, DEF_RT_PRIO, 0,
ARG_VALUE_FORM, "set preferences for iproute2-style rules to rt_table (see: man ip)"},
- {ODI,4,0,ARG_RT_TABLE, 0, A_PS1,A_ADM,A_INI,A_CFA,A_ANY, &Rt_table, MIN_RT_TABLE, MAX_RT_TABLE, DEF_RT_TABLE, 0,
- ARG_VALUE_FORM, "set tables for iproute2-style routing tables (see: man ip)"},
-
- {ODI,4,0,ARG_THROW_RULES, 0, A_PS1,A_ADM,A_INI,A_CFA,A_ANY, &throw_rules, 0, 1, 1, 0,
+ {ODI,4,0,ARG_RT_TABLE, 0, A_PS1,A_ADM,A_INI,A_CFA,A_ANY, &Rt_table, MIN_RT_TABLE, MAX_RT_TABLE-RT_TABLE_MAX_OFFS, DEF_RT_TABLE, 0,
+ ARG_VALUE_FORM, "set bmx routing-table offset (iproute2 style, see: man ip)"},
+
+#ifndef LESS_OPTIONS
+ {ODI,4,0,ARG_THROW_RULES, 0, A_PS1,A_ADM,A_INI,A_CFA,A_ANY, &throw_rules, 0, 1, DEF_THROW_RULES,0,
ARG_VALUE_FORM, "disable/enable default throw rules"},
- {ODI,4,0,ARG_PRIO_RULES, 0, A_PS1,A_ADM,A_INI,A_CFA,A_ANY, &prio_rules, 0, 1, 1, 0,
+ {ODI,4,0,ARG_PRIO_RULES, 0, A_PS1,A_ADM,A_INI,A_CFA,A_ANY, &prio_rules, 0, 1, DEF_PRIO_RULES, 0,
ARG_VALUE_FORM, "disable/enable default priority rules"},
-
+#endif
{ODI,4,0,ARG_NO_POLICY_RT, 'n',A_PS0,A_ADM,A_INI,A_ARG,A_ANY, 0, 0, 0, 0, opt_policy_rt,
0, "disable policy routing (throw and priority rules)"},
- {ODI,4,0,"lo_rule", 0, A_PS1,A_ADM,A_INI,A_CFA,A_ANY, &Lo_rule, 0, 1, 1, 0,
+#ifndef LESS_OPTIONS
+ {ODI,4,0,"metric", 0, A_PS1,A_ADM,A_INI,A_CFA,A_ANY, &metric, 0, OV32, DEF_METRIC, 0,
+ ARG_VALUE_FORM, "set non-zero metric for all bmx routes"},
+
+ {ODI,4,0,"lo_rule", 0, A_PS1,A_ADM,A_INI,A_CFA,A_ANY, &Lo_rule, 0, 1, DEF_LO_RULE, 0,
ARG_VALUE_FORM, "disable/enable autoconfiguration of lo rule"},
-
+#endif
{ODI,5,0,ARG_THROW, 0, A_PMN,A_ADM,A_DYI,A_CFA,A_ANY, 0, 0, 0, 0, opt_throw,
ARG_PREFIX_FORM, "do NOT route packets matching src or dst IP range(s) into gateway tunnel or announced networks"},
@@ -2149,13 +2171,15 @@
ARG_NETW_FORM, "specify network of throw rule"},
{ODI,5,ARG_THROW,ARG_MASK, 'm',A_CS1,A_ADM,A_DYI,A_CFA,A_ANY, 0, 0, 0, 0, opt_throw,
- ARG_MASK_FORM, "specify network of throw rule"},
+ ARG_MASK_FORM, "specify network of throw rule"}
-
- {ODI,5,0,ARG_PEDANTIC_CLEANUP, 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &Pedantic_cleanup,0, 1, 0, 0,
+#ifndef LESS_OPTIONS
+ ,
+ {ODI,5,0,ARG_PEDANTIC_CLEANUP, 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &Pedantic_cleanup,0, 1, DEF_PEDANT_CLNUP,0,
ARG_VALUE_FORM, "disable/enable pedantic cleanup of system configuration (like ip_forward,..) \n"
" at program termination. Its generally safer to keep this disabled to not mess up \n"
- " with other routing protocols" }
+ " with other routing protocols"}
+#endif
};
@@ -2169,11 +2193,14 @@
void init_route( void ) {
- if( open_netlink_socket() < 0 )
+ if( ( nl_sk = open_netlink_socket()) <= 0 )
cleanup_all( -500067 );
- errno=0;
- if ( !rt_sock && (rt_sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
+ if( ( flush_sk = open_netlink_socket()) <= 0 )
+ cleanup_all( -500067 );
+
+ errno=0;
+ if ( !rt_sock && (rt_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
dbgf( DBGL_SYS, DBGT_ERR, "can't create routing socket %s:", strerror(errno) );
cleanup_all( -500021 );
}
@@ -2200,8 +2227,12 @@
restore_kernel_config( NULL );
- close_netlink_socket();
+ if( nl_sk > 0 )
+ close( nl_sk );
+ if( flush_sk > 0 )
+ close( flush_sk );
+
if ( rt_sock )
close( rt_sock );
Modified: trunk/batman-experimental/list-batman.c
===================================================================
--- trunk/batman-experimental/list-batman.c 2010-04-12 19:06:37 UTC (rev 1633)
+++ trunk/batman-experimental/list-batman.c 2010-04-15 08:16:16 UTC (rev 1634)
@@ -29,12 +29,14 @@
* This is only for internal list manipulation where we know
* the next entries already!
*/
+/*
void __list_add( struct list_head *new, struct list_head *prev, struct list_head *next ) {
new->next = next;
prev->next = new;
}
+*/
/**
* list_add - add a new entry
@@ -46,8 +48,11 @@
*/
void list_add( struct list_head *new, struct list_head_first *head ) {
- __list_add( new, (struct list_head *)head, head->next );
+// __list_add( new, (struct list_head *)head, head->next );
+ new->next = head->next;
+ ((struct list_head *)head)->next = new;
+
if ( head->prev == (struct list_head *)head )
head->prev = new;
@@ -63,7 +68,9 @@
*/
void list_add_tail( struct list_head *new, struct list_head_first *head ) {
- __list_add( new, head->prev, (struct list_head *)head );
+// __list_add( new, head->prev, (struct list_head *)head );
+ new->next = (struct list_head *)head;
+ head->prev->next = new;
head->prev = new;
@@ -85,11 +92,13 @@
* This is only for internal list manipulation where we know
* the next entries already!
*/
+/*
void __list_del( struct list_head *prev, struct list_head *next ) {
prev->next = next;
}
+*/
/**
* list_del - deletes entry from list.
@@ -101,8 +110,10 @@
if ( head->prev == entry )
head->prev = prev_entry;
- __list_del( prev_entry, entry->next );
+// __list_del( prev_entry, entry->next );
+ prev_entry->next = entry->next;
+
entry->next = (void *) 0;
}
@@ -113,9 +124,10 @@
* list_empty - tests whether a list is empty
* @head: the list to test.
*/
+/*
int list_empty( struct list_head_first *head ) {
return head->next == (struct list_head *)head;
}
-
+*/
Modified: trunk/batman-experimental/list-batman.h
===================================================================
--- trunk/batman-experimental/list-batman.h 2010-04-12 19:06:37 UTC (rev 1633)
+++ trunk/batman-experimental/list-batman.h 2010-04-15 08:16:16 UTC (rev 1634)
@@ -52,10 +52,10 @@
void list_add_tail( struct list_head *new, struct list_head_first *head );
void list_add_before( struct list_head *prev_node, struct list_head *next_node, struct list_head *new_node );
void list_del( struct list_head *prev_entry, struct list_head *entry, struct list_head_first *head );
-int list_empty( struct list_head_first *head );
+//int list_empty( struct list_head_first *head );
+#define list_empty(lst) ((lst)->next == (struct list_head *)(lst))
-
#define INIT_LIST_HEAD(ptr) do { \
(ptr)->next = (ptr); \
} while (0)
Modified: trunk/batman-experimental/metrics.c
===================================================================
--- trunk/batman-experimental/metrics.c 2010-04-12 19:06:37 UTC (rev 1633)
+++ trunk/batman-experimental/metrics.c 2010-04-15 08:16:16 UTC (rev 1634)
@@ -29,136 +29,16 @@
void flush_sq_record( struct sq_record *sqr ) {
- sqr->wa_val = sqr->wa_unscaled = sqr->wa_clr_sqn = sqr->wa_clr_sqn = 0;
-
- memset( sqr->sqn_entry_queue, 0, SQN_LOUNGE_SIZE );
-}
+ sqr->wa_val = sqr->wa_unscaled = 0;
+ sqr->wa_clr_sqn = sqr->wa_set_sqn = ((SQ_TYPE) (sqr->wa_clr_sqn - (MAX_PATH_LOUNGE + MAX_PWS + 1)));
-
-//returns seqno tip of exit queue
-static void push_sqn_lounge_queue( uint8_t probe, uint8_t lounge_size, SQ_TYPE seqno,
- struct sq_record *sqr, uint8_t ws,
- uint8_t *exit_queue, uint8_t *exit_queue_len, SQ_TYPE *exit_queue_tip,
- uint32_t orig, uint32_t neigh, struct batman_if *bif, char *who )
-{
-
- uint8_t pos = seqno % (SQN_LOUNGE_SIZE);
-
- dbgf_ext( DBGT_INFO, "probe %d, SQN %d, exitQueueTip %d, lounge_size %d, wa_val_old %d ws %d",
- probe, seqno, sqr->sqn_entry_queue_tip, lounge_size, sqr->wa_val, ws );
-
- if ( seqno == sqr->sqn_entry_queue_tip ) {
-
-#ifndef NOPARANOIA
- if ( probe && sqr->sqn_entry_queue[pos] ) {
- dbgf( DBGL_SYS, DBGT_ERR,
- "%s OG %16s NB %16s IF %s probe[%d]=%d but entryQueue[pos:%d]=%d already marked!",
- who, ipStr(orig), ipStr(neigh), bif->dev,
- seqno, probe, pos, sqr->sqn_entry_queue[pos] );
- }
-#endif
- if ( !sqr->sqn_entry_queue[pos] )
- sqr->sqn_entry_queue[pos] = probe;
-
- *exit_queue_len = 0;
- *exit_queue_tip = sqr->sqn_entry_queue_tip - lounge_size;
-
- dbgf_ext( DBGT_INFO, "MAINSTREAM (SQN equal to entry_queue_tip) wa_val_new %d, exitQueueLen %d, exitQueue[tip:%d] %d",
- sqr->wa_val, *exit_queue_len, *exit_queue_tip, exit_queue[(*exit_queue_tip)%SQN_LOUNGE_SIZE]);
-
-
-
- } else if ( ((SQ_TYPE)( seqno - sqr->sqn_entry_queue_tip )) > MAX_SEQNO - lounge_size ) { //impossible for lounge_size==0
-
-#ifndef NOPARANOIA
- if ( probe && sqr->sqn_entry_queue[pos] ) {
- dbgf( DBGL_SYS, DBGT_ERR,
- "%s OG %16s NB %16s IF %s probe[%d]=%d but entryQueue[pos:%d]=%d already marked! tip %d",
- who, ipStr(orig), ipStr(neigh), bif->dev,
- seqno, probe, pos, sqr->sqn_entry_queue[pos], sqr->sqn_entry_queue_tip);
- }
-#endif
- if ( !sqr->sqn_entry_queue[pos] )
- sqr->sqn_entry_queue[pos] = probe;
-
- *exit_queue_len = 0;
-
- *exit_queue_tip = sqr->sqn_entry_queue_tip - lounge_size;
-
- dbgf_ext( DBGT_INFO, "ACCEPTABLE (SQN within entry-queue-boundaries) wa_val_new %d, exitQueueLen %d, exitQueue[tip:%d] %d",
- sqr->wa_val, *exit_queue_len, *exit_queue_tip, exit_queue[(*exit_queue_tip)%SQN_LOUNGE_SIZE]);
-
-
- } else if ( ((SQ_TYPE)( seqno - sqr->sqn_entry_queue_tip )) <= lounge_size ) { //impossible for lounge_size==0
- // seqno == sqr->sqn_entry_queue_tip has already been catched above
-
- SQ_TYPE i;
- uint8_t len = 0;
-
-
- for( i = sqr->sqn_entry_queue_tip+1-lounge_size; i != ((SQ_TYPE)(seqno+1-lounge_size)); i++ ) {
- len++;
- exit_queue[i%SQN_LOUNGE_SIZE] = sqr->sqn_entry_queue[i%SQN_LOUNGE_SIZE];
- }
-
- for( i = sqr->sqn_entry_queue_tip+1 ; i != ((SQ_TYPE)(seqno+1)); i++ )
- sqr->sqn_entry_queue[i%SQN_LOUNGE_SIZE] = 0;
-
- sqr->sqn_entry_queue[pos] = probe;
- sqr->sqn_entry_queue_tip = seqno;
-
- *exit_queue_len = len;
- *exit_queue_tip = sqr->sqn_entry_queue_tip - lounge_size;
-
- dbgf_ext( DBGT_INFO, "AVANTGARDE (SQN redefining entry-queue-boundaries) wa_val_new %d, exitQueueLen %d, exitQueue[tip:%d] %d",
- sqr->wa_val, *exit_queue_len, *exit_queue_tip, exit_queue[(*exit_queue_tip)%SQN_LOUNGE_SIZE]);
-
-
-
- } else if ( ((SQ_TYPE)( seqno - sqr->sqn_entry_queue_tip )) <= ws + lounge_size ) {
- // seqno - sqr->sqn_entry_queue_tip <= lounge_size has already been catched above
-
- SQ_TYPE i, old_entry_queue_tip = sqr->sqn_entry_queue_tip;
-
- for( i = sqr->sqn_entry_queue_tip+1-lounge_size ; i != ((SQ_TYPE)(sqr->sqn_entry_queue_tip+1)); i++ )
- exit_queue[i%SQN_LOUNGE_SIZE] = sqr->sqn_entry_queue[i%SQN_LOUNGE_SIZE];
-
-
- for( i = seqno+1 - lounge_size ; i != ((SQ_TYPE)(seqno+1)); i++ )
- sqr->sqn_entry_queue[i%SQN_LOUNGE_SIZE] = 0;
-
- sqr->sqn_entry_queue[pos] = probe;
- sqr->sqn_entry_queue_tip = seqno;
-
- *exit_queue_len = lounge_size;
- *exit_queue_tip = old_entry_queue_tip;
-
- dbgf_ext( DBGT_INFO, "CRITICAL NEW (partly purging entry-queue) wa_val_new %d, exitQueueLen %d, exitQueue[tip:%d] %d",
- sqr->wa_val, *exit_queue_len, *exit_queue_tip, exit_queue[(*exit_queue_tip)%SQN_LOUNGE_SIZE]);
-
- } else {
-
- SQ_TYPE i;
-
- for( i = seqno+1 - lounge_size ; i != ((SQ_TYPE)(seqno+1)); i++ )
- sqr->sqn_entry_queue[i%SQN_LOUNGE_SIZE] = 0;
-
- sqr->sqn_entry_queue[pos] = probe;
- sqr->sqn_entry_queue_tip = seqno;
-
- *exit_queue_len = 0;
- *exit_queue_tip = sqr->sqn_entry_queue_tip - lounge_size;
-
- dbgf_ext( DBGT_INFO, "LOST NEW (completely purging entry-queue) wa_val_new %d, exitQueueLen %d, exitQueue[tip:%d] %d",
- sqr->wa_val, *exit_queue_len, *exit_queue_tip, exit_queue[(*exit_queue_tip)%SQN_LOUNGE_SIZE]);
-
- }
}
+/*
+//static
+void update_metric( uint8_t probe, SQ_TYPE sq_upd, struct sq_record *sqr, uint8_t ws ) {
-static void update_metric( uint8_t probe, SQ_TYPE sq_upd, struct sq_record *sqr, uint8_t ws ) {
-
uint32_t m_weight = ws/2;
SQ_TYPE offset = sq_upd - sqr->wa_clr_sqn;
uint32_t old_wa_val = sqr->wa_val;
@@ -195,75 +75,57 @@
dbgf_ext( DBGT_INFO, "probe %d, SQN %d, old_wa_val %d, new_wa_val %d", probe, sq_upd, old_wa_val, sqr->wa_val );
}
+*/
-/*update_queued_metric() MUST deal with unordered SQNs !!!
+void update_lounged_metric(uint8_t probe, uint8_t lounge_size, SQ_TYPE sqn_incm, SQ_TYPE sqn_max, struct sq_record *sqr, uint8_t ws)
+{
+ SQ_TYPE sq_upd;
-SQNs of incoming OGM are collected (queued) in a waiting-room/lounge (entry-queue)
-before being further processed (considered for path/link quality calculation).
-This way we can reorder lately rcvd OGM-SQNs and process them in the right order.
-The maximum acceptable delay (in terms of SQNs) is defined by the lounge_size of each node.
+ if ( probe )
+ sq_upd = sqn_incm;
-push_sqn_lounge_queue() is responsible to manage the waiting room and return ready-to-process SQN in the exit-queue
+ else if ( ((SQ_TYPE)(sqn_max - sqr->wa_clr_sqn )) > lounge_size )
+ sq_upd = sqn_max - lounge_size;
+ else
+ return;
-*/
-void update_queued_metric( uint8_t probe, uint8_t lounge_size, SQ_TYPE seqno, struct sq_record *sqr, uint8_t ws,
- uint32_t orig, uint32_t neigh, struct batman_if *bif, char* who )
-{
- dbgf_ext( DBGT_INFO, " " );
-
- uint8_t old_wa_val;
- old_wa_val = sqr->wa_val;
-
- if ( lounge_size == 0 ) {
-
- //IMPORTANT: update_metric needs ordered SQNs
- update_metric( probe, seqno, sqr, ws );
-
+
+ uint32_t m_weight = ws/2;
+ SQ_TYPE i, offset = sq_upd - sqr->wa_clr_sqn;
+
+ if ( offset >= ws ) {
+
+ sqr->wa_unscaled = 0;
+
} else {
-
- uint8_t exit_queue[SQN_LOUNGE_SIZE];
- uint8_t exit_queue_len;
- SQ_TYPE exit_queue_tip;
-
- push_sqn_lounge_queue( probe, lounge_size, seqno, sqr, ws,
- exit_queue, &exit_queue_len, &exit_queue_tip,
- orig, neigh, bif, who );
-
- SQ_TYPE i;
- for( i = exit_queue_tip+1-exit_queue_len; i != ((SQ_TYPE)(exit_queue_tip+1)); i++ )
- update_metric( exit_queue[i%SQN_LOUNGE_SIZE], i, sqr, ws );
-
- if ( sqr->sqn_entry_queue_tip == seqno ) { // MAINSTREAM, AVANTGARDE, CRITICAL_NEW, or LOST_NEW
-
- if ( exit_queue_len == 0 || // MAINSTREAM, ACCEPTABLE, or LOST_NEW
- ((SQ_TYPE)(sqr->sqn_entry_queue_tip - lounge_size)) != exit_queue_tip ) // CRITICAL_NEW
- {
- update_metric( 0, sqr->sqn_entry_queue_tip - lounge_size, sqr, ws );
- }
-
- }
+
+ for ( i=0; i < offset; i++ )
+ sqr->wa_unscaled -= ( sqr->wa_unscaled / m_weight );
+
}
-
- //dbgf( ((old_wa_val && !sqr->wa_val) ? DBGL_CHANGES : DBGL_ALL), ((old_wa_val && !sqr->wa_val) ? DBGT_WARN : DBGT_INFO),
- dbgf_ext( DBGT_INFO,
- /*if ( !strcmp( who, "process_ogm(own via NB)" ) || !strcmp( who, "schedule_own_ogm()") )
- dbg( DBGL_CHANGES, DBGT_INFO, */
- "done! %26s OG %-15s via IF %-10s NB %-10s probe %3d lounge_size %2d SQN %-5d wa_val old %3d new %3d",
- who, ipStr( orig ), bif->dev, ipStr( neigh ), probe, lounge_size, seqno, old_wa_val, sqr->wa_val );
-
-
-}
+ sqr->wa_clr_sqn = sq_upd;
-uint32_t get_wavg( uint32_t wavg, uint8_t weight_exp ) {
+ if ( probe /* && sqr->wa_set_sqn != sq_upd */ ) {
- return wavg>>weight_exp;
+ paranoia( -500197, (sqr->wa_set_sqn == sq_upd) /*check validate_considered_order()*/ );
+
+ sqr->wa_unscaled += ( (probe * WA_SCALE_FACTOR) / m_weight );
+
+ sqr->wa_set_sqn = sq_upd;
+ }
+
+ sqr->wa_val = sqr->wa_unscaled/WA_SCALE_FACTOR;
+
+
}
+
+
uint32_t upd_wavg( uint32_t *wavg, uint32_t probe, uint8_t weight_exp ) {
#ifndef NOPARANOIA
@@ -280,5 +142,5 @@
*wavg = probe<<weight_exp;
- return *wavg>>weight_exp;
+ return WAVG(*wavg,weight_exp);
}
Modified: trunk/batman-experimental/metrics.h
===================================================================
--- trunk/batman-experimental/metrics.h 2010-04-12 19:06:37 UTC (rev 1633)
+++ trunk/batman-experimental/metrics.h 2010-04-15 08:16:16 UTC (rev 1634)
@@ -28,10 +28,10 @@
void flush_sq_record( struct sq_record *sqr );
-void update_queued_metric( uint8_t probe, uint8_t lounge_size, SQ_TYPE seqno, struct sq_record *sqr, uint8_t ws,
- uint32_t orig, uint32_t neigh, struct batman_if *bif, char* who );
+void update_lounged_metric( uint8_t probe, uint8_t lounge_size, SQ_TYPE sqn_incm, SQ_TYPE sqn_max, struct sq_record *sqr, uint8_t ws );
-uint32_t get_wavg( uint32_t wavg, uint8_t weight_exp );
+#define WAVG( wavg , weight_exp ) ( (uint32_t) ( (wavg) >> (weight_exp) ) )
+
uint32_t upd_wavg( uint32_t *wavg, uint32_t probe, uint8_t weight_exp );
#endif
Modified: trunk/batman-experimental/originator.c
===================================================================
--- trunk/batman-experimental/originator.c 2010-04-12 19:06:37 UTC (rev 1633)
+++ trunk/batman-experimental/originator.c 2010-04-15 08:16:16 UTC (rev 1634)
@@ -30,41 +30,62 @@
#include "originator.h"
#include "plugin.h"
#include "schedule.h"
+//#include "avl.h"
static int32_t my_seqno;
-static int32_t path_hystere;
-int32_t my_lws;
-int32_t my_pws;
-int32_t my_ogi = DEF_OGI; /* orginator message interval in miliseconds */
-int32_t my_link_lounge;
-int32_t Default_lounge;
+int32_t my_pws = DEF_PWS;
-static int32_t purge_to;
-static int32_t dad_to;
+int32_t local_lws = DEF_LWS;
-static int32_t lateness_penalty;
+int32_t local_rtq_lounge = DEF_RTQ_LOUNGE;
-static int32_t Asocial_device;
+int32_t my_path_lounge = DEF_PATH_LOUNGE;
-int32_t Ttl;
+static int32_t my_path_hystere = DEF_PATH_HYST;
-int32_t wl_clones;
+static int32_t my_rcnt_hystere = DEF_RCNT_HYST;
-static int32_t asym_weight;
+static int32_t my_rcnt_pws = DEF_RCNT_PWS;
-static int32_t asym_exp;
+/*
+static int32_t my_rcnt_lounge = DEF_RCNT_LOUNGE;
+*/
+static int32_t my_rcnt_fk = DEF_RCNT_FK;
+static int32_t my_late_penalty = DEF_LATE_PENAL;
+
+static int32_t drop_2hop_loop = DEF_DROP_2HLOOP;
+
+static int32_t purge_to = DEF_PURGE_TO;
+
+int32_t dad_to = DEF_DAD_TO;
+
+static int32_t Asocial_device = DEF_ASOCIAL;
+
+int32_t Ttl = DEF_TTL;
+
+int32_t wl_clones = DEF_WL_CLONES;
+
+static int32_t my_asym_weight = DEF_ASYM_WEIGHT;
+
+static int32_t my_hop_penalty = DEF_HOP_PENALTY;
+
+static int32_t my_asym_exp = DEF_ASYM_EXP;
+
+
static SIMPEL_LIST( pifnb_list );
SIMPEL_LIST( link_list );
+//struct avl_tree link_avl = {sizeof( uint32_t), NULL};
+AVL_TREE( link_avl, sizeof( uint32_t) );
struct batman_if *primary_if = NULL;
uint32_t primary_addr = 0;
-//char primary_ip_str[ADDR_STR_LEN] = "";
-struct hashtable_t *orig_hash = NULL;
+//struct avl_tree orig_avl = {sizeof( uint32_t), NULL};
+AVL_TREE( orig_avl, sizeof( uint32_t) );
SIMPEL_LIST( if_list );
@@ -79,20 +100,20 @@
dbgf_all( DBGT_INFO, " " );
- addr_to_str( (new_router ? new_router->addr : 0 ), new_nh_str );
- addr_to_str( (orig_node->router ? orig_node->router->addr : 0 ), old_nh_str );
+ addr_to_str( (new_router ? new_router->nnkey_addr : 0 ), new_nh_str );
+ addr_to_str( (orig_node->router ? orig_node->router->nnkey_addr : 0 ), old_nh_str );
/* update routing table and check for changed hna announcements */
if ( orig_node->router != new_router )
dbg( DBGL_CHANGES, DBGT_INFO, "change route to %-15s via %-15s %s %3d / %3d (prev. via %-15s %s %3d)",
orig_node->orig_str,
new_nh_str,
- (new_router ? new_router->iif->dev : "--"),
- (new_router ? new_router->accepted_sqr.wa_val : 0),
+ (new_router ? new_router->nnkey_iif->dev : "--"),
+ (new_router ? new_router->longtm_sqr.wa_val : 0),
orig_node->pws,
old_nh_str,
- (orig_node->router ? orig_node->router->iif->dev : "--"),
- (orig_node->router ? orig_node->router->accepted_sqr.wa_val : 0) );
+ (orig_node->router ? orig_node->router->nnkey_iif->dev : "--"),
+ (orig_node->router ? orig_node->router->longtm_sqr.wa_val : 0) );
if ( orig_node->router != new_router ) {
@@ -104,10 +125,10 @@
/* route altered or deleted */
if ( orig_node->router ) {
- add_del_route( orig_node->orig, 32, orig_node->router->addr, 0,
- orig_node->router->iif->if_index,
- orig_node->router->iif->dev,
- RT_TABLE_HOSTS, RT_UNICAST, DEL, TRACK_OTHER_HOST );
+ add_del_route( orig_node->orig, 32, orig_node->router->nnkey_addr, 0,
+ orig_node->router->nnkey_iif->if_index,
+ orig_node->router->nnkey_iif->dev,
+ RT_TABLE_HOSTS, RTN_UNICAST, DEL, TRACK_OTHER_HOST );
}
@@ -116,10 +137,10 @@
orig_node->rt_changes++;
- add_del_route( orig_node->orig, 32, new_router->addr, primary_addr,
- new_router->iif->if_index,
- new_router->iif->dev,
- RT_TABLE_HOSTS, RT_UNICAST, ADD, TRACK_OTHER_HOST );
+ add_del_route( orig_node->orig, 32, new_router->nnkey_addr, primary_addr,
+ new_router->nnkey_iif->if_index,
+ new_router->nnkey_iif->dev,
+ RT_TABLE_HOSTS, RTN_UNICAST, ADD, TRACK_OTHER_HOST );
}
@@ -132,7 +153,7 @@
}
static void flush_orig( struct orig_node *orig_node, struct batman_if *bif ) {
- struct list_head *neigh_pos /*, *neigh_temp, *neigh_prev*/;
+ struct list_head *neigh_pos /*, *neigh_temp, *neigh_prev */;
struct neigh_node *neigh_node = NULL;
dbgf_all( DBGT_INFO, "%s", ipStr( orig_node->orig ) );
@@ -141,20 +162,49 @@
neigh_node = list_entry( neigh_pos, struct neigh_node, list );
- if ( !bif || bif == neigh_node->iif )
- flush_sq_record( &neigh_node->accepted_sqr );
+ if ( !bif || bif == neigh_node->nnkey_iif ) {
+ flush_sq_record( &neigh_node->longtm_sqr );
+ flush_sq_record( &neigh_node->recent_sqr );
+ }
}
+
- if ( !bif || ( orig_node->router && orig_node->router->iif == bif ) ) {
+ if ( !bif || ( orig_node->router && orig_node->router->nnkey_iif == bif ) ) {
update_routes( orig_node, NULL );
cb_plugin_hooks( orig_node, PLUGIN_CB_ORIG_FLUSH );
}
+
+/*
+ * plugins must be called with PLUGIN_CB_ORIG_FLUSH and PLUGIN_CB_ORIG_DESRTROY
+ * before orig_node->router can be destroyed:
+ *
+ neigh_prev = (struct list_head *) & orig_node->neigh_list;
+ // for all neighbours towards this originator ...
+
+ list_for_each_safe(neigh_pos, neigh_temp, &orig_node->neigh_list) {
+
+ neigh_node = list_entry(neigh_pos, struct neigh_node, list);
+
+ if (!bif || (neigh_node->iif == bif)) {
+
+ list_del(neigh_prev, neigh_pos, &orig_node->neigh_list);
+
+ debugFree(neigh_node, 1403);
+
+ } else {
+ neigh_prev = &neigh_node->list;
+ }
+ }
+*/
+
+
}
-static struct neigh_node *init_neigh_node( struct orig_node *orig_node, uint32_t neigh, struct batman_if *iif, uint16_t seqno, uint32_t last_aware )
+static
+struct neigh_node *init_neigh_node( struct orig_node *orig_node, uint32_t neigh, struct batman_if *iif, uint16_t seqno, uint32_t last_aware )
{
dbgf_all( DBGT_INFO, " " );
@@ -162,142 +212,207 @@
memset( neigh_node, 0, sizeof(struct neigh_node) );
INIT_LIST_HEAD( &neigh_node->list );
- neigh_node->addr = neigh;
- neigh_node->iif = iif;
+ neigh_node->nnkey_addr = neigh;
+ neigh_node->nnkey_iif = iif;
neigh_node->last_aware = last_aware;
list_add_tail( &neigh_node->list, &orig_node->neigh_list );
+ avl_insert(&orig_node->neigh_avl, neigh_node );
return neigh_node;
}
-
-
-static struct neigh_node *update_orig( struct orig_node *orig_node, struct orig_node *orig_node_neigh,
- uint16_t *oCtx, struct msg_buff *mb )
+static
+struct neigh_node *update_orig(struct orig_node *on, uint16_t *oCtx, struct msg_buff *mb)
{
-
prof_start( PROF_update_originator );
struct list_head *neigh_pos;
- struct neigh_node *incoming_neigh = NULL, *tmp_neigh = NULL;
- struct neigh_node *curr_router = orig_node->router;
-
+ struct neigh_node *incm_rt = NULL, *tmp_neigh = NULL;
+ struct neigh_node *curr_rt = on->router;
+ struct neigh_node *old_rt;
struct bat_packet_ogm *ogm = mb->bp.ogm;
-
- uint32_t best_neigh_val = 0;
-
- dbgf_all( DBGT_INFO, "%s", orig_node->orig_str );
-
+ old_rt = curr_rt;
+ uint32_t max_othr_longtm_val = 0;
+ uint32_t max_othr_recent_val = 0;
+
+ dbgf_all( DBGT_INFO, "%s", on->orig_str );
+
/* only used for debugging purposes */
- if ( orig_node->first_valid_sec == 0 )
- orig_node->first_valid_sec = batman_time_sec;
+ if (!on->first_valid_sec)
+ on->first_valid_sec = batman_time_sec;
// find incoming_neighbor and purge outdated SQNs of alternative next hops
- list_for_each( neigh_pos, &orig_node->neigh_list ) {
+ list_for_each( neigh_pos, &on->neigh_list ) {
+ uint8_t probe = 0;
+
tmp_neigh = list_entry( neigh_pos, struct neigh_node, list );
- if ( ( tmp_neigh->addr == mb->neigh ) && ( tmp_neigh->iif == mb->iif ) )
- incoming_neigh = tmp_neigh;
+ if ( ( tmp_neigh->nnkey_addr == mb->neigh ) && ( tmp_neigh->nnkey_iif == mb->iif ) ) {
- uint8_t probe = 0;
-
- if ( incoming_neigh == tmp_neigh && (*oCtx & IS_ACCEPTED)) {
-
- if ( *oCtx & IS_NEW )
- probe = PROBE_RANGE;
- else
- probe = PROBE_RANGE - (lateness_penalty*PROBE_TO100);
-
- }
-
- update_queued_metric( probe,
- orig_node->path_lounge, ogm->ogm_seqno, &tmp_neigh->accepted_sqr, orig_node->pws,
- orig_node->orig, tmp_neigh->addr, mb->iif,
- (incoming_neigh == tmp_neigh) ? "update_orig( incoming NB )" : "update_orig( other NB )" );
-
-
- best_neigh_val = MAX( best_neigh_val, tmp_neigh->accepted_sqr.wa_val );
-
- }
+ incm_rt = tmp_neigh;
- if ( !incoming_neigh )
- cleanup_all( -500001 );
-
-
- /*
- only change curr_router if:
- - incoming packet has been received via incoming_neighbor which is better than the old curr_router
- - not-yet-rebroadcasted (not-yet-decided based on) this or newer seeqno
- */
-
- if ( ( ( curr_router == NULL ) ||
- ( curr_router->accepted_sqr.wa_val == 0 && incoming_neigh->accepted_sqr.wa_val ) ||
- ( curr_router->accepted_sqr.wa_val + (path_hystere*PROBE_TO100) < incoming_neigh->accepted_sqr.wa_val) ) &&
- //( (uint16_t)( ogm->ogm_seqno - (orig_node->last_decided_sqn + 1) ) <= MAX_SEQNO - orig_node->pws ) )
- ((SQ_TYPE)( orig_node->last_decided_sqn - ogm->ogm_seqno ) >= orig_node->pws ) )
- {
- curr_router = incoming_neigh;
- }
-
- /*
- only keep and rebroadcast OGM rcvd via old curr_router if:
- - curr_router == incoming_neighbor is really the best neighbor towards our destination
- - not-yet-rebroadcasted (not-yet-decided based on) this or newer seeqno
- */
- if ( curr_router == incoming_neigh ) {
-
- if ( ( curr_router->accepted_sqr.wa_val + (path_hystere*PROBE_TO100) >= best_neigh_val ) &&
- ((SQ_TYPE)( orig_node->last_decided_sqn - ogm->ogm_seqno ) >= orig_node->pws ) ) {
-
- orig_node->last_decided_sqn = ogm->ogm_seqno;
-
- *oCtx |= IS_BEST_NEIGH_AND_NOT_BROADCASTED;
-
- }
-
- } else {
-
+ if (*oCtx & IS_ACCEPTED) {
+
+ if (*oCtx & IS_NEW)
+ probe = PROBE_RANGE;
+ else
+ probe = PROBE_RANGE - (my_late_penalty * PROBE_TO100);
+ }
+ }
+
+ update_lounged_metric(probe, my_path_lounge, ogm->ogm_seqno, on->last_valid_sqn, &tmp_neigh->longtm_sqr,
+ on->pws);
+
+ if ( incm_rt != tmp_neigh)
+ max_othr_longtm_val = MAX(max_othr_longtm_val, tmp_neigh->longtm_sqr.wa_val);
+
+
+
+ if ( my_rcnt_fk == MAX_RCNT_FK )
+ continue;
+
+ //if (*oCtx & IS_NEW || (((SQ_TYPE) (on->last_valid_sqn - ogm->ogm_seqno)) <= my_rcnt_lounge))
+
+ update_lounged_metric(probe, my_path_lounge, ogm->ogm_seqno, on->last_valid_sqn, &tmp_neigh->recent_sqr,
+ my_rcnt_pws);
+
+
+ if ( incm_rt != tmp_neigh )
+ max_othr_recent_val = MAX(max_othr_recent_val, tmp_neigh->recent_sqr.wa_val);
+
+ }
+
+
+
+ paranoia( -500001, !incm_rt );
+
+ /*
+ * The following if-else-else branch implements my currently best known heuristic
+ * Its tuned for fast path convergence as well as long-term path-quality awareness.
+ * In the future this should be configurable by each node participating in the mesh.
+ * Its Fuzzy! The following path-quality characteristics are judged:
+ * - Recent vers. Longterm path quality
+ * - eXtreme vers. Conservative distinction to alternative paths
+ * - Best vers. Worst path quality
+ * allowing combinations like:
+ * Recent_Conservative_Best (RCB) -- Recent_eXtreme_Best (RXB) -- Longterm_Conservative_Best (LCB)
+ * The general idea is to keep/change the path (best neighbor) if:
+ * - change: (RXB (implying RCB)) || (RCB && LCB)
+ * - keep: RXB || RCB || LCB
+ * - not-yet-rebroadcasted (not-yet-finally-decided based on) this or newer seqno
+ * - incoming packet has been received via incoming_neighbor which is better than all other router
+ * - curr_router == incoming_neighbor is really the best neighbor towards our destination
+ * */
+ int8_t RXB = 0, RCB = 0, LCB = 0, changed = 0;
+
+
+ if ( ( curr_rt != incm_rt ) &&
+ ( ((SQ_TYPE)( on->last_decided_sqn - ogm->ogm_seqno ) >= on->pws ) ) &&
+
+ ( ( ( my_rcnt_fk == MAX_RCNT_FK ) &&
+ ( ( LCB = ((int)incm_rt->longtm_sqr.wa_val > (int)(max_othr_longtm_val) + (my_path_hystere * PROBE_TO100)) ) )
+
+ ) || (
+
+ ( my_rcnt_fk != MAX_RCNT_FK ) &&
+
+ ( ( ( LCB = ((int)incm_rt->longtm_sqr.wa_val > (int)(max_othr_longtm_val) + (my_path_hystere * PROBE_TO100)) ) &&
+ ( RCB = ((int)incm_rt->recent_sqr.wa_val > (int)(max_othr_recent_val) ) ) )
+ ||
+ ( RXB = ((int)incm_rt->recent_sqr.wa_val > (int)((max_othr_recent_val * my_rcnt_fk)/100) + (my_rcnt_hystere * PROBE_TO100)) )
+
+ )
+ )
+ )
+ ) {
+
+ curr_rt = incm_rt;
+ on->last_decided_sqn = ogm->ogm_seqno;
+ *oCtx |= IS_BEST_NEIGH_AND_NOT_BROADCASTED;
+ changed = YES;
+
+ } else if
+ ( ( curr_rt == incm_rt ) &&
+ ( ((SQ_TYPE)( on->last_decided_sqn - ogm->ogm_seqno ) >= on->pws ) ) &&
+
+ ( ( ( my_rcnt_fk == MAX_RCNT_FK ) &&
+ ( ( LCB = ((int)incm_rt->longtm_sqr.wa_val >= (int)(max_othr_longtm_val) - (my_path_hystere * PROBE_TO100)) ) )
+
+ ) || (
+
+ ( my_rcnt_fk != MAX_RCNT_FK ) &&
+
+ ( ( ( LCB = ((int)incm_rt->longtm_sqr.wa_val >= (int)(max_othr_longtm_val) - (my_path_hystere * PROBE_TO100)) ) ||
+ ( RCB = ((int)incm_rt->recent_sqr.wa_val >= (int)(max_othr_recent_val) ) ) )
+ )
+ )
+ )
+ ) {
+
+ on->last_decided_sqn = ogm->ogm_seqno;
+ *oCtx |= IS_BEST_NEIGH_AND_NOT_BROADCASTED;
+
+ }
+
+ if ( changed && !LCB ) {
+ dbgf(DBGL_CHANGES, DBGT_INFO,
+ "%s path to %-15s via %-15s (old %-15s incm %-15s) due to %s %s %s PH: "
+ "recent incm %3d othr %3d fk %-4d "
+ "longtm incm %3d othr %3d",
+ changed ? "NEW" : "OLD",
+ on->orig_str,
+ curr_rt ? ipStr(curr_rt->nnkey_addr) : "----",
+ old_rt ? ipStr(old_rt->nnkey_addr) : "----",
+ ipStr(incm_rt->nnkey_addr),
+ LCB ? " LCB" : "!LCB",
+ RCB ? " RCB" : "!RCB",
+ RXB ? " RXB" : "!RXB",
+ incm_rt->recent_sqr.wa_val / PROBE_TO100,
+ max_othr_recent_val, my_rcnt_fk,
+ incm_rt->longtm_sqr.wa_val / PROBE_TO100,
+ max_othr_longtm_val
+ );
+ }
+
+ if ( curr_rt != incm_rt ) {
+
// only evaluate and change recorded attributes and route if arrived via best neighbor
prof_stop( PROF_update_originator );
- return curr_router;
+ return curr_rt;
}
-
- orig_node->last_path_ttl = ogm->ogm_ttl;
+
+
+ on->last_path_ttl = ogm->ogm_ttl;
- orig_node->ogx_flag = ogm->ogx_flag;
+ on->ogx_flag = ogm->ogx_flag;
- orig_node->ogm_misc = ogm->ogm_misc;
+ on->ogm_misc = ogm->ogm_misc;
- uint8_t orig_changed = 0;
- if ( orig_node->pws != ogm->ogm_pws ) {
+ if ( on->pws != ogm->ogm_pws ) {
dbg( DBGL_SYS, DBGT_INFO,
"window size of OG %s changed from %d to %d, flushing packets and route!",
- orig_node->orig_str, orig_node->pws, ogm->ogm_pws );
+ on->orig_str, on->pws, ogm->ogm_pws );
- orig_node->pws = ogm->ogm_pws;
- orig_changed++;
- }
-
- if ( orig_changed ) {
- flush_orig( orig_node, NULL );
+ on->pws = ogm->ogm_pws;
+ flush_orig( on, NULL );
prof_stop( PROF_update_originator );
return NULL;
}
-
prof_stop( PROF_update_originator );
- return curr_router;
+ return curr_rt;
}
-static void free_pifnb_node( struct orig_node *orig_node ) {
+static
+void free_pifnb_node( struct orig_node *orig_node ) {
struct pifnb_node *pn;
struct list_head *pifnb_pos, *pifnb_pos_tmp, *prev_list_head;
@@ -332,7 +447,8 @@
}
-static int8_t init_pifnb_node( struct orig_node *orig_node ) {
+static
+int8_t init_pifnb_node( struct orig_node *orig_node ) {
struct pifnb_node *pn_tmp = NULL;
struct list_head *list_pos, *prev_list_head;
uint16_t id4him = 1;
@@ -378,7 +494,8 @@
-static void free_link_node( struct orig_node *orig_node, struct batman_if *bif ) {
+static
+void free_link_node( struct orig_node *orig_node, struct batman_if *bif ) {
struct link_node *ln;
struct list_head *list_pos, *list_tmp, *list_prev;
@@ -399,7 +516,7 @@
if ( !bif || lndev->bif == bif ) {
- dbgf( DBGL_CHANGES, DBGT_INFO, "purging lndev %16s %10s %s",
+ dbgf_all( DBGT_INFO, "purging lndev %16s %10s %s",
orig_node->orig_str, lndev->bif->dev, lndev->bif->if_ip_str );
list_del( list_prev, list_pos, &ln->lndev_list );
@@ -421,7 +538,10 @@
if ( ln->orig_node == orig_node && list_empty( &ln->lndev_list ) ) {
+ dbgf_all( DBGT_INFO, "purging link_node %16s ", orig_node->orig_str);
+
list_del( list_prev, list_pos, &link_list );
+ avl_remove(&link_avl, /*(uint32_t*)*/orig_node->link_node);
debugFree( orig_node->link_node, 1428 );
@@ -436,7 +556,8 @@
}
-static void flush_link_node_seqnos( void ) {
+static
+void flush_link_node_seqnos( void ) {
struct list_head *ln_pos, *lndev_pos, *lndev_tmp;
struct link_node *ln = NULL;
@@ -457,7 +578,8 @@
}
}
-static void init_link_node( struct orig_node *orig_node ) {
+static
+void init_link_node( struct orig_node *orig_node ) {
struct link_node *ln;
@@ -468,47 +590,52 @@
INIT_LIST_HEAD( &ln->list );
ln->orig_node = orig_node;
+ ln->orig_addr = orig_node->orig;
INIT_LIST_HEAD_FIRST( ln->lndev_list );
list_add_tail ( &ln->list, &link_list );
+ avl_insert(&link_avl, ln);
}
-static int8_t validate_orig_seqno( struct orig_node *orig_node, uint32_t neigh, SQ_TYPE ogm_seqno ) {
+static
+int8_t validate_orig_seqno( struct orig_node *orig_node, uint32_t neigh, SQ_TYPE ogm_seqno ) {
// this originator IP is somehow known..(has ever been valid)
if ( orig_node->last_valid_time || orig_node->last_valid_sqn ) {
- if ( (uint16_t)( ogm_seqno + orig_node->path_lounge - orig_node->last_valid_sqn ) >
+ if ( (uint16_t)( ogm_seqno + my_path_lounge - orig_node->last_valid_sqn ) >
MAX_SEQNO - orig_node->pws ) {
dbg_mute( 25, DBGL_CHANGES, DBGT_WARN,
"drop OGM %-15s via %4s NB %-15s with old SQN %5i "
"(prev %5i lounge-margin %2i pws %3d lvld %d) !",
orig_node->orig_str,
- (orig_node->router && orig_node->router->addr == neigh) ? "best" : "altn",
+ (orig_node->router && orig_node->router->nnkey_addr == neigh) ? "best" : "altn",
ipStr(neigh),
ogm_seqno,
orig_node->last_valid_sqn,
- orig_node->path_lounge, orig_node->pws, orig_node->last_valid_time );
+ my_path_lounge, orig_node->pws, orig_node->last_valid_time );
return FAILURE;
- }
-
-
- if ( // if seqno is more than 10 times out of dad timeout
- ((uint16_t)( ogm_seqno + orig_node->path_lounge - orig_node->last_valid_sqn )) >
- ((10 * dad_to) + orig_node->path_lounge) &&
- // but we have received an ogm in less than timeout sec
- LESS_U32( batman_time, (orig_node->last_valid_time + (1000 * dad_to)) ) )
+ }
+
+
+ if (// if seqno is more than 10 times out of dad timeout
+ ((uint16_t) (ogm_seqno + my_path_lounge - orig_node->last_valid_sqn)) >
+ (my_path_lounge +
+ ((1000 * dad_to) / MIN(WAVG(orig_node->ogi_wavg, OGI_WAVG_EXP), MIN_OGI))) &&
+ // but we have received an ogm in less than timeout sec
+ LESS_U32(batman_time, (orig_node->last_valid_time + (1000 * dad_to))))
{
dbg_mute( 26, DBGL_SYS, DBGT_WARN,
"DAD-alert! %s via NB %s with out-of-range SQN %i lounge-margin %i "
- "lvld %i at %d Reinit in %d s",
- orig_node->orig_str, ipStr(neigh), ogm_seqno, orig_node->path_lounge,
- orig_node->last_valid_sqn, orig_node->last_valid_time,
+ "lvld %i at %d dad_to %d wavg %d Reinit in %d s",
+ orig_node->orig_str, ipStr(neigh), ogm_seqno, my_path_lounge,
+ orig_node->last_valid_sqn, orig_node->last_valid_time,
+ dad_to, WAVG(orig_node->ogi_wavg, OGI_WAVG_EXP),
((orig_node->last_valid_time + (1000 * dad_to)) - batman_time)/1000 );
return FAILURE;
@@ -533,27 +660,8 @@
// remove old:
if ( orig_node->primary_orig_node != orig_node ) {
- /*
- struct list_head *pos, *tmp;
- struct list_head *prev = (struct list_head *)&orig_node->primary_orig->pog_referrer_list;
- list_for_each_safe( pos, tmp, &orig_node->primary_orig->pog_referrer_list ) {
-
- struct pog_referrer_node *pog_referrer_node = list_entry( pos, struct pog_referrer_node, list );
-
- if ( pog_referrer_node->addr = orig_node->orig ) ) {
-
- list_del( prev, pos, &orig_node->primary_orig->pog_referrer_list );
-
- debugFree( pos, 1555 );
-
- } else {
- prev = &pog_referrer_node->list;
- }
-
- }
- */
orig_node->primary_orig_node->pog_refcnt--;
- paranoia( -5000152, orig_node->pog_refcnt < 0 );
+ paranoia( -500152, orig_node->pog_refcnt < 0 );
}
orig_node->primary_orig_node = NULL;
@@ -564,15 +672,8 @@
// add new:
if ( orig_node->orig != new_primary_addr ) {
- /*
- struct pog_referrer_node *pog_referrer_node = debugMalloc( sizeof (struct pog_referrer_node), 555 );
- memset( pog_referrer_node, 0, sizeof(struct pog_referrer_node) );
- INIT_LIST_HEAD( &pog_referrer_node->list );
- pog_referrer_node->addr = new_primary_addr;
- list_add_tail( &pog_referrer_node->list, &orig_node->pog_referrer_list );
- */
- orig_node->primary_orig_node = get_orig_node( new_primary_addr, YES/*create*/ );
-
+
+ orig_node->primary_orig_node = get_orig_node( new_primary_addr, YES/*create*/ );
orig_node->primary_orig_node->pog_refcnt++;
} else {
@@ -585,8 +686,8 @@
}
-static int8_t validate_primary_orig( struct orig_node *orig_node, struct msg_buff *mb, uint16_t oCtx ) {
- //static int8_t validate_primary_orig( struct orig_node *orig_node, uint32_t primary_addr, SQ_TYPE primary_sqn, uint8_t is_direct ) {
+static
+int8_t validate_primary_orig( struct orig_node *orig_node, struct msg_buff *mb, uint16_t oCtx ) {
if ( mb->rcv_ext_len[EXT_TYPE_64B_PIP] ) {
@@ -667,11 +768,60 @@
return SUCCESS;
}
+static
+void update_rtq_link(struct orig_node *orig_node_neigh, uint16_t oCtx, struct msg_buff *mb,
+ struct batman_if *iif, struct bat_packet_ogm *ogm, struct link_node_dev *lndev)
+{
+ dbgf_all(DBGT_INFO,
+ "received own OGM via NB, lastTxIfSeqno: %d, currRxSeqno: %d oCtx: 0x%X "
+ "link_node %s primary_orig %s",
+ (iif->if_seqno - OUT_SEQNO_OFFSET), ogm->ogm_seqno, oCtx,
+ (orig_node_neigh->link_node ? "exist" : "NOT exists"),
+ (orig_node_neigh->primary_orig_node ? "exist" : "NOT exists"));
+ if (!(oCtx & HAS_DIRECTLINK_FLAG) || (oCtx & HAS_CLONED_FLAG) || iif->if_addr != ogm->orig)
+ return;
-static void update_link( struct orig_node *orig_node, SQ_TYPE sqn, struct batman_if *iif, uint16_t oCtx, uint8_t link_flags ) {
-
+
+ if (((SQ_TYPE) ((iif->if_seqno - OUT_SEQNO_OFFSET) - ogm->ogm_seqno)) > local_rtq_lounge ) {
+
+ dbg_mute(51, DBGL_CHANGES, DBGT_WARN,
+ "late reception of own OGM via NB %s lastTxIfSqn %d rcvdSqn %d margin %d ! "
+ "Try configureing a greater --%s value .",
+ mb->neigh_str, (iif->if_seqno - OUT_SEQNO_OFFSET),
+ ogm->ogm_seqno, local_rtq_lounge, ARG_RTQ_LOUNGE);
+
+ return;
+ }
+
+ /* neighbour has to indicate direct link and it has to come via the corresponding interface */
+ /* if received seqno equals last send seqno save new seqno for bidirectional check */
+ if (orig_node_neigh->link_node && orig_node_neigh->primary_orig_node && lndev) {
+
+ update_lounged_metric(PROBE_RANGE, local_rtq_lounge, ogm->ogm_seqno, (iif->if_seqno - OUT_SEQNO_OFFSET),
+ &lndev->rtq_sqr, local_lws);
+
+
+ if (orig_node_neigh->primary_orig_node->id4me != ogm->prev_hop_id) {
+
+ if (orig_node_neigh->primary_orig_node->id4me != 0)
+ dbg_mute(53, DBGL_CHANGES, DBGT_WARN,
+ "received changed prev_hop_id from neighbor %s !!!",
+ mb->neigh_str);
+
+ orig_node_neigh->primary_orig_node->id4me = ogm->prev_hop_id;
+ }
+
+ dbgf_all(DBGT_INFO, "indicating bidirectional link");
+
+ }
+}
+
+
+static
+void update_rq_link( struct orig_node *orig_node, SQ_TYPE sqn, struct batman_if *iif, uint16_t oCtx ) {
+
if ( !( (oCtx & IS_DIRECT_NEIGH) || orig_node->link_node ) )
return;
@@ -682,32 +832,20 @@
if ( !orig_node->link_node )
init_link_node( orig_node );
-
- //check for changed link flags
- if ( orig_node->link_node->link_flags != link_flags ) {
-
- dbg( DBGL_SYS, DBGT_INFO, "neighbor %s changed link flags from %X to %X",
- orig_node->orig_str, orig_node->link_node->link_flags, link_flags );
-
- orig_node->link_node->link_flags = link_flags;
- }
}
- dbgf_all( DBGT_INFO, "OG %s SQN %d IF %s ctx %x link_flags %x ln %s cloned %s direct %s",
- orig_node->orig_str, sqn, iif->dev, oCtx, link_flags,
+ dbgf_all( DBGT_INFO, "OG %s SQN %d IF %s ctx %x ln %s cloned %s direct %s",
+ orig_node->orig_str, sqn, iif->dev, oCtx,
orig_node->link_node ? "YES":"NO",
(oCtx & HAS_CLONED_FLAG) ? "YES":"NO",
(oCtx & IS_DIRECT_NEIGH) ? "YES":"NO" );
-
-
- // skip updateing link_node if this SQN is known but not new
+
+ // skip updateing link_node if this SQN is known but not new
if ( ( orig_node->last_valid_time || orig_node->last_valid_sqn ) &&
- ( (uint16_t)( sqn + my_link_lounge - orig_node->last_valid_sqn ) > MAX_SEQNO - my_lws ) )
- {
+ ( (uint16_t)( sqn + RQ_LINK_LOUNGE - orig_node->last_valid_sqn ) > MAX_SEQNO - local_lws - MAX_PATH_LOUNGE) )
return;
- }
paranoia( -500156, !orig_node->link_node );
@@ -730,9 +868,7 @@
this_lndev = lndev;
} else {
- update_queued_metric( 0, my_link_lounge, sqn, &lndev->rq_sqr, my_lws,
- orig_node->orig, orig_node->orig, lndev->bif,
- "update_link( other link )" );
+ update_lounged_metric( 0, RQ_LINK_LOUNGE, sqn, orig_node->last_valid_sqn, &lndev->rq_sqr, local_lws );
}
@@ -744,12 +880,12 @@
if ( this_lndev ) {
uint8_t probe = ( (oCtx & IS_DIRECT_NEIGH) && !(oCtx & HAS_CLONED_FLAG) ) ? PROBE_RANGE : 0;
-
- update_queued_metric( probe, my_link_lounge, sqn, &this_lndev->rq_sqr, my_lws,
- orig_node->orig, orig_node->orig, iif,
- "update_link( this link )" );
-
- this_lndev->last_lndev = batman_time;
+
+ update_lounged_metric(probe, RQ_LINK_LOUNGE, sqn, orig_node->last_valid_sqn, &this_lndev->rq_sqr, local_lws);
+
+ if ( probe)
+ this_lndev->last_lndev = batman_time;
+
}
//orig_node->link_node->last_rq_sqn = in_seqno;
@@ -769,12 +905,13 @@
}
-static int tq_power( int tq_rate_value, int range ) {
+static
+int tq_power( int tq_rate_value, int range ) {
int tq_power_value = range;
int exp_counter;
- for ( exp_counter = 0; exp_counter < asym_exp; exp_counter++ )
+ for ( exp_counter = 0; exp_counter < my_asym_exp; exp_counter++ )
tq_power_value = ((tq_power_value * tq_rate_value) / range);
return tq_power_value;
@@ -782,83 +919,49 @@
-static uint8_t alreadyConsideredValid( struct orig_node *orig_node, SQ_TYPE seqno, uint32_t neigh, struct batman_if *iif ) {
+static
+int8_t validate_considered_order( struct orig_node *orig_node, SQ_TYPE seqno, uint32_t neigh, struct batman_if *iif ) {
+
+
+ struct neigh_node *nn;
+ struct neigh_node_key key = {neigh, iif};
+
+ if ( (nn = (struct neigh_node*)avl_find( &orig_node->neigh_avl, &key )) ) {
+
+ paranoia( -500198, (nn->nnkey_addr != neigh || nn->nnkey_iif != iif ) );
+
+ nn->last_aware = batman_time;
+
+ if (seqno == nn->last_considered_seqno) {
+
+ return FAILURE;
+
+ } else if (((SQ_TYPE) (seqno - nn->last_considered_seqno)) > MAX_SEQNO - my_pws) {
+
+ dbgf_ext(DBGT_WARN,
+ "rcvd illegal SQN %d order from %s via %s %s (last considered sqn %d",
+ seqno, orig_node->orig_str, ipStr(neigh), iif->dev,
+ nn->last_considered_seqno);
+
+ return FAILURE;
+ }
+
+ nn->last_considered_seqno = seqno;
+ return SUCCESS;
+ }
- struct list_head *neigh_pos;
- struct neigh_node *neigh_node;
+ nn = init_neigh_node( orig_node, neigh, iif, seqno, batman_time );
- uint8_t spos = seqno % (SQN_LOUNGE_SIZE);
-
- list_for_each( neigh_pos, &orig_node->neigh_list ) {
-
- neigh_node = list_entry( neigh_pos, struct neigh_node, list );
-
- if ( neigh == neigh_node->addr && iif == neigh_node->iif ) {
-
- dbgf_ext( DBGT_INFO,
- "OG %s via IF %s NB %s SQN %d spos %d lastConsideredSQN %d lounge_size %d",
- orig_node->orig_str, iif->dev, ipStr(neigh),
- seqno, spos, neigh_node->last_considered_seqno, orig_node->path_lounge );
-
- neigh_node->last_aware = batman_time;
-
- if ( seqno == neigh_node->last_considered_seqno ) {
-
- if ( neigh_node->considered_seqnos & (0x01<<spos) )
- return YES;
-
- neigh_node->considered_seqnos |= (0x01<<spos);
- return NO;
-
- } else if ( ((SQ_TYPE)( seqno - neigh_node->last_considered_seqno )) > MAX_SEQNO - orig_node->path_lounge ) {
-
- if ( neigh_node->considered_seqnos & (0x01<<spos) )
- return YES;
-
- neigh_node->considered_seqnos |= (0x01<<spos);
- return NO;
-
-
- } else if ( ((SQ_TYPE)( seqno - neigh_node->last_considered_seqno )) <= orig_node->path_lounge ) {
- // seqno == neigh_node->last_considered_seqno has already been catched above
-
- SQ_TYPE i;
-
- for( i = neigh_node->last_considered_seqno+1 ; i != ((SQ_TYPE)(seqno+1)); i++ )
- neigh_node->considered_seqnos &= ~( 0x01 << (i%(SQN_LOUNGE_SIZE)) );
-
- neigh_node->considered_seqnos |= (0x01<<spos);
- neigh_node->last_considered_seqno = seqno;
- return NO;
-
- } else {
-
- neigh_node->considered_seqnos = (0x01<<spos);
- neigh_node->last_considered_seqno = seqno;
- return NO;
-
- }
-
- }
-
- }
-
- neigh_node = init_neigh_node( orig_node, neigh, iif, seqno, batman_time );
-
- neigh_node->considered_seqnos = (0x01<<spos);
- neigh_node->last_considered_seqno = seqno;
- return NO;
+ nn->last_considered_seqno = seqno;
+ return SUCCESS;
}
/* this function finds and may create an originator entry for the given address */
struct orig_node *get_orig_node( uint32_t addr, uint8_t create ) {
prof_start( PROF_get_orig_node );
- struct orig_node *orig_node;
- struct hashtable_t *swaphash;
-
- orig_node = ((struct orig_node *)hash_find( orig_hash, &addr ));
-
+ struct orig_node *orig_node = ((struct orig_node *)avl_find( &orig_avl, &addr));
+
if ( !create ) {
prof_stop( PROF_get_orig_node );
return orig_node;
@@ -874,7 +977,8 @@
memset( orig_node, 0, (sizeof(struct orig_node) + (plugin_data_registries[PLUGIN_DATA_ORIG] * sizeof(void*) ) ) );
INIT_LIST_HEAD_FIRST( orig_node->neigh_list );
- //INIT_LIST_HEAD_FIRST( pog_referrer_list );
+ AVL_INIT_TREE( orig_node->neigh_avl, sizeof( struct neigh_node_key ) );
+
addr_to_str( addr, orig_node->orig_str );
dbgf_all( DBGT_INFO, "creating new originator: %s with %d plugin_data_registries",
@@ -884,26 +988,23 @@
orig_node->last_aware = batman_time;
orig_node->router = NULL;
orig_node->link_node = NULL;
- orig_node->path_lounge = Default_lounge;
-
- orig_node->ogi_wavg = 0;
- orig_node->pws = my_pws;
-
- hash_add( orig_hash, orig_node );
-
- if ( orig_hash->elements * 4 > orig_hash->size ) {
-
- swaphash = hash_resize( orig_hash, orig_hash->size * 2 );
-
- if ( swaphash == NULL ) {
- dbg( DBGL_SYS, DBGT_ERR, "couldn't resize hash table" );
- cleanup_all( -500097 );
- }
-
- orig_hash = swaphash;
-
- }
-
+// orig_node->path_lounge = my_path_lounge;
+ orig_node->pws = my_pws;
+// orig_node->path_hystere = my_path_hystere;
+// orig_node->late_penalty = my_late_penalty;
+// orig_node->hop_penalty = my_hop_penalty;
+// orig_node->asym_weight = my_asym_weight;
+// orig_node->asym_exp = my_asym_exp;
+// orig_node->rcnt_pws = my_rcnt_pws;
+// orig_node->rcnt_lounge = my_rcnt_lounge;
+// orig_node->rcnt_hystere = my_rcnt_hystere;
+// orig_node->rcnt_fk = my_rcnt_fk;
+
+
+ upd_wavg(&orig_node->ogi_wavg, DEF_OGI, OGI_WAVG_EXP);
+
+ avl_insert( &orig_avl, /*(uint32_t*)*/orig_node);
+
cb_plugin_hooks( orig_node, PLUGIN_CB_ORIG_CREATE );
prof_stop( PROF_get_orig_node );
@@ -914,26 +1015,28 @@
void purge_orig( uint32_t curr_time, struct batman_if *bif ) {
prof_start( PROF_purge_originator );
- struct hash_it_t *hashit = NULL;
struct list_head *neigh_pos, *neigh_temp, *neigh_prev;
- struct orig_node *orig_node;
+ struct orig_node *orig_node = NULL;
struct neigh_node *neigh_node;
static char neigh_str[ADDR_STR_LEN];
dbgf_all( DBGT_INFO, "%d %s", curr_time, bif ? bif->dev : "???" );
- checkIntegrity();
+ //checkIntegrity();
/* for all origins... */
- while ( (hashit = hash_iterate( orig_hash, hashit )) ) {
+ uint32_t orig_ip = 0;
+
+ while ( (orig_node = (struct orig_node*)avl_next( &orig_avl, &orig_ip ) ) ) {
+
+ orig_ip = orig_node->orig;
+
+ dbgf_all( DBGT_INFO, "%d %s %s", curr_time, bif ? bif->dev : "???", orig_node->orig_str );
+
+
- orig_node = hashit->bucket->data;
-
- dbgf_all( DBGT_INFO, "%d %s %s", curr_time, bif ? bif->dev : "???", orig_node->orig_str );
-
- /* purge outdated originators completely */
-
if ( !curr_time || bif || LESS_U32( orig_node->last_aware + (1000*((uint32_t)purge_to)), curr_time ) ) {
+ /* purge outdated originators completely */
dbgf_all( DBGT_INFO, "originator timeout: %s, last_valid %u, last_aware %u",
orig_node->orig_str, orig_node->last_valid_time, orig_node->last_aware );
@@ -952,9 +1055,10 @@
neigh_node = list_entry( neigh_pos, struct neigh_node, list );
- if ( !bif || ( neigh_node->iif == bif ) ) {
+ if ( !bif || ( neigh_node->nnkey_iif == bif ) ) {
list_del( neigh_prev, neigh_pos, &orig_node->neigh_list );
+ avl_remove( &orig_node->neigh_avl, neigh_node );
debugFree( neigh_node, 1403 );
@@ -979,7 +1083,7 @@
set_primary_orig( orig_node, 0 );
- hash_remove_bucket( orig_hash, hashit );
+ avl_remove( &orig_avl, /*(uint32_t*)*/orig_node);
debugFree( orig_node, 1402 );
}
@@ -1044,12 +1148,14 @@
orig_node->router != neigh_node )
{
- addr_to_str( neigh_node->addr, neigh_str );
+ addr_to_str( neigh_node->nnkey_addr, neigh_str );
dbgf_all( DBGT_INFO,
"Neighbour timeout: originator %s, neighbour: %s, last_aware %u",
orig_node->orig_str, neigh_str, neigh_node->last_aware );
list_del( neigh_prev, neigh_pos, &orig_node->neigh_list );
+
+ avl_remove( &orig_node->neigh_avl, neigh_node );
debugFree( neigh_node, 1403 );
@@ -1062,9 +1168,8 @@
}
}
- checkIntegrity();
+ //checkIntegrity();
-
prof_stop( PROF_purge_originator );
}
@@ -1198,193 +1303,136 @@
}
- //mb->orig_node_neigh =
orig_node_neigh = get_orig_node( neigh, YES/*create*/ );
- if ( orig_node_neigh->link_node )
- lndev = get_lndev( orig_node_neigh->link_node, iif, NO/*create*/ );
-
-
- if ( !( (oCtx & IS_DIRECT_NEIGH) || orig_node_neigh->last_valid_time ) ) {
-
+ if ( !(oCtx & IS_DIRECT_NEIGH) && !(orig_node_neigh->last_valid_time) ) {
dbgf_all( DBGT_INFO, "drop OGM: rcvd via unknown neighbor!" );
goto process_ogm_end;
- }
+ }
+
+ if ((oCtx & HAS_CLONED_FLAG) && !orig_node_neigh->primary_orig_node) {
+ dbgf_all(DBGT_INFO, "drop OGM: first contact with neighbor MUST be without cloned flag!");
+ goto process_ogm_end;
+ }
+
+ if (orig_node_neigh->link_node)
+ lndev = get_lndev(orig_node_neigh->link_node, iif, NO/*create*/);
+
-
if ( oCtx & IS_MY_ORIG ) {
-
- dbgf_all( DBGT_INFO,
- "received own OGM via NB, lastTxIfSeqno: %d, currRxSeqno: %d, prevRxSeqno: %d, "
- "currRxSeqno-prevRxSeqno %d, link_node %s primary_orig %s",
- ( iif->if_seqno - OUT_SEQNO_OFFSET ), ogm->ogm_seqno, 0, 0,
- (orig_node_neigh->link_node ? "exist":"NOT exists"),
- (orig_node_neigh->primary_orig_node ? "exist":"NOT exists") );
-
- if ( !(oCtx & HAS_DIRECTLINK_FLAG) || iif->if_addr != ogm->orig )
- goto process_ogm_end;
-
-
- if ( ((SQ_TYPE)(( iif->if_seqno - OUT_SEQNO_OFFSET ) - ogm->ogm_seqno )) > my_link_lounge ) {
-
- dbg_mute( 51, DBGL_CHANGES, DBGT_WARN,
- "late reception of own OGM via NB %s lastTxIfSqn %d rcvdSqn %d margin %d",
- mb->neigh_str, ( iif->if_seqno - OUT_SEQNO_OFFSET ),
- ogm->ogm_seqno, my_link_lounge );
-
- goto process_ogm_end;
- }
-
- /* neighbour has to indicate direct link and it has to come via the corresponding interface */
- /* if received seqno equals last send seqno save new seqno for bidirectional check */
- if ( !(oCtx & HAS_CLONED_FLAG) &&
- orig_node_neigh->link_node &&
- orig_node_neigh->primary_orig_node &&
- lndev )
- {
-
- update_queued_metric( PROBE_RANGE, my_link_lounge, ogm->ogm_seqno,
- &lndev->rtq_sqr, my_lws,
- ogm->orig, orig_node_neigh->orig, iif, "process_ogm(own via NB)" );
-
-
- if ( orig_node_neigh->primary_orig_node->id4me != ogm->prev_hop_id ) {
-
- if( orig_node_neigh->primary_orig_node->id4me != 0 )
- dbg_mute( 53, DBGL_CHANGES, DBGT_WARN,
- "received changed prev_hop_id from neighbor %s !!!",
- mb->neigh_str );
-
- orig_node_neigh->primary_orig_node->id4me = ogm->prev_hop_id;
- }
-
- dbgf_all( DBGT_INFO, "indicating bidirectional link");
-
- } else {
-
- dbgf_all( DBGT_WARN, "NOT indicating bidirectional link" );
-
- }
-
+ update_rtq_link(orig_node_neigh, oCtx, mb, iif, ogm, lndev);
goto process_ogm_end;
}
-
-
- /* drop packet if sender is not a direct NB and if we have no route towards the rebroadcasting NB */
- if ( !(oCtx & IS_DIRECT_NEIGH) && orig_node_neigh->router == NULL ) {
-
- dbgf_all( DBGT_INFO, "drop OGM: via unknown (non-direct) neighbor!" );
+
+ if ( ogm->ogm_ttl == 0 ) {
+ dbgf_all( DBGT_INFO, "drop OGM: TTL of zero!" );
goto process_ogm_end;
- }
+ }
+
+ if ( lndev && lndev->rtq_sqr.wa_val > 0 )
+ oCtx |= IS_BIDIRECTIONAL;
+
- if ( !(oCtx & IS_DIRECT_NEIGH) && ( orig_node_neigh->primary_orig_node == NULL ||
- orig_node_neigh->primary_orig_node->id4me == 0 ||
- orig_node_neigh->primary_orig_node->id4me == ogm->prev_hop_id ) )
- {
-
- dbgf_all( DBGT_INFO, "drop OGM: %s via NB %s %s !!!!",
- ipStr( ogm->orig ), mb->neigh_str,
- ( ( orig_node_neigh->primary_orig_node == NULL ||
- orig_node_neigh->primary_orig_node->id4me == 0 ) ?
- "with unknown primaryOG" :" via two-hop loop " ) );
-
- goto process_ogm_end;
- }
+ // drop packet if sender is not a direct NB and if we have no route towards the rebroadcasting NB
+ if (!(oCtx & IS_DIRECT_NEIGH) && !(orig_node_neigh->router)) {
+ dbgf_all(DBGT_INFO, "drop OGM: via unknown (non-direct) neighbor!");
+ goto process_ogm_end;
+ }
+
+ if (!(oCtx & IS_DIRECT_NEIGH)) {
+
+ if (!orig_node_neigh->primary_orig_node || !orig_node_neigh->primary_orig_node->id4me) {
+
+ dbgf_all(DBGT_INFO, "drop OGM: %s via NB %s %s !!!!",
+ ipStr(ogm->orig), mb->neigh_str, "with unknown primaryOG");
+ goto process_ogm_end;
+ }
+
+ if (drop_2hop_loop &&
+ orig_node_neigh->primary_orig_node &&
+ orig_node_neigh->primary_orig_node->id4me == ogm->prev_hop_id) {
+
+ dbgf_all(DBGT_INFO, "drop OGM: %s via NB %s %s !!!!",
+ ipStr(ogm->orig), mb->neigh_str, " via two-hop loop ");
+ goto process_ogm_end;
+ }
+ }
- if ( ogm->ogm_ttl == 0 ) {
-
- dbgf_all( DBGT_INFO, "drop OGM: TTL of zero!" );
- goto process_ogm_end;
- }
mb->orig_node = orig_node =
(oCtx & IS_DIRECT_NEIGH) ? orig_node_neigh : get_orig_node( ogm->orig, YES/*create*/ );
-
- if ( validate_orig_seqno( orig_node, neigh, ogm->ogm_seqno ) == FAILURE ) {
- //dbg_mute( 25, DBGL_CHANGES, DBGT_WARN, "drop OGM: %15s, via NB %15s, with seqno %i\n",
- // ipStr( ogm->orig ), mb->neigh_str, ogm->ogm_seqno );
- goto process_ogm_end;
+
+
+ if (validate_orig_seqno(orig_node, neigh, ogm->ogm_seqno) == FAILURE) {
+ dbgf_all( DBGT_WARN, "drop OGM: %15s, via NB %15s, SQN %i\n",
+ ipStr(ogm->orig), mb->neigh_str, ogm->ogm_seqno);
+ goto process_ogm_end;
}
-
-
- if ( (oCtx & HAS_CLONED_FLAG) && orig_node_neigh->primary_orig_node == NULL ) {
- dbgf_all( DBGT_INFO, "drop OGM: first contact with neighbor MUST be without cloned flag!" );
- goto process_ogm_end;
- }
-
if ( validate_primary_orig( orig_node, mb, oCtx ) == FAILURE ) {
-
dbg( DBGL_SYS, DBGT_WARN, "drop OGM: primary originator/if conflict!" );
goto process_ogm_end;
}
- if ( alreadyConsideredValid( orig_node, ogm->ogm_seqno, neigh, iif ) ) {
-
+ if ( validate_considered_order( orig_node, ogm->ogm_seqno, neigh, iif ) == FAILURE ) {
dbgf_all( DBGT_INFO, "drop OGM: already considered this OGM and SEQNO via this link neighbor!" );
goto process_ogm_end;
}
- // OK! OGM seems valid..
- oCtx |= IS_VALID;
-
uint16_t rand_100 = rand_num( 100 );
addr_to_str( ogm->orig, mb->orig_str );
+
- //MUST be after validate_primary_orig()
- update_link( orig_node, ogm->ogm_seqno, iif, oCtx, mb->link_flags );
-
- if ( orig_node_neigh->link_node && lndev && lndev->rtq_sqr.wa_val > 0 )
- oCtx |= IS_BIDIRECTIONAL;
-
-
if ( ((SQ_TYPE)( orig_node->last_valid_sqn - ogm->ogm_seqno )) >= orig_node->pws ) {
// we've never seen a valid sqn of this size before, therefore:
// everything which is out of our current path-window is new!
- oCtx |= IS_NEW;
+ oCtx |= IS_NEW;
+
+ // estimating average originaotr interval of this node
+ if (orig_node->last_valid_time && LESS_U32(orig_node->last_valid_time, batman_time)) {
+
+ if (((SQ_TYPE) (ogm->ogm_seqno - (orig_node->last_wavg_sqn + 1))) < orig_node->pws) {
+ upd_wavg(&orig_node->ogi_wavg,
+ ((batman_time - orig_node->last_valid_time) /
+ (ogm->ogm_seqno - orig_node->last_wavg_sqn)),
+ OGI_WAVG_EXP);
+ }
+
+ orig_node->last_wavg_sqn = ogm->ogm_seqno;
+ }
+
+ orig_node->last_valid_sqn = ogm->ogm_seqno;
+ orig_node->last_valid_time = batman_time;
+
+ } else if ( ((SQ_TYPE)( orig_node->last_valid_sqn - ogm->ogm_seqno )) <= my_path_lounge ) {
- } else if ( ((SQ_TYPE)( orig_node->last_valid_sqn - ogm->ogm_seqno )) <= orig_node->path_lounge ) {
-
// everything else which is still within SQN_ENTRY_QUEUE is acceptable
oCtx |= IS_ACCEPTABLE;
-
}
- if ( oCtx & IS_NEW ) {
-
- // estimating average originaotr interval of this node
- if ( ((SQ_TYPE)( ogm->ogm_seqno - orig_node->last_valid_sqn+1 )) < orig_node->pws &&
- orig_node->last_valid_time && LESS_U32( orig_node->last_valid_time, batman_time ) )
- {
- upd_wavg( &orig_node->ogi_wavg,
- ( (batman_time - orig_node->last_valid_time) /
- (ogm->ogm_seqno - orig_node->last_valid_sqn)),
- OGI_WAVG_EXP );
- }
-
- orig_node->last_valid_sqn = ogm->ogm_seqno;
- orig_node->last_valid_time = batman_time;
-
- }
+ //MUST be after validate_primary_orig()
+ update_rq_link( orig_node, ogm->ogm_seqno, iif, oCtx );
+
+
-
int tq_rate_value = tq_rate( orig_node_neigh, iif, PROBE_RANGE );
if ( (oCtx & IS_BIDIRECTIONAL) &&
((oCtx & IS_NEW) || (oCtx & IS_ACCEPTABLE)) &&
+ rand_100 >= my_hop_penalty &&
// rand_100 <= (MAX_ASYM_WEIGHT - asym_weight) + ( (tq_power(tq_rate_value,PROBE_RANGE)/PROBE_TO100) * 99) / 100 )
- rand_100 <= (MAX_ASYM_WEIGHT - asym_weight) + ( (tq_power(tq_rate_value,PROBE_RANGE)/PROBE_TO100) ) )
+ rand_100 <= (MAX_ASYM_WEIGHT - my_asym_weight) + ( (tq_power(tq_rate_value,PROBE_RANGE)/PROBE_TO100) ) )
{
// finally we only accept OGMs with probability TQ of its incoming link
@@ -1395,20 +1443,25 @@
struct neigh_node *old_router = orig_node->router;
- struct neigh_node *new_router = update_orig( orig_node, orig_node_neigh, &oCtx, mb );
+ struct neigh_node *new_router = update_orig( orig_node, &oCtx, mb );
if ( old_router != new_router )
update_routes( orig_node, new_router );
- if ( new_router != orig_node->router ) {
+ if ( !new_router || new_router != orig_node->router ) {
- dbgf( DBGL_SYS, DBGT_ERR,
- "new_router %s for %s differs from installed router %s",
- ipStr( new_router ? new_router->addr : 0 ),
+ dbgf_all( DBGT_INFO, //as long as incoming link is not bidirectional,...
+ "new_rt %s for %s is zero or differs from installed rt %s "
+ "(old_rt %s rcvd vi %s %s",
+ ipStr( new_router ? new_router->nnkey_addr : 0 ),
orig_node->orig_str,
- ipStr( orig_node->router ? orig_node->router->addr : 0 ) );
+ ipStr( orig_node->router ? orig_node->router->nnkey_addr : 0 ),
+ ipStr( old_router ? old_router->nnkey_addr : 0 ), mb->neigh_str, mb->iif->dev );
}
+
+ // new_router can be zero !!!
+ //paranoia( -500195, ( !new_router || new_router != orig_node->router ) );
// check if ogm_hooks would reject new_router
if ( cb_ogm_hooks( mb, oCtx, old_router ) != CB_OGM_ACCEPT ) {
@@ -1420,14 +1473,14 @@
dbgf_all( DBGT_INFO,
"done OGM accepted %s acceptable %s bidirectLink %s new %s BNTOG %s asocial %s tq %d "
- "asym_w %d acceptSQN %d rcvdSQN %d rand100 %d",
+ "hop_penalty %d asym_w %d acceptSQN %d rcvdSQN %d rand100 %d",
( oCtx & IS_ACCEPTED ? "Y" : "N" ),
( oCtx & IS_ACCEPTABLE ? "Y" : "N" ),
( oCtx & IS_BIDIRECTIONAL ? "Y" : "N" ),
( oCtx & IS_NEW ? "Y" : "N" ),
( oCtx & IS_BEST_NEIGH_AND_NOT_BROADCASTED ? "Y" : "N" ),
( oCtx & IS_ASOCIAL ? "Y" : "N" ),
- tq_rate_value, asym_weight, orig_node->last_accepted_sqn, ogm->ogm_seqno, rand_100 );
+ tq_rate_value, my_hop_penalty, my_asym_weight, orig_node->last_accepted_sqn, ogm->ogm_seqno, rand_100 );
// either it IS_DIRECT_NEIGH, then validate_primary_orig() with orig_node=orig_neigh_node has been called
@@ -1436,7 +1489,10 @@
//paranoia( -5000151, (!orig_node_neigh->primary_orig_node->id4him) );
if ( !orig_node_neigh->primary_orig_node->id4him ) {
- dbgf( DBGL_SYS, DBGT_WARN, "invalid id4him");
+
+ dbgf( DBGL_SYS, DBGT_WARN, "invalid id4him for orig %s via %s",
+ orig_node->orig_str, mb->neigh_str );
+
goto process_ogm_end;
}
@@ -1452,9 +1508,9 @@
-static int32_t opt_show_origs ( uint8_t cmd, uint8_t _save, struct opt_type *opt, struct opt_parent *patch, struct ctrl_node *cn ) {
+static
+int32_t opt_show_origs ( uint8_t cmd, uint8_t _save, struct opt_type *opt, struct opt_parent *patch, struct ctrl_node *cn ) {
- struct hash_it_t *hashit = NULL;
struct orig_node *orig_node;
uint16_t batman_count = 0;
@@ -1465,113 +1521,123 @@
if ( !strcmp( opt->long_name, ARG_ORIGINATORS ) ) {
- int nodes_count = 0, sum_packet_count = 0, sum_rcvd_all_bits = 0;
- int sum_lvld = 0, sum_last_pws = 0, sum_last_pls = 0, sum_ogi_avg = 0;
+ int nodes_count = 0, sum_packet_count = 0, sum_recent_count = 0;
+ int sum_lvld = 0, sum_last_pws = 0, sum_ogi_avg = 0;
int sum_reserved_something = 0, sum_route_changes = 0, sum_hops = 0;
- dbg_printf( cn, "Originator outgoingIF bestNextHop brc "
- "(~rcvd knownSince lseq lvld pws pls ~ogi misc hop change )\n");
-
- while ( (hashit = hash_iterate( orig_hash, hashit )) ) {
-
- orig_node = hashit->bucket->data;
-
+ dbg_printf( cn, "Originator outgoingIF bestNextHop TQ(rcnt) "
+ "knownSince lsqn(diff) lvld pws ~ogi cpu hop\n");
+ uint32_t orig_ip = 0;
+
+ while ((orig_node = (struct orig_node*) avl_next(&orig_avl, &orig_ip))) {
+
+ orig_ip = orig_node->orig;
+
if ( !orig_node->router || orig_node->primary_orig_node != orig_node )
continue;
+
+ /*
+ struct orig_node *onn = get_orig_node( orig_node->router->addr, NO );
+
+ if ( !onn || !onn->last_valid_time || !onn->router )
+ continue;
+ */
+/*
+ int estimated_rcvd = (( (100 * orig_node->router->accepted_sqr.wa_val)/PROBE_TO100 )+99) /
+ (((tq_power( tq_rate( onn, onn->router->iif, PROBE_RANGE ), PROBE_RANGE ) )/PROBE_TO100)+1);
+*/
- struct orig_node *onn = get_orig_node( orig_node->router->addr, NO/*create*/ );
-
- if ( !onn || !onn->last_valid_time || !onn->router )
- continue;
-
nodes_count++;
batman_count++;
- int estimated_rcvd = (( (100 * orig_node->router->accepted_sqr.wa_val)/PROBE_TO100 )+99) /
- (((tq_power( tq_rate( onn, onn->router->iif, PROBE_RANGE ), PROBE_RANGE ) )/PROBE_TO100)+1);
- dbg_printf( cn, "%-15s %-10s %15s %3i ( %3i %s %5i %4i %3i %3i %4i %4i %3i %6i )\n",
- orig_node->orig_str, orig_node->router->iif->dev,
- ipStr( orig_node->router->addr ),
- orig_node->router->accepted_sqr.wa_val/PROBE_TO100,
- estimated_rcvd > 100 ? 100 : estimated_rcvd,
+ dbg_printf( cn, "%-15s %-10s %-15s %3i %3i %s %5i %3i %5i %3i %4i %3i %3i\n",
+ orig_node->orig_str, orig_node->router->nnkey_iif->dev,
+ ipStr( orig_node->router->nnkey_addr ),
+ orig_node->router->longtm_sqr.wa_val/PROBE_TO100,
+ orig_node->router->recent_sqr.wa_val/PROBE_TO100,
+// estimated_rcvd > 100 ? 100 : estimated_rcvd,
get_human_uptime( orig_node->first_valid_sec ),
orig_node->last_valid_sqn,
+ orig_node->router->longtm_sqr.wa_clr_sqn - orig_node->last_valid_sqn,
( batman_time - orig_node->last_valid_time)/1000,
orig_node->pws,
- orig_node->path_lounge,
- get_wavg( orig_node->ogi_wavg, OGI_WAVG_EXP ),
+ WAVG( orig_node->ogi_wavg, OGI_WAVG_EXP ),
orig_node->ogm_misc,
- (Ttl+1 - orig_node->last_path_ttl),
- orig_node->rt_changes
+ (Ttl+1 - orig_node->last_path_ttl)
);
- sum_packet_count+= orig_node->router->accepted_sqr.wa_val/PROBE_TO100; /* accepted */
- sum_rcvd_all_bits+= MIN( estimated_rcvd, 100 );
+ sum_packet_count+= orig_node->router->longtm_sqr.wa_val/PROBE_TO100; /* accepted */
+ sum_recent_count+= orig_node->router->recent_sqr.wa_val/PROBE_TO100; /* accepted */
+// sum_rcvd_all_bits+= MIN( estimated_rcvd, 100 );
sum_lvld+= (batman_time - orig_node->last_valid_time)/1000;
sum_last_pws+= orig_node->pws;
- sum_last_pls+=orig_node->path_lounge;
- sum_ogi_avg+= get_wavg( orig_node->ogi_wavg, OGI_WAVG_EXP );
+ sum_ogi_avg+= WAVG( orig_node->ogi_wavg, OGI_WAVG_EXP );
sum_reserved_something+= orig_node->ogm_misc;
sum_route_changes+= orig_node->rt_changes;
sum_hops+= (Ttl+1 - orig_node->last_path_ttl);
}
- dbg_printf( cn, "%4d %-37s %3i ( %3i %4i %3i %3i %4i %4i %3i %6d )\n",
+ dbg_printf( cn, "%8d %-33s %3i %3i %5i %3i %4i %3i %3i\n",
nodes_count, "known Originator(s), averages: ",
(nodes_count > 0 ? ( sum_packet_count / nodes_count ) : -1 ),
- (nodes_count > 0 ? ( sum_rcvd_all_bits / nodes_count ) : -1 ),
+ (nodes_count > 0 ? ( sum_recent_count / nodes_count ) : -1 ),
+// (nodes_count > 0 ? ( sum_rcvd_all_bits / nodes_count ) : -1 ),
(nodes_count > 0 ? ( sum_lvld / nodes_count ) : -1),
(nodes_count > 0 ? ( sum_last_pws / nodes_count ) : -1 ),
- (nodes_count > 0 ? ( sum_last_pls / nodes_count ) : -1 ),
(nodes_count > 0 ? ( sum_ogi_avg / nodes_count ) : -1),
(nodes_count > 0 ? ( sum_reserved_something / nodes_count ) : -1),
- (nodes_count > 0 ? ( sum_hops / nodes_count ) : -1),
- (nodes_count > 0 ? ( sum_route_changes / nodes_count ) : -1) );
+ (nodes_count > 0 ? ( sum_hops / nodes_count ) : -1) );
} else if ( !strcmp( opt->long_name, ARG_STATUS ) ) {
- dbg_printf( cn, "BatMan-eXp %s%s, "
- "%s %s, LWS %i, PWS %i, OGI %4ims, SQN %5d, "
- "UT %s, CPU %2d.%1d\n",
+ dbg_printf( cn, "BMX %s%s, "
+ "%s, LWS %i, PWS %i, OGI %4ims, "
+ "UT %s, CPU %d.%1d\n",
SOURCE_VERSION,
( strncmp( REVISION_VERSION, "0", 1 ) != 0 ? REVISION_VERSION : "" ),
- primary_if ? primary_if->dev : "--",
ipStr( primary_addr ),
- my_lws, my_pws, my_ogi,
- primary_if ? primary_if->if_seqno : 0,
+ local_lws, my_pws, my_ogi,
get_human_uptime( 0 ),
s_curr_avg_cpu_load/10, s_curr_avg_cpu_load%10
);
} else if ( !strcmp( opt->long_name, ARG_LINKS ) ) {
+
+ dbg_printf( cn, "Neighbor viaIF Originator RTQ RQ TQ "
+ " lseq lvld rid nid\n");
+
+ uint32_t orig_ip = 0;
+ struct link_node * ln;
+
+ while ((ln = (struct link_node*) avl_next(&link_avl, &orig_ip))) {
+
+ orig_ip = ln->orig_addr;
+
+/*
struct list_head *link_pos;
-
- dbg_printf( cn, "Neighbor outgoingIF bestNextHop brc "
- "(~rcvd knownSince lseq lvld rid nid ) [ viaIF RTQ RQ TQ]\n");
-
list_for_each( link_pos, &link_list ) {
struct link_node *ln = list_entry(link_pos, struct link_node, list);
-
+*/
+
+
orig_node = ln->orig_node;
if ( !orig_node->router )
continue;
- struct orig_node *onn = get_orig_node( orig_node->router->addr, NO/*create*/ );
+/*
+ struct orig_node *onn = get_orig_node( orig_node->router->addr, NO );
if ( !onn || !onn->last_valid_time || !onn->router )
continue;
+*/
- int estimated_rcvd = (( (100 * orig_node->router->accepted_sqr.wa_val)/PROBE_TO100 )+99) /
- (((tq_power( tq_rate( onn, onn->router->iif, PROBE_RANGE ), PROBE_RANGE ) )/PROBE_TO100)+1);
-
-
struct list_head *lndev_pos;
list_for_each( lndev_pos, &ln->lndev_list ) {
@@ -1582,22 +1648,22 @@
tq = tq_rate( orig_node, lndev->bif, PROBE_RANGE );
rtq = lndev->rtq_sqr.wa_val;
- dbg_printf( cn, "%-15s %-10s %15s %3i ( %3i %s %5i %4i %3d %3d ) "
- "[%10s %3i %3i %3i] \n",
- orig_node->orig_str, orig_node->router->iif->dev,
- ipStr( orig_node->router->addr ),
- // accepted and rebroadcasted:
- orig_node->router->accepted_sqr.wa_val/PROBE_TO100,
- estimated_rcvd > 100 ? 100 : estimated_rcvd,
- get_human_uptime( orig_node->first_valid_sec ),
+ dbg_printf( cn, "%-15s %-10s %-15s %3i %3i %3i %5i %4i %3d %3d\n",
+ orig_node->orig_str, lndev->bif->dev,
+ orig_node->primary_orig_node ? orig_node->primary_orig_node->orig_str : "???",
+ rtq/PROBE_TO100, rq/PROBE_TO100, tq/PROBE_TO100,
+ // accepted and rebroadcasted:
+ // orig_node->router->accepted_sqr.wa_val/PROBE_TO100,
+ // estimated_rcvd > 100 ? 100 : estimated_rcvd,
+ // get_human_uptime( orig_node->first_valid_sec ),
orig_node->last_valid_sqn,
- ( batman_time - orig_node->last_valid_time)/1000,
+// ( batman_time - orig_node->last_valid_time)/1000,
+ ( batman_time - lndev->last_lndev)/1000,
( orig_node->primary_orig_node ?
orig_node->primary_orig_node->id4me : -1 ),
( orig_node->primary_orig_node ?
- orig_node->primary_orig_node->id4him : -1 ),
- lndev->bif->dev,
- rtq/PROBE_TO100, rq/PROBE_TO100, tq/PROBE_TO100 );
+ orig_node->primary_orig_node->id4him : -1 )
+ );
}
@@ -1615,35 +1681,38 @@
ipStr( primary_addr ),
get_human_uptime( 0 ) );
-
- while ( (hashit = hash_iterate( orig_hash, hashit )) ) {
-
- orig_node = hashit->bucket->data;
-
+ uint32_t orig_ip = 0;
+
+ while ((orig_node = (struct orig_node*) avl_next(&orig_avl, &orig_ip))) {
+
+ orig_ip = orig_node->orig;
+
if ( !orig_node->router || orig_node->primary_orig_node != orig_node )
continue;
- struct orig_node *onn = get_orig_node( orig_node->router->addr, NO/*create*/ );
+/*
+ struct orig_node *onn = get_orig_node( orig_node->router->addr, NO );
if ( !onn || !onn->last_valid_time || !onn->router )
continue;
+*/
dbg_ogm_out = snprintf( dbg_ogm_str, MAX_DBG_STR_SIZE, "%-15s (%3i) %15s [%10s] ",
orig_node->orig_str,
- orig_node->router->accepted_sqr.wa_val/PROBE_TO100,
- ipStr( orig_node->router->addr ),
- orig_node->router->iif->dev );
+ orig_node->router->longtm_sqr.wa_val/PROBE_TO100,
+ ipStr( orig_node->router->nnkey_addr ),
+ orig_node->router->nnkey_iif->dev );
list_for_each( neigh_pos, &orig_node->neigh_list ) {
neigh_node = list_entry( neigh_pos, struct neigh_node, list );
- if( neigh_node->addr != orig_node->router->addr ) {
+ if( neigh_node->nnkey_addr != orig_node->router->nnkey_addr ) {
dbg_ogm_out = dbg_ogm_out +
snprintf( (dbg_ogm_str + dbg_ogm_out), (MAX_DBG_STR_SIZE - dbg_ogm_out),
" %15s (%3i)",
- ipStr( neigh_node->addr ),
- neigh_node->accepted_sqr.wa_val/PROBE_TO100 );
+ ipStr( neigh_node->nnkey_addr ),
+ neigh_node->longtm_sqr.wa_val/PROBE_TO100 );
}
}
@@ -1663,7 +1732,8 @@
-static int32_t opt_dev_show ( uint8_t cmd, uint8_t _save, struct opt_type *opt, struct opt_parent *patch, struct ctrl_node *cn ) {
+static
+int32_t opt_dev_show ( uint8_t cmd, uint8_t _save, struct opt_type *opt, struct opt_parent *patch, struct ctrl_node *cn ) {
struct list_head *pos;
@@ -1672,9 +1742,10 @@
list_for_each( pos, &if_list ) {
struct batman_if *bif = list_entry( pos, struct batman_if, list );
-
- dbg_cn( cn, DBGL_ALL, DBGT_NONE, "%-10s %8s %15s/%-2d brc %-15s SQN %5d TTL %2d %11s %8s %11s",
+
+ dbg_cn( cn, DBGL_ALL, DBGT_NONE, "%-10s %5d %8s %15s/%-2d brc %-15s SQN %5d TTL %2d %11s %8s %11s",
bif->dev,
+ bif->if_index,
!bif->if_active ? "-" :
( bif->if_linklayer == VAL_DEV_LL_LO ? "loopback":
( bif->if_linklayer == VAL_DEV_LL_LAN ? "ethernet":
@@ -1683,7 +1754,7 @@
bif->if_prefix_length,
ipStr(bif->if_broad),
bif->if_seqno,
- bif->own_ogm_out ? bif->own_ogm_out->ogm_ttl : -1,
+ bif->if_ttl,
bif->if_singlehomed ? "singlehomed" : "multihomed",
bif->if_active ? "active" : "inactive",
bif == primary_if ? "primary" : "non-primary"
@@ -1694,7 +1765,8 @@
return SUCCESS;
}
-static int32_t opt_dev ( uint8_t cmd, uint8_t _save, struct opt_type *opt, struct opt_parent *patch, struct ctrl_node *cn ) {
+static
+int32_t opt_dev ( uint8_t cmd, uint8_t _save, struct opt_type *opt, struct opt_parent *patch, struct ctrl_node *cn ) {
struct list_head *list_pos, *list_tmp, *list_prev;
struct batman_if *bif = NULL;
@@ -1741,9 +1813,9 @@
remove_outstanding_ogms( bif );
list_del( list_prev, list_pos, &if_list );
+
+ debugFree(bif, 1214);
- debugFree( list_pos, 1214 );
-
return SUCCESS;
@@ -1756,18 +1828,27 @@
if ( !bif ) {
- if ( cmd == OPT_APPLY )
- bif = debugMalloc( sizeof(struct batman_if), 206 );
- else
+ if ( cmd == OPT_APPLY ) {
+
+ bif = debugMalloc( sizeof(struct batman_if), 206 );
+ memset(bif, 0, sizeof (struct batman_if));
+
+ INIT_LIST_HEAD(&bif->list);
+
+ if ( list_empty( &if_list ) )
+ primary_if = bif;
+
+ list_add_tail( &bif->list, &if_list );
+
+ } else {
+
bif = &test_bif;
-
-
- memset( bif, 0, sizeof(struct batman_if) );
- INIT_LIST_HEAD( &bif->list );
-
- bif->own_send_node = (struct send_node*)&(bif->own_send_buff[0]);
- bif->own_ogm_out = (struct bat_packet_ogm*)&(bif->own_send_node->ogm_buff[0]);
-
+ memset(bif, 0, sizeof (struct batman_if));
+
+ }
+
+ bif->aggregation_out = bif->aggregation_out_buff;
+
snprintf( bif->dev, wordlen(patch->p_val)+1, "%s", patch->p_val );
snprintf( bif->dev_phy, wordlen(patch->p_val)+1, "%s", patch->p_val );
@@ -1779,13 +1860,8 @@
bif->if_seqno_schedule = batman_time;
- bif->own_ogm_out->ext_msg = NO;
- bif->own_ogm_out->bat_type = BAT_TYPE_OGM;
+ bif->if_seqno = (primary_if && primary_if != bif) ? primary_if->if_seqno : my_seqno;
- bif->own_ogm_out->ogx_flag = NO;
-
- bif->if_seqno = primary_if ? primary_if->if_seqno : my_seqno;
-
bif->aggregation_len = sizeof( struct bat_header );
@@ -1795,16 +1871,7 @@
bif->if_ant_diversity_conf = -1;
bif->if_linklayer_conf = -1;
bif->if_singlehomed_conf = -1;
-
-
- if ( cmd == OPT_APPLY ) {
-
- if ( list_empty( &if_list ) )
- primary_if = bif;
-
- list_add_tail( &bif->list, &if_list );
- }
-
+
}
if ( cmd == OPT_CHECK )
@@ -1846,12 +1913,11 @@
} else if ( cmd == OPT_POST && opt && !opt->parent_name ) {
check_interfaces(); //will always be called whenever a parameter is changed (due to OPT_POST)
-
+ /*
if ( !on_the_fly ) {
// add rule for hosts and announced interfaces and networks
if ( prio_rules ) {
- add_del_rule( 0, 0, RT_TABLE_INTERFACES, RT_PRIO_INTERFACES, 0, RTA_DST, ADD, TRACK_STANDARD );
add_del_rule( 0, 0, RT_TABLE_HOSTS, RT_PRIO_HOSTS, 0, RTA_DST, ADD, TRACK_STANDARD );
add_del_rule( 0, 0, RT_TABLE_NETWORKS, RT_PRIO_NETWORKS, 0, RTA_DST, ADD, TRACK_STANDARD );
}
@@ -1861,6 +1927,7 @@
cleanup_all( CLEANUP_FAILURE );
}
+ */
}
return SUCCESS;
@@ -1944,7 +2011,8 @@
{ODI,5,0,ARG_DEV, 0, A_PMN,A_ADM,A_DYI,A_CFA,A_ANY, 0, 0, 0, 0, opt_dev,
"<interface-name>", "add or change device or its configuration, options for specified device are:"},
-
+
+#ifndef LESS_OPTIONS
{ODI,5,ARG_DEV,ARG_DEV_TTL, 't',A_CS1,A_ADM,A_DYI,A_CFA,A_ANY, 0, MIN_TTL, MAX_TTL, DEF_TTL, opt_dev,
ARG_VALUE_FORM, "set TTL of generated OGMs"},
@@ -1961,61 +2029,87 @@
ARG_VALUE_FORM, 0/*"set number of broadcast antennas (e.g. for antenna-diversity use /d=2 /c=400 aggreg_interval=100)"*/},
+ {ODI,5,ARG_DEV,ARG_DEV_HIDE, 'h',A_CS1,A_ADM,A_DYI,A_CFA,A_ANY, 0, 0, 1, 0, opt_dev,
+ ARG_VALUE_FORM, "disable/enable hiding of OGMs generated to non link-neighboring nodes. Default for non-primary interfaces"},
+#endif
+
{ODI,5,ARG_DEV,ARG_DEV_LL, 'l',A_CS1,A_ADM,A_DYI,A_CFA,A_ANY, 0, VAL_DEV_LL_LAN, VAL_DEV_LL_WLAN,0, opt_dev,
ARG_VALUE_FORM, "manually set device type for linklayer specific optimization (1=lan, 2=wlan)"},
- {ODI,5,ARG_DEV,ARG_DEV_HIDE, 'h',A_CS1,A_ADM,A_DYI,A_CFA,A_ANY, 0, 0, 1, 0, opt_dev,
- ARG_VALUE_FORM, "disable/enable hiding of OGMs generated to non link-neighboring nodes. Default for non-primary interfaces"},
-
{ODI,5,0,ARG_INTERFACES, 0, A_PS0,A_USR,A_DYI,A_ARG,A_ANY, 0, 0, 1, 0, opt_dev_show,
0, "show configured interfaces"},
- {ODI,5,0,ARG_OGI_INTERVAL, 'o',A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &my_ogi, MIN_OGI, MAX_OGI, DEF_OGI, 0,
- ARG_VALUE_FORM, "set interval in ms with which new originator message (OGM) are send"},
-
- {ODI,5,0,"path_window_size", 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &my_pws, MIN_PWS, MAX_PWS, DEF_PWS, opt_if_soft,
+ {ODI,5,0,ARG_LWS, 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &local_lws, MIN_LWS, MAX_LWS, DEF_LWS, opt_lws,
+ ARG_VALUE_FORM, "set link window size (LWS) for link-quality calculation (link metric)"},
+
+#ifndef LESS_OPTIONS
+
+ {ODI,5,0,ARG_RTQ_LOUNGE, 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &local_rtq_lounge,MIN_RTQ_LOUNGE,MAX_RTQ_LOUNGE,DEF_RTQ_LOUNGE, opt_lws,
+ ARG_VALUE_FORM, "set local LLS buffer size to artificially delay OGM processing for ordered link-quality calulation"},
+
+ {ODI,5,0,ARG_PWS, 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &my_pws, MIN_PWS, MAX_PWS, DEF_PWS, opt_if_soft,
ARG_VALUE_FORM, "set path window size (PWS) for end2end path-quality calculation (path metric)"},
-
- {ODI,5,0,"link_window_size", 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &my_lws, MIN_LWS, MAX_LWS, DEF_LWS, opt_lws,
- ARG_VALUE_FORM, "set link window size (LWS) for link-quality calculation (link metric)"},
-
- {ODI,5,0,"path_hysteresis", 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &path_hystere, MIN_PATH_HYST, MAX_PATH_HYST, DEF_PATH_HYST, 0,
+
+ {ODI,5,0,ARG_PATH_LOUNGE, 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &my_path_lounge,MIN_PATH_LOUNGE,MAX_PATH_LOUNGE,DEF_PATH_LOUNGE,opt_purge,
+ ARG_VALUE_FORM, "set default PLS buffer size to artificially delay my OGM processing for ordered path-quality calulation"},
+
+ {ODI,5,0,ARG_PATH_HYST, 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &my_path_hystere,MIN_PATH_HYST, MAX_PATH_HYST, DEF_PATH_HYST, opt_purge,
ARG_VALUE_FORM, "use hysteresis to delay route switching to alternative next-hop neighbors with better path metric"},
-
- {ODI,5,0,"purge_timeout", 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &purge_to, MIN_PURGE_TO, MAX_PURGE_TO, DEF_PURGE_TO, 0,
+
+
+ {ODI,5,0,ARG_RCNT_PWS, 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &my_rcnt_pws, MIN_RCNT_PWS, MAX_RCNT_PWS, DEF_RCNT_PWS, opt_purge,
+ ARG_VALUE_FORM, ""},
+
+/*
+ {ODI,5,0,ARG_RCNT_LOUNGE, 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &my_rcnt_lounge,MIN_RCNT_LOUNGE,MAX_RCNT_LOUNGE,DEF_RCNT_LOUNGE,opt_purge,
+ ARG_VALUE_FORM, ""},
+*/
+
+ {ODI,5,0,ARG_RCNT_HYST, 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &my_rcnt_hystere,MIN_RCNT_HYST, MAX_RCNT_HYST, DEF_RCNT_HYST, opt_purge,
+ ARG_VALUE_FORM, "use hysteresis to delay fast-route switching to alternative next-hop neighbors with a recently extremely better path metric"},
+
+ {ODI,5,0,ARG_RCNT_FK, 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &my_rcnt_fk, MIN_RCNT_FK, MAX_RCNT_FK, DEF_RCNT_FK, opt_purge,
+ ARG_VALUE_FORM, "configure threshold faktor for dead-path detection"},
+
+
+ {ODI,5,0,ARG_DROP_2HLOOP, 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &drop_2hop_loop,MIN_DROP_2HLOOP,MAX_DROP_2HLOOP,DEF_DROP_2HLOOP,0,
+ ARG_VALUE_FORM, "drop OGMs received via two-hop loops"},
+
+
+ {ODI,5,0,ARG_ASYM_EXP, 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &my_asym_exp, MIN_ASYM_EXP, MAX_ASYM_EXP, DEF_ASYM_EXP, 0,
+ ARG_VALUE_FORM, "ignore OGMs (rcvd via asymmetric links) with TQ^<val> to radically reflect asymmetric-links"},
+
+ {ODI,5,0,"asocial_device", 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &Asocial_device,MIN_ASOCIAL, MAX_ASOCIAL, DEF_ASOCIAL, 0,
+ ARG_VALUE_FORM, "disable/enable asocial mode for devices unwilling to forward other nodes' traffic"},
+
+ {ODI,5,0,ARG_WL_CLONES, 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &wl_clones, MIN_WL_CLONES, MAX_WL_CLONES, DEF_WL_CLONES, opt_if_soft,
+ ARG_VALUE_FORM, "broadcast OGMs per ogm-interval for wireless devices with\n"
+ " given probability [%] (eg 200% will broadcast the same OGM twice)"},
+
+ {ODI,5,0,ARG_ASYM_WEIGHT, 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &my_asym_weight, MIN_ASYM_WEIGHT,MAX_ASYM_WEIGHT,DEF_ASYM_WEIGHT,0,
+ ARG_VALUE_FORM, "ignore OGMs (rcvd via asymmetric links) with given probability [%] to better reflect asymmetric-links"},
+
+ {ODI,5,0,ARG_HOP_PENALTY, 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &my_hop_penalty, MIN_HOP_PENALTY,MAX_HOP_PENALTY,DEF_HOP_PENALTY,0,
+ ARG_VALUE_FORM, "ignore OGMs with given probability [%] to better reflect path-hop distance"},
+
+ // there SHOULD! be a minimal lateness_penalty >= 1 ! Otherwise a shorter path with equal path-cost than a longer path will never dominate
+ {ODI,5,0,ARG_LATE_PENAL, 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &my_late_penalty,MIN_LATE_PENAL,MAX_LATE_PENAL, DEF_LATE_PENAL, opt_purge,
+ ARG_VALUE_FORM, "penalize non-first rcvd OGMs "},
+
+ {ODI,5,0,ARG_PURGE_TO, 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &purge_to, MIN_PURGE_TO, MAX_PURGE_TO, DEF_PURGE_TO, 0,
ARG_VALUE_FORM, "timeout in seconds for purging stale originators"},
-
- {ODI,5,0,"dad_timeout", 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &dad_to, MIN_DAD_TO, MAX_DAD_TO, DEF_DAD_TO, 0,
+
+#endif
+ {ODI,5,0,ARG_DAD_TO, 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &dad_to, MIN_DAD_TO, MAX_DAD_TO, DEF_DAD_TO, 0,
ARG_VALUE_FORM, "duplicate address (DAD) detection timout in seconds"},
-
+
{ODI,5,0,"seqno", 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &my_seqno, MIN_SEQNO, MAX_SEQNO, DEF_SEQNO, opt_seqno,0,0},
-
- {ODI,5,0,ARG_WL_CLONES, 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &wl_clones, 0, 400, 200, opt_if_soft,
- ARG_VALUE_FORM, "broadcast OGMs per ogm-interval for wireless devices with\n"
- " given probability [%] (eg 200% will broadcast the same OGM twice)"},
-
- {ODI,5,0,ARG_ASYM_WEIGHT, 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &asym_weight, MIN_ASYM_WEIGHT,MAX_ASYM_WEIGHT,DEF_ASYM_WEIGHT,0,
- ARG_VALUE_FORM, "ignore OGMs (rcvd via asymmetric links) with given probability [%] to better reflect asymmetric-links"},
-
- {ODI,5,0,"lateness_penalty", 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &lateness_penalty,0, 100, 2 ,0,
- ARG_VALUE_FORM, "penalize non-firsr rcvd OGMs "},
-
- {ODI,5,0,"link_lounge_size", 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &my_link_lounge,MIN_LOUNGE_SIZE,3, 1, 0,
- ARG_VALUE_FORM, "set local LLS buffer size to artificially delay OGM processing for ordered link-quality calulation"},
-
- {ODI,5,0,"path_lounge_size", 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &Default_lounge,MIN_LOUNGE_SIZE,MAX_LOUNGE_SIZE,1, 0,
- ARG_VALUE_FORM, "set default PLS buffer size to artificially delay OGM processing for ordered path-quality calulation"},
-
+
+
{ODI,5,0,"ttl", 't',A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &Ttl, MIN_TTL, MAX_TTL, DEF_TTL, opt_if_soft,
ARG_VALUE_FORM, "set time-to-live (TTL) for OGMs of primary interface"},
- {ODI,5,0,ARG_ASYM_EXP, 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &asym_exp, MIN_ASYM_EXP, MAX_ASYM_EXP, DEF_ASYM_EXP, 0,
- ARG_VALUE_FORM, "ignore OGMs (rcvd via asymmetric links) with TQ^<val> to radically reflect asymmetric-links"},
- {ODI,5,0,"asocial_device", 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &Asocial_device,NO, YES, NO, 0,
- ARG_VALUE_FORM, "disable/enable asocial mode for devices unwilling to forward other nodes' traffic"},
-
-
{ODI,5,0,"flush_all", 0, A_PS0,A_ADM,A_DYN,A_ARG,A_ANY, 0, 0, 0, 0, opt_purge,
0, "purge all neighbors and routes on the fly"}
};
Modified: trunk/batman-experimental/originator.h
===================================================================
--- trunk/batman-experimental/originator.h 2010-04-12 19:06:37 UTC (rev 1633)
+++ trunk/batman-experimental/originator.h 2010-04-15 08:16:16 UTC (rev 1634)
@@ -17,60 +17,108 @@
*
*/
+#define WA_SCALE_FACTOR 1000 /* scale factor used to increase precision of integer division */
+#define PROBE_TO100 1
+#define PROBE_RANGE 100
+
#define MIN_SEQNO 0
#define DEF_SEQNO 0 /* causes seqno to be randomized */
#define MAX_SEQNO ((uint16_t)-1)
-extern int32_t my_pws; // my path window size used to quantify the end to end path quality between me and other nodes
#define MAX_PWS 250 /* TBD: should not be larger until ogm->ws and neigh_node.packet_count (and related variables) is only 8 bit */
-#define MIN_PWS 1
+#define MIN_PWS 10
#define DEF_PWS 100 /* NBRF: NeighBor Ranking sequence Frame) sliding packet range of received orginator messages in squence numbers (should be a multiple of our word size) */
+#define ARG_PWS "path_window_size"
+extern int32_t my_pws; // my path window size used to quantify the end to end path quality between me and other nodes
-extern int32_t my_lws; // my link window size used to quantify the link qualities to direct neighbors
-#define DEF_LWS 100
+
+#define DEF_LWS 20
#define MAX_LWS 250
#define MIN_LWS 1
+#define ARG_LWS "link_window_size"
+extern int32_t local_lws; // my link window size used to quantify the link qualities to direct neighbors
-#define ARG_OGI_INTERVAL "ogm_interval"
-extern int32_t my_ogi; // my originator interval
-#define DEF_OGI 1000
-#define MIN_OGI 200
-#define MAX_OGI 10000
-extern int32_t my_link_lounge;
-extern int32_t Default_lounge;
+// the default link_lounge_size of 2 is good to compensate for ogi ~ but <= aggreg_interval
+#define MIN_RTQ_LOUNGE 0
+#define MAX_RTQ_LOUNGE 10
+#define DEF_RTQ_LOUNGE 2
+#define ARG_RTQ_LOUNGE "link_lounge_size"
+extern int32_t local_rtq_lounge;
-#define MIN_LOUNGE_SIZE 0
-#define MAX_LOUNGE_SIZE (SQN_LOUNGE_SIZE-1)
+#define RQ_LINK_LOUNGE 0 /* may also be rtq_link_lounge */
-//#define PURGE_SAFETY_PERIOD 25000 //25000
-//#define PURGE_TIMEOUT ((MAX_OGI*MAX_PWS) + PURGE_SAFETY_PERIOD) /* 10 minutes + safety_period */
-//extern int32_t purge_to
-#define DEF_PURGE_TO 100000
+#define MIN_PATH_LOUNGE 0
+#define MAX_PATH_LOUNGE (SQN_LOUNGE_SIZE-1)
+#define DEF_PATH_LOUNGE 8
+#define ARG_PATH_LOUNGE "path_lounge_size"
+extern int32_t my_path_lounge;
+
+
+#define MIN_PATH_HYST 0
+#define MAX_PATH_HYST (PROBE_RANGE/PROBE_TO100)/2
+#define DEF_PATH_HYST 0
+#define ARG_PATH_HYST "path_hysteresis"
+
+#define MIN_RCNT_HYST 0
+#define MAX_RCNT_HYST (PROBE_RANGE/PROBE_TO100)/2
+#define DEF_RCNT_HYST 1
+#define ARG_RCNT_HYST "fast_path_hysteresis"
+
+#define DEF_RCNT_PWS 20
+#define MIN_RCNT_PWS 2
+#define MAX_RCNT_PWS MAX_PWS
+#define ARG_RCNT_PWS "fast_path_window_size"
+
+#define DEF_RCNT_LOUNGE DEF_PATH_LOUNGE
+#define MIN_RCNT_LOUNGE MIN_PATH_LOUNGE
+#define MAX_RCNT_LOUNGE MAX_PATH_LOUNGE
+#define ARG_RCNT_LOUNGE "fast_path_lounge_size"
+
+#define DEF_RCNT_FK 150
+#define MIN_RCNT_FK 100
+#define MAX_RCNT_FK 1000
+#define ARG_RCNT_FK "fast_path_faktor"
+
+#define MIN_LATE_PENAL 0
+#define MAX_LATE_PENAL 100
+#define DEF_LATE_PENAL 1
+#define ARG_LATE_PENAL "lateness_penalty"
+
+#define MIN_DROP_2HLOOP NO
+#define MAX_DROP_2HLOOP YES
+#define DEF_DROP_2HLOOP NO
+#define ARG_DROP_2HLOOP "drop_two_hop_loops"
+
+#define DEF_PURGE_TO 100
#define MIN_PURGE_TO 10
#define MAX_PURGE_TO 864000 /*10 days*/
+#define ARG_PURGE_TO "purge_timeout"
+// extern int32_t purge_to;
-//extern int32_t dad_to;
#define DEF_DAD_TO 100
#define MIN_DAD_TO 1
#define MAX_DAD_TO 3600
-//#define DEF_DAD_TO 100
-//#define MIN_DAD_TO 10 /* if this is changed, be careful with PURGE_TIMEOUT */
-//#define MAX_DAD_TO (PURGE_TIMEOUT/2)
+#define ARG_DAD_TO "dad_timeout"
+extern int32_t dad_to;
-extern int32_t Ttl;
+#define MIN_ASOCIAL NO
+#define MAX_ASOCIAL YES
+#define DEF_ASOCIAL NO
+
#define DEF_TTL 50 /* Time To Live of OGM broadcast messages */
#define MAX_TTL 63
#define MIN_TTL 1
+extern int32_t Ttl;
-#define ARG_WL_CLONES "ogm_broadcasts"
-extern int32_t wl_clones;
#define DEF_WL_CLONES 200
#define MIN_WL_CLONES 0
#define MAX_WL_CLONES 400
+#define ARG_WL_CLONES "ogm_broadcasts"
+extern int32_t wl_clones;
#define DEF_LAN_CLONES 100
@@ -80,30 +128,31 @@
#define MAX_ASYM_WEIGHT 100
#define ARG_ASYM_WEIGHT "asymmetric_weight"
+#define DEF_HOP_PENALTY 1
+#define MIN_HOP_PENALTY 0
+#define MAX_HOP_PENALTY 100
+#define ARG_HOP_PENALTY "hop_penalty"
+
+
#define DEF_ASYM_EXP 1
#define MIN_ASYM_EXP 0
#define MAX_ASYM_EXP 3
#define ARG_ASYM_EXP "asymmetric_exp"
-#define WA_SCALE_FACTOR 1000 /* scale factor used to increase precision of integer division */
-#define PROBE_TO100 1
-#define PROBE_RANGE 100
-
-#define MIN_PATH_HYST 0
-#define MAX_PATH_HYST (PROBE_RANGE/PROBE_TO100)/2
-#define DEF_PATH_HYST 0
-
-
extern struct batman_if *primary_if;
extern uint32_t primary_addr;
-extern struct hashtable_t *orig_hash;
+//extern struct hashtable_t *orig_hash;
+extern struct avl_tree orig_avl;
+
extern struct list_head_first if_list;
extern struct list_head_first link_list;
+extern struct avl_tree link_avl;
+
struct orig_node *get_orig_node( uint32_t addr, uint8_t create );
int tq_rate( struct orig_node *orig_node_neigh, struct batman_if *iif, int range );
Modified: trunk/batman-experimental/os.h
===================================================================
--- trunk/batman-experimental/os.h 2010-04-12 19:06:37 UTC (rev 1633)
+++ trunk/batman-experimental/os.h 2010-04-15 08:16:16 UTC (rev 1634)
@@ -21,14 +21,6 @@
#define _BATMAN_OS_H
-/* get_time functions MUST be called at least every 2*MAX_SELECT_TIMEOUT_MS to allow for properly working time-drift checks */
-
-/* overlaps after approximately 138 years */
-//#define get_time_sec() get_time( NO, NULL )
-
-/* overlaps after 49 days, 17 hours, 2 minutes, and 48 seconds */
-//#define get_time_msec() get_time( YES, NULL )
-
# define timercpy(d, a) (d)->tv_sec = (a)->tv_sec; (d)->tv_usec = (a)->tv_usec;
@@ -51,6 +43,20 @@
void cleanup_all( int status );
+/*
+ * PARANOIA ERROR CODES:
+ * Negative numbers are used as SIGSEV error codes !
+ * Currently used numbers are
+ * for core programs: -500000 ... -500198
+ */
+#ifdef NOPARANOIA
+#define paranoia( ... )
+#else
+#define paranoia( code , problem ); do { if ( problem ) { cleanup_all( code ); } }while(0)
+#endif
+
+
+
void update_batman_time( struct timeval *precise_tv );
char *get_human_uptime( uint32_t reference );
@@ -95,9 +101,8 @@
*
* Things you should leave as is unless your know what you are doing !
*
- * RT_TABLE_INTERFACES routing table for announced (non-primary) interfaces IPs and other unique IP addresses
- * RT_TABLE_NETWORKS routing table for announced networks
* RT_TABLE_HOSTS routing table for routes towards originators
+ * RT_TABLE_NETWORKS routing table for announced networks
* RT_TABLE_TUNNEL routing table for the tunnel towards the internet gateway
* RT_PRIO_DEFAULT standard priority for routing rules
* RT_PRIO_UNREACH standard priority for unreachable rules
@@ -105,82 +110,41 @@
*
***/
+#define RT_TABLE_HOSTS -1
+#define RT_TABLE_NETWORKS -2
+#define RT_TABLE_TUNNEL -3
-extern int32_t Rt_table;
-#define ARG_RT_TABLE "rt_table_offset"
-#define DEF_RT_TABLE 64
-#define MIN_RT_TABLE 2
-#define MAX_RT_TABLE 240
-#define RT_TABLE_INTERFACES (Rt_table + 0)
-#define RT_TABLE_NETWORKS (Rt_table + 1)
-#define RT_TABLE_HOSTS (Rt_table + 2)
-#define RT_TABLE_TUNNEL (Rt_table + 4)
-
-
-extern int32_t Rt_prio;
-#define ARG_RT_PRIO "prio_rules_offset"
-#define MIN_RT_PRIO 3
-#define MAX_RT_PRIO 32765
-#define DEF_RT_PRIO 6500
-
-#define RT_PRIO_INTERFACES (Rt_prio + 0 )
-#define RT_PRIO_HOSTS (Rt_prio + 100)
-#define RT_PRIO_NETWORKS (Rt_prio + 199)
-#define RT_PRIO_TUNNEL (Rt_prio + 300)
-
-
-extern int32_t prio_rules;
-#define ARG_PRIO_RULES "prio_rules"
-
-
-#define ARG_THROW_RULES "throw_rules"
-
-#define ARG_NO_POLICY_RT "no_policy_routing"
-
-#define ARG_PEDANTIC_CLEANUP "pedantic_cleanup"
-
-
-
extern uint8_t if_conf_soft_changed; // temporary enabled to trigger changed interface configuration
extern uint8_t if_conf_hard_changed; // temporary enabled to trigger changed interface configuration
extern int Mtu_min;
-struct rules_node {
+struct routes_node {
struct list_head list;
- uint32_t network;
- uint8_t netmask;
- uint8_t rt_table;
- uint32_t prio;
- char *iif;
- int8_t rule_t;
+ uint32_t dest;
+ uint16_t netmask;
+ uint16_t rt_table;
+ int16_t rta_type;
int8_t track_t;
};
-
-struct routes_node {
+
+struct rules_node {
struct list_head list;
- uint32_t dest;
- uint8_t netmask;
- uint8_t rt_table;
- int8_t route_t;
+ uint32_t prio;
+ char *iif;
+ uint32_t network;
+ int16_t netmask;
+ int16_t rt_table;
+ int16_t rta_type;
int8_t track_t;
};
-/***
- *
- * route types: 0 = RTN_UNICAST, 1 = THROW, 2 = UNREACHABLE
- *
- ***/
-#define RT_UNICAST 0
-#define RT_THROW 1
-#define RT_UNREACH 2
-
//track types:
enum {
TRACK_NO,
@@ -192,7 +156,8 @@
TRACK_TUNNEL
};
-void add_del_route( uint32_t dest, uint8_t netmask, uint32_t router, uint32_t source, int32_t ifi, char *dev, uint8_t rt_table, int8_t route_type, int8_t del, int8_t track );
+void add_del_route( uint32_t dest, int16_t mask, uint32_t gw, uint32_t src, int32_t ifi, char *dev,
+ int16_t rt_table_macro, int16_t rta_type, int8_t del, int8_t track_t );
/***
*
@@ -203,7 +168,7 @@
*
***/
-void add_del_rule( uint32_t network, uint8_t netmask, uint8_t rt_table, uint32_t prio, char *iif, int8_t rule_type, int8_t del, int8_t track );
+// void add_del_rule( uint32_t network, uint8_t netmask, int16_t rt_macro, uint32_t prio, char *iif, int8_t rule_type, int8_t del, int8_t track_t );
enum {
IF_RULE_SET_TUNNEL,
@@ -245,167 +210,6 @@
#define ARG_GW_CLASS "gateway_class"
#ifndef NOTUNNEL
-
-
-#define ARG_UNRESP_GW_CHK "unresp_gateway_check"
-
-#define ARG_TWO_WAY_TUNNEL "two_way_tunnel"
-
-#define ARG_ONE_WAY_TUNNEL "one_way_tunnel"
-
-#define ARG_GW_HYSTERESIS "gateway_hysteresis"
-#define MIN_GW_HYSTERE 1
-#define MAX_GW_HYSTERE PROBE_RANGE/PROBE_TO100
-#define DEF_GW_HYSTERE 2
-
-
-#define BATMAN_TUN_PREFIX "bat"
-#define MAX_BATMAN_TUN_INDEX 20
-
-#define TUNNEL_DATA 0x01
-#define TUNNEL_IP_REQUEST 0x02
-#define TUNNEL_IP_INVALID 0x03
-#define TUNNEL_IP_REPLY 0x06
-
-#define GW_STATE_UNKNOWN 0x01
-#define GW_STATE_VERIFIED 0x02
-
-#define ONE_MINUTE 60000
-
-#define GW_STATE_UNKNOWN_TIMEOUT (1 * ONE_MINUTE)
-#define GW_STATE_VERIFIED_TIMEOUT (5 * ONE_MINUTE)
-
-#define IP_LEASE_TIMEOUT (1 * ONE_MINUTE)
-
-#define MAX_TUNNEL_IP_REQUESTS 60 //12
-#define TUNNEL_IP_REQUEST_TIMEOUT 1000 // msec
-
-
-struct tun_request_type {
- uint32_t lease_ip;
- uint16_t lease_lt;
-} __attribute__((packed));
-
-struct tun_data_type {
- unsigned char ip_packet[MAX_MTU];
-} __attribute__((packed));
-
-struct tun_packet_start {
-#if __BYTE_ORDER == __LITTLE_ENDIAN
- unsigned int type:4;
- unsigned int version:4; // should be the first field in the packet in network byte order
-#elif __BYTE_ORDER == __BIG_ENDIAN
- unsigned int version:4;
- unsigned int type:4;
-#else
-# error "Please fix <bits/endian.h>"
-#endif
-} __attribute__((packed));
-
-struct tun_packet
-{
- uint8_t reserved1;
- uint8_t reserved2;
- uint8_t reserved3;
-
- struct tun_packet_start start;
-#define TP_TYPE start.type
-#define TP_VERS start.version
-
- union
- {
- struct tun_request_type trt;
- struct tun_data_type tdt;
- }tt;
-#define LEASE_IP tt.trt.lease_ip
-#define LEASE_LT tt.trt.lease_lt
-#define IP_PACKET tt.tdt.ip_packet
-} __attribute__((packed));
-
-
-#define TX_RP_SIZE (sizeof(struct tun_packet_start) + sizeof(struct tun_request_type))
-#define TX_DP_SIZE (sizeof(struct tun_packet_start) + sizeof(struct tun_data_type))
-
-
-struct gwc_args {
- uint32_t gw_state_stamp;
- uint8_t gw_state;
- uint8_t prev_gw_state;
- uint32_t orig;
- struct gw_node *gw_node; // pointer to gw node
- struct sockaddr_in gw_addr; // gateway ip
- char gw_str[ADDR_STR_LEN]; // string of gateway ip
- struct sockaddr_in my_addr; // primary_ip
- uint32_t my_tun_addr; // ip used for bat0 tunnel interface
- char my_tun_str[ADDR_STR_LEN]; // string of my_tun_addr
- int32_t mtu_min;
- uint8_t tunnel_type;
- int32_t udp_sock;
- int32_t tun_fd;
- int32_t tun_ifi;
- char tun_dev[IFNAMSIZ]; // was tun_if
- uint32_t tun_ip_request_stamp;
- uint32_t tun_ip_lease_stamp;
- uint32_t tun_ip_lease_duration;
- uint32_t send_tun_ip_requests;
- uint32_t pref_addr;
- // uint32_t last_invalidip_warning;
-};
-
-
-struct gws_args
-{
- int8_t netmask;
- int32_t port;
- int32_t owt;
- int32_t twt;
- int32_t lease_time;
- int mtu_min;
- uint32_t my_tun_ip;
- uint32_t my_tun_netmask;
- uint32_t my_tun_ip_h;
- uint32_t my_tun_suffix_mask_h;
- struct sockaddr_in client_addr;
- struct gw_client **gw_client_list;
- int32_t sock;
- int32_t tun_fd;
- int32_t tun_ifi;
- char tun_dev[IFNAMSIZ];
-};
-
-
-#define DEF_GWTUN_NETW_PREFIX "169.254.0.0" /* 0x0000FEA9 */
-
-#define MIN_GWTUN_NETW_MASK 20
-#define MAX_GWTUN_NETW_MASK 30
-#define DEF_GWTUN_NETW_MASK 22
-
-#define MIN_TUN_LTIME 60 /*seconds*/
-#define MAX_TUN_LTIME 60000
-#define DEF_TUN_LTIME 600
-#define ARG_TUN_LTIME "tunnel_lease_time"
-
-
-#define MIN_RT_CLASS 0
-#define MAX_RT_CLASS 3
-
-// field accessor and flags for gateway announcement extension packets
-#define EXT_GW_FIELD_GWTYPES ext_related
-#define EXT_GW_FIELD_GWFLAGS def8
-#define EXT_GW_FIELD_GWPORT d16.def16
-#define EXT_GW_FIELD_GWADDR d32.def32
-
-// the flags for gw extension messsage gwtypes:
-#define TWO_WAY_TUNNEL_FLAG 0x01
-#define ONE_WAY_TUNNEL_FLAG 0x02
-
-struct tun_orig_data {
-
- int16_t tun_array_len;
- struct ext_packet tun_array[];
-
-};
-
struct plugin_v1 *tun_get_plugin_v1( void );
#endif
Modified: trunk/batman-experimental/plugin.c
===================================================================
--- trunk/batman-experimental/plugin.c 2010-04-12 19:06:37 UTC (rev 1633)
+++ trunk/batman-experimental/plugin.c 2010-04-15 08:16:16 UTC (rev 1634)
@@ -336,9 +336,6 @@
pn->plugin = p;
pn->dlhandle = dlhandle;
- if ( pn->plugin_v1 )
- Link_flags |= pn->plugin_v1->link_flags;
-
list_add_tail( &pn->list, &plugin_list );
dbgf_all( DBGT_INFO, "%s SUCCESS", pn->plugin_v1->plugin_name );
@@ -359,15 +356,13 @@
static void deactivate_plugin( void *p ) {
if ( !is_plugin_active( p ) ) {
- cleanup_all( -500146 );
+ cleanup_all( -500190 );
//dbg( DBGL_SYS, DBGT_ERR, "deactivate_plugin(): requested to deactivate inactive plugin !");
//return;
}
struct list_head *list_pos, *tmp_pos, *prev_pos = (struct list_head*)&plugin_list;
- Link_flags = 0;
-
list_for_each_safe( list_pos, tmp_pos, &plugin_list ) {
struct plugin_node *pn = list_entry( list_pos, struct plugin_node, list );
@@ -379,7 +374,7 @@
if ( pn->version != PLUGIN_VERSION_01 )
cleanup_all( -500098 );
- dbgf( DBGL_CHANGES, DBGT_INFO, "deactivating plugin %s", pn->plugin_v1->plugin_name );
+ dbg( DBGL_CHANGES, DBGT_INFO, "deactivating plugin %s", pn->plugin_v1->plugin_name );
if ( pn->plugin_v1->cb_cleanup )
(*( pn->plugin_v1->cb_cleanup )) ();
@@ -392,9 +387,6 @@
} else {
- if ( pn->plugin_v1 )
- Link_flags |= pn->plugin_v1->link_flags;
-
prev_pos = &pn->list;
}
@@ -405,7 +397,6 @@
static int8_t activate_dyn_plugin( const char* name ) {
- //get_plugin_v1 get_plugin_v1;
struct plugin_v1* (*get_plugin_v1) ( void ) = NULL;
void *dlhandle;
@@ -449,13 +440,22 @@
}
dbgf_all( DBGT_INFO, "survived dlopen()!" );
-
-
- if ( !( (*(void **)(&get_plugin_v1)) = dlsym( dlhandle, "get_plugin_v1")) ) {
-
+
+
+ typedef struct plugin_v1* (*sdl_init_function_type) ( void );
+
+ union {
+ sdl_init_function_type func;
+ void * obj;
+ } alias;
+
+ alias.obj = dlsym( dlhandle, "get_plugin_v1");
+
+ if ( !( get_plugin_v1 = alias.func ) ) {
dbgf( DBGL_SYS, DBGT_ERR, "dlsym( %s ) failed: %s", name, dlerror() );
return FAILURE;
}
+
if ( !(pv1 = get_plugin_v1()) ) {
Modified: trunk/batman-experimental/plugin.h
===================================================================
--- trunk/batman-experimental/plugin.h 2010-04-12 19:06:37 UTC (rev 1633)
+++ trunk/batman-experimental/plugin.h 2010-04-15 08:16:16 UTC (rev 1634)
@@ -46,7 +46,6 @@
void (*cb_plugin_handler[PLUGIN_CB_SIZE]) (void*);
//some other attributes
- uint8_t link_flags;
};
Modified: trunk/batman-experimental/posix/posix.c
===================================================================
--- trunk/batman-experimental/posix/posix.c 2010-04-12 19:06:37 UTC (rev 1633)
+++ trunk/batman-experimental/posix/posix.c 2010-04-15 08:16:16 UTC (rev 1634)
@@ -38,6 +38,7 @@
#include "metrics.h"
#include "plugin.h"
#include "schedule.h"
+//#include "avl.h"
# define timercpy(d, a) (d)->tv_sec = (a)->tv_sec; (d)->tv_usec = (a)->tv_usec;
@@ -53,6 +54,14 @@
}
#endif
+/* get_time functions MUST be called at least every 2*MAX_SELECT_TIMEOUT_MS to allow for properly working time-drift checks */
+
+/* overlaps after approximately 138 years */
+//#define get_time_sec() get_time( NO, NULL )
+
+/* overlaps after 49 days, 17 hours, 2 minutes, and 48 seconds */
+//#define get_time_msec() get_time( YES, NULL )
+
void update_batman_time( struct timeval *precise_tv ) {
timeradd( &max_tv, &new_tv, &acceptable_p_tv );
@@ -176,7 +185,9 @@
void print_animation( void ) {
- Trash = system( "clear" );
+ int trash;
+
+ trash = system( "clear" );
BAT_LOGO_END( 0, 500 );
sym_print( 0, 3, "." );
@@ -379,25 +390,26 @@
void cleanup_all( int status ) {
static int cleaning_up = NO;
-
- if ( status < 0 ) {
- /*
- * Negative numbers are used as SIGSEV error codes !
- * Currently used numbers are
- * for core programs: -500000 ... -500156
- */
- dbg( DBGL_SYS, DBGT_ERR,
- "Terminating with error code %d ! Please notify a developer", status );
+
+ if (status < 0) {
+ dbg(DBGL_SYS, DBGT_ERR, "Terminating with error code %d ! Please notify a developer", status);
+
+ dbg(DBGL_SYS, DBGT_ERR, "raising SIGSEGV to simplify debugging ...");
+
+ errno = 0;
+ if (raise(SIGSEGV)) {
+ dbg(DBGL_SYS, DBGT_ERR, "raising SIGSEGV failed: %s...", strerror(errno));
+ }
+
+ }
+
+
+ if (!cleaning_up) {
+
+ cleaning_up = YES;
+
+ // first, restore defaults...
- raise( SIGSEGV );
- }
-
- if ( !cleaning_up ) {
-
- cleaning_up = YES;
-
- // first, restore defaults...
-
stop = 1;
cleanup_schedule();
@@ -421,13 +433,11 @@
remove_outstanding_ogms( bif );
list_del( (struct list_head *)&if_list, list_pos, &if_list );
-
- debugFree( list_pos, 1214 );
+
+ //debugFree(bif->own_ogm_out, 1209);
+ debugFree(bif, 1214);
}
- hash_destroy( orig_hash );
-
-
// last, close debugging system and check for forgotten resources...
cleanup_control();
@@ -462,28 +472,27 @@
My_pid = getpid();
-
- char *d = getenv(BMX_ENV_DEBUG);
+/* char *d = getenv(BMX_ENV_DEBUG);
if ( d && strtol(d, NULL , 10) >= DBGL_MIN && strtol(d, NULL , 10) <= DBGL_MAX )
debug_level = strtol(d, NULL , 10);
+*/
-
srand( My_pid );
init_set_bits_table256();
- orig_hash = hash_new( 128, compare_key, choose_key, 4 );
-
signal( SIGINT, handler );
signal( SIGTERM, handler );
signal( SIGPIPE, SIG_IGN );
signal( SIGSEGV, segmentation_fault );
+ init_control();
+
init_profile();
init_route();
- init_control();
+// init_control();
init_route_args();
Modified: trunk/batman-experimental/posix/tunnel.c
===================================================================
--- trunk/batman-experimental/posix/tunnel.c 2010-04-12 19:06:37 UTC (rev 1633)
+++ trunk/batman-experimental/posix/tunnel.c 2010-04-15 08:16:16 UTC (rev 1634)
@@ -33,16 +33,73 @@
#include <linux/if_tun.h> /* TUNSETPERSIST, ... */
#include <linux/if.h> /* ifr_if, ifr_tun */
#include <fcntl.h> /* open(), O_RDWR */
+#include <asm/types.h>
+#include <sys/socket.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
#include "batman.h"
#include "os.h"
#include "originator.h"
#include "plugin.h"
#include "schedule.h"
-static int32_t Tun_persist;
+#define ARG_UNRESP_GW_CHK "unresp_gateway_check"
+
+#define ARG_TWO_WAY_TUNNEL "two_way_tunnel"
+
+#define ARG_ONE_WAY_TUNNEL "one_way_tunnel"
+
+#define ARG_GW_HYSTERESIS "gateway_hysteresis"
+#define MIN_GW_HYSTERE 1
+#define MAX_GW_HYSTERE PROBE_RANGE/PROBE_TO100
+#define DEF_GW_HYSTERE 2
+
+
+#define BATMAN_TUN_PREFIX "bat"
+#define MAX_BATMAN_TUN_INDEX 20
+
+#define TUNNEL_DATA 0x01
+#define TUNNEL_IP_REQUEST 0x02
+#define TUNNEL_IP_INVALID 0x03
+#define TUNNEL_IP_REPLY 0x06
+
+#define GW_STATE_UNKNOWN 0x01
+#define GW_STATE_VERIFIED 0x02
+
+#define ONE_MINUTE 60000
+
+#define GW_STATE_UNKNOWN_TIMEOUT (1 * ONE_MINUTE)
+#define GW_STATE_VERIFIED_TIMEOUT (5 * ONE_MINUTE)
+
+#define IP_LEASE_TIMEOUT (1 * ONE_MINUTE)
+
+#define MAX_TUNNEL_IP_REQUESTS 60 //12
+#define TUNNEL_IP_REQUEST_TIMEOUT 1000 // msec
+
+#define DEF_GWTUN_NETW_PREFIX "169.254.0.0" /* 0x0000FEA9 */
+
+#define MIN_GWTUN_NETW_MASK 20
+#define MAX_GWTUN_NETW_MASK 30
+#define DEF_GWTUN_NETW_MASK 22
+
+#define MIN_TUN_LTIME 60 /*seconds*/
+#define MAX_TUN_LTIME 60000
+#define DEF_TUN_LTIME 600
+#define ARG_TUN_LTIME "tunnel_lease_time"
+
+#define DEF_TUN_PERSIST 1
+
+
+#define MIN_RT_CLASS 0
+#define MAX_RT_CLASS 3
+
+
+static int32_t Tun_persist = DEF_TUN_PERSIST;
+
static int32_t my_gw_port = 0;
static uint32_t my_gw_addr = 0;
@@ -73,11 +130,131 @@
static uint32_t gw_tunnel_netmask;
-static int32_t Tun_leasetime;
+static int32_t Tun_leasetime = DEF_TUN_LTIME;
static uint32_t pref_gateway = 0;
+
+
+
+struct tun_request_type {
+ uint32_t lease_ip;
+ uint16_t lease_lt;
+} __attribute__((packed));
+
+struct tun_data_type {
+ unsigned char ip_packet[MAX_MTU];
+} __attribute__((packed));
+
+struct tun_packet_start {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ unsigned int type:4;
+ unsigned int version:4; // should be the first field in the packet in network byte order
+#elif __BYTE_ORDER == __BIG_ENDIAN
+ unsigned int version:4;
+ unsigned int type:4;
+#else
+# error "Please fix <bits/endian.h>"
+#endif
+} __attribute__((packed));
+
+struct tun_packet
+{
+ uint8_t reserved1;
+ uint8_t reserved2;
+ uint8_t reserved3;
+
+ struct tun_packet_start start;
+#define TP_TYPE start.type
+#define TP_VERS start.version
+
+ union
+ {
+ struct tun_request_type trt;
+ struct tun_data_type tdt;
+ struct iphdr iphdr;
+ }tt;
+#define LEASE_IP tt.trt.lease_ip
+#define LEASE_LT tt.trt.lease_lt
+#define IP_PACKET tt.tdt.ip_packet
+#define IP_HDR tt.iphdr
+} __attribute__((packed));
+
+
+#define TX_RP_SIZE (sizeof(struct tun_packet_start) + sizeof(struct tun_request_type))
+#define TX_DP_SIZE (sizeof(struct tun_packet_start) + sizeof(struct tun_data_type))
+
+
+struct gwc_args {
+ uint32_t gw_state_stamp;
+ uint8_t gw_state;
+ uint8_t prev_gw_state;
+ uint32_t orig;
+ struct gw_node *gw_node; // pointer to gw node
+ struct sockaddr_in gw_addr; // gateway ip
+ char gw_str[ADDR_STR_LEN]; // string of gateway ip
+ struct sockaddr_in my_addr; // primary_ip
+ uint32_t my_tun_addr; // ip used for bat0 tunnel interface
+ char my_tun_str[ADDR_STR_LEN]; // string of my_tun_addr
+ int32_t mtu_min;
+ uint8_t tunnel_type;
+ int32_t udp_sock;
+ int32_t tun_fd;
+ int32_t tun_ifi;
+ char tun_dev[IFNAMSIZ]; // was tun_if
+ uint32_t tun_ip_request_stamp;
+ uint32_t tun_ip_lease_stamp;
+ uint32_t tun_ip_lease_duration;
+ uint32_t send_tun_ip_requests;
+ uint32_t pref_addr;
+ // uint32_t last_invalidip_warning;
+};
+
+
+struct gws_args
+{
+ int8_t netmask;
+ int32_t port;
+ int32_t owt;
+ int32_t twt;
+ int32_t lease_time;
+ int mtu_min;
+ uint32_t my_tun_ip;
+ uint32_t my_tun_netmask;
+ uint32_t my_tun_ip_h;
+ uint32_t my_tun_suffix_mask_h;
+ struct sockaddr_in client_addr;
+ struct gw_client **gw_client_list;
+ int32_t sock;
+ int32_t tun_fd;
+ int32_t tun_ifi;
+ char tun_dev[IFNAMSIZ];
+};
+
+
+
+// field accessor and flags for gateway announcement extension packets
+#define EXT_GW_FIELD_GWTYPES ext_related
+#define EXT_GW_FIELD_GWFLAGS def8
+#define EXT_GW_FIELD_GWPORT d16.def16
+#define EXT_GW_FIELD_GWADDR d32.def32
+
+// the flags for gw extension messsage gwtypes:
+#define TWO_WAY_TUNNEL_FLAG 0x01
+#define ONE_WAY_TUNNEL_FLAG 0x02
+
+struct tun_orig_data {
+
+ int16_t tun_array_len;
+ struct ext_packet tun_array[];
+
+};
+
+
+
+
+
static uint16_t my_gw_ext_array_len = 0;
static struct ext_packet my_gw_extension_packet; //currently only one gw_extension_packet considered
static struct ext_packet *my_gw_ext_array = &my_gw_extension_packet;
@@ -468,7 +645,8 @@
// memorize new gw_msg
update_gw_list( on, gw_array_len, gw_array );
- } else if ( tuno && gw_array && (tuno->tun_array_len != gw_array_len || memcmp( tuno->tun_array, gw_array, gw_array_len * sizeof(struct ext_packet)))) {
+ } else if ( tuno && gw_array &&
+ (tuno->tun_array_len != gw_array_len || memcmp( tuno->tun_array, gw_array, gw_array_len * sizeof(struct ext_packet)))) {
// update existing gw_msg
update_gw_list( on, gw_array_len, gw_array );
@@ -477,6 +655,7 @@
/* restart gateway selection if routing class 3 and we have more packets than curr_gateway */
if ( curr_gateway &&
+ on->router &&
routing_class == 3 &&
tuno &&
tuno->tun_array[0].EXT_GW_FIELD_GWFLAGS &&
@@ -484,15 +663,15 @@
curr_gateway->orig_node != on &&
( ( pref_gateway == on->orig ) ||
( pref_gateway != curr_gateway->orig_node->orig &&
- curr_gateway->orig_node->router->accepted_sqr.wa_val + (gw_hysteresis*PROBE_TO100)
- <= on->router->accepted_sqr.wa_val ) ) ) {
+ curr_gateway->orig_node->router->longtm_sqr.wa_val + (gw_hysteresis*PROBE_TO100)
+ <= on->router->longtm_sqr.wa_val ) ) ) {
dbg( DBGL_CHANGES, DBGT_INFO, "Restart gateway selection. %s gw found! "
"%d OGMs from new GW %s (compared to %d from old GW %s)",
pref_gateway == on->orig ? "Preferred":"Better",
- on->router ? on->router->accepted_sqr.wa_val : 255,
+ on->router->longtm_sqr.wa_val,
on->orig_str,
- pref_gateway != on->orig ? curr_gateway->orig_node->router->accepted_sqr.wa_val : 255,
+ pref_gateway != on->orig ? curr_gateway->orig_node->router->longtm_sqr.wa_val : 255,
pref_gateway != on->orig ? curr_gateway->orig_node->orig_str : "???" );
curr_gateway = NULL;
@@ -525,7 +704,7 @@
if ( gwc_args->pref_addr == 0 || gwc_args->pref_addr != tp->LEASE_IP ) {
if ( gwc_args->pref_addr /*== 0 ?????*/ )
- add_del_route( 0, 0, 0, 0, gwc_args->tun_ifi, gwc_args->tun_dev, RT_TABLE_TUNNEL, RT_UNICAST, DEL, TRACK_TUNNEL );
+ add_del_route( 0, 0, 0, 0, gwc_args->tun_ifi, gwc_args->tun_dev, RT_TABLE_TUNNEL, RTN_UNICAST, DEL, TRACK_TUNNEL );
if ( set_tun_addr( gwc_args->udp_sock, tp->LEASE_IP, gwc_args->tun_dev ) < 0 ) {
@@ -534,7 +713,12 @@
}
/* kernel deletes routes after resetting the interface ip */
- add_del_route( 0, 0, 0, 0, gwc_args->tun_ifi, gwc_args->tun_dev, RT_TABLE_TUNNEL, RT_UNICAST, ADD, TRACK_TUNNEL );
+ add_del_route( 0, 0, 0, 0, gwc_args->tun_ifi, gwc_args->tun_dev, RT_TABLE_TUNNEL, RTN_UNICAST, ADD, TRACK_TUNNEL );
+
+ // critical syntax: may be used for nameserver updates
+ dbg( DBGL_CHANGES, DBGT_INFO, "GWT: GW-client tunnel init succeeded - type: 2WT dev: %s IP: %s MTU: %d GWIP: %s",
+ gwc_args->tun_dev, ipStr( tp->LEASE_IP ) , gwc_args->mtu_min, ipStr( gwc_args->gw_addr.sin_addr.s_addr) );
+
}
gwc_args->tun_ip_lease_stamp = batman_time;
@@ -689,7 +873,7 @@
tp_len = tp_data_len + sizeof(tp.start);
- if ( tp_data_len < (int32_t)sizeof(struct iphdr) || ((struct iphdr *)(tp.IP_PACKET))->version != 4 ) {
+ if ( tp_data_len < (int32_t)sizeof(struct iphdr) || tp.IP_HDR.version != 4 ) {
dbgf( DBGL_SYS, DBGT_ERR, "Received Invalid packet type via tunnel !" );
continue;
@@ -741,10 +925,10 @@
unresp_gw_chk &&
gwc_args->gw_state == GW_STATE_UNKNOWN &&
gwc_args->gw_state_stamp == 0 ) {
-
- if( ( (((struct iphdr *)(tp.IP_PACKET))->protocol == IPPROTO_TCP )) ||
- ( (((struct iphdr *)(tp.IP_PACKET))->protocol == IPPROTO_UDP) &&
- (((struct udphdr *)(tp.IP_PACKET + ((struct iphdr *)(tp.IP_PACKET))->ihl*4))->dest == dns_port) )
+
+ if ((tp.IP_HDR.protocol == IPPROTO_TCP) ||
+ ( (tp.IP_HDR.protocol == IPPROTO_UDP) &&
+ (((struct udphdr *)((uint8_t*)&tp.IP_HDR) + (tp.IP_HDR.ihl*4))->dest == dns_port) )
) {
gwc_args->gw_state_stamp = batman_time;
}
@@ -817,16 +1001,14 @@
// got data from gateway
if ( tp.TP_TYPE == TUNNEL_DATA ) {
-
- if ( tp_data_len >= (int32_t)sizeof(struct iphdr) &&
- ((struct iphdr *)(tp.IP_PACKET))->version == 4 ) {
+ if (tp_data_len >= (int32_t)sizeof (struct iphdr) && tp.IP_HDR.version == 4) {
+
if ( write( gwc_args->tun_fd, tp.IP_PACKET, tp_data_len ) < 0 ) {
dbgf( DBGL_SYS, DBGT_ERR, "can't write packet: %s", strerror(errno) );
- }
+ }
- if ( unresp_gw_chk &&
- ((struct iphdr *)(tp.IP_PACKET))->protocol != IPPROTO_ICMP ) {
+ if (unresp_gw_chk && tp.IP_HDR.protocol != IPPROTO_ICMP) {
gwc_args->gw_state = GW_STATE_VERIFIED;
gwc_args->gw_state_stamp = batman_time;
@@ -836,10 +1018,10 @@
if( gwc_args->prev_gw_state != gwc_args->gw_state ) {
- dbgf( DBGL_CHANGES, DBGT_INFO,
- "changed GW state: from %d to %d, incoming IP protocol: %d",
- gwc_args->prev_gw_state, gwc_args->gw_state,
- ((struct iphdr *)(tp.IP_PACKET))->protocol );
+ dbgf( DBGL_CHANGES, DBGT_INFO,
+ "changed GW state: from %d to %d, incoming IP protocol: %d",
+ gwc_args->prev_gw_state, gwc_args->gw_state,
+ tp.IP_HDR.protocol);
gwc_args->prev_gw_state = gwc_args->gw_state;
}
@@ -903,7 +1085,7 @@
update_interface_rules( IF_RULE_CLR_TUNNEL );
if ( gwc_args->my_tun_addr )
- add_del_route( 0, 0, 0, 0, gwc_args->tun_ifi, gwc_args->tun_dev, RT_TABLE_TUNNEL, RT_UNICAST, DEL, TRACK_TUNNEL );
+ add_del_route( 0, 0, 0, 0, gwc_args->tun_ifi, gwc_args->tun_dev, RT_TABLE_TUNNEL, RTN_UNICAST, DEL, TRACK_TUNNEL );
if ( gwc_args->tun_fd ) {
del_dev_tun( gwc_args->tun_fd, gwc_args->tun_dev, gwc_args->my_tun_addr, __FUNCTION__ );
@@ -915,6 +1097,9 @@
set_fd_hook( gwc_args->udp_sock, gwc_recv_udp, YES /*delete*/ );
}
+ // critical syntax: may be used for nameserver updates
+ dbg( DBGL_CHANGES, DBGT_INFO, "GWT: GW-client tunnel closed " );
+
debugFree( gwc_args, 1207 );
gwc_args = NULL;
@@ -1066,9 +1251,13 @@
gwc_args->my_tun_addr = gwc_args->my_addr.sin_addr.s_addr;
addr_to_str( gwc_args->my_tun_addr, gwc_args->my_tun_str );
- add_del_route( 0, 0, 0, 0, gwc_args->tun_ifi, gwc_args->tun_dev, RT_TABLE_TUNNEL, RT_UNICAST, ADD, TRACK_TUNNEL );
+ add_del_route( 0, 0, 0, 0, gwc_args->tun_ifi, gwc_args->tun_dev, RT_TABLE_TUNNEL, RTN_UNICAST, ADD, TRACK_TUNNEL );
+ // critical syntax: may be used for nameserver updates
+ dbg( DBGL_CHANGES, DBGT_INFO, "GWT: GW-client tunnel init succeeded - type: 1WT dev: %s IP: %s MTU: %d",
+ gwc_args->tun_dev, ipStr( gwc_args->my_addr.sin_addr.s_addr ) , gwc_args->mtu_min );
+
} else /*if ( gwc_args->tunnel_type & TWO_WAY_TUNNEL_FLAG )*/ {
register_task( 0, gwc_maintain_twt, NULL );
@@ -1080,6 +1269,9 @@
gwc_init_failure:
+ // critical syntax: may be used for nameserver updates
+ dbg( DBGL_CHANGES, DBGT_INFO, "GWT: GW-client tunnel init failed" );
+
gwc_cleanup();
curr_gateway = NULL;
@@ -1256,7 +1448,7 @@
if ( tp.TP_TYPE == TUNNEL_DATA ) {
- if ( !(tp_data_len >= (int32_t)sizeof(struct iphdr) && ((struct iphdr *)(tp.IP_PACKET))->version == 4 ) ) {
+ if ( !(tp_data_len >= (int32_t)sizeof(struct iphdr) && tp.IP_HDR.version == 4 ) ) {
dbgf( DBGL_SYS, DBGT_ERR, "Invalid packet type via tunnel" );
continue;
@@ -1354,7 +1546,7 @@
tp_len = tp_data_len + sizeof(tp.start);
- if ( !(gws_args->twt) || tp_data_len < (int32_t)sizeof(struct iphdr) || ((struct iphdr *)(tp.IP_PACKET))->version != 4 ) {
+ if ( !(gws_args->twt) || tp_data_len < (int32_t)sizeof(struct iphdr) || tp.IP_HDR.version != 4 ) {
dbgf( DBGL_SYS, DBGT_ERR, "Invalid packet type for client tunnel" );
continue;
@@ -1406,7 +1598,7 @@
if ( gws_args->tun_ifi )
add_del_route( gws_args->my_tun_ip, gws_args->netmask,
- 0, 0, gws_args->tun_ifi, gws_args->tun_dev, 254, RT_UNICAST, DEL, TRACK_TUNNEL );
+ 0, 0, gws_args->tun_ifi, gws_args->tun_dev, 254, RTN_UNICAST, DEL, TRACK_TUNNEL );
if ( gws_args->tun_fd ) {
del_dev_tun( gws_args->tun_fd, gws_args->tun_dev, gws_args->my_tun_ip, __FUNCTION__ );
@@ -1425,6 +1617,10 @@
}
+ // critical syntax: may be used for nameserver updates
+ dbg( DBGL_CHANGES, DBGT_INFO, "GWT: GW-server tunnel closed - dev: %s IP: %s/%d MTU: %d",
+ gws_args->tun_dev, ipStr( gws_args->my_tun_ip ), gws_args->netmask , gws_args->mtu_min );
+
debugFree( gws_args, 1223 );
gws_args = NULL;
@@ -1435,7 +1631,7 @@
static int32_t gws_init( void ) {
- char str[16], str2[16];
+ //char str[16], str2[16];
if ( probe_tun() == FAILURE )
goto gws_init_failure;
@@ -1469,10 +1665,10 @@
gws_args->my_tun_ip_h = ntohl( gw_tunnel_prefix );
gws_args->my_tun_suffix_mask_h = ntohl( ~gws_args->my_tun_netmask );
- addr_to_str( gws_args->my_tun_ip, str );
- addr_to_str( gws_args->my_tun_netmask, str2 );
- dbgf( DBGL_CHANGES, DBGT_INFO, "my_tun_ip %s, my_tun_netmask: %s", str, str2);
+ //addr_to_str( gws_args->my_tun_ip, str );
+ //addr_to_str( gws_args->my_tun_netmask, str2 );
+
gws_args->client_addr.sin_family = AF_INET;
gws_args->client_addr.sin_port = htons(gws_args->port);
@@ -1535,7 +1731,7 @@
}
add_del_route( gws_args->my_tun_ip, gws_args->netmask,
- 0, 0, gws_args->tun_ifi, gws_args->tun_dev, 254, RT_UNICAST, ADD, TRACK_TUNNEL );
+ 0, 0, gws_args->tun_ifi, gws_args->tun_dev, 254, RTN_UNICAST, ADD, TRACK_TUNNEL );
register_task( 5000, gws_garbage_collector, NULL );
@@ -1552,10 +1748,17 @@
my_gw_ext_array_len = 1;
+ // critical syntax: may be used for nameserver updates
+ dbg( DBGL_CHANGES, DBGT_INFO, "GWT: GW-server tunnel init succeeded - dev: %s IP: %s/%d MTU: %d",
+ gws_args->tun_dev, ipStr( gws_args->my_tun_ip ), gws_args->netmask , gws_args->mtu_min );
+
return SUCCESS;
gws_init_failure:
-
+
+ // critical syntax: may be used for nameserver updates
+ dbg( DBGL_CHANGES, DBGT_INFO, "GWT: GW-server tunnel init failed" );
+
gws_cleanup();
return FAILURE;
@@ -1644,7 +1847,7 @@
if ( routing_class == 0 || curr_gateway ||
((routing_class == 1 || routing_class == 2 ) &&
- ( batman_time_sec < (((uint32_t)(my_ogi*my_pws))/(CHOOSE_GW_DELAY_DIVISOR*1000)) )) ) {
+ ( batman_time_sec < COMMON_OBSERVATION_WINDOW )) ) {
return;
}
@@ -1676,24 +1879,24 @@
get_gw_speeds( tuno->tun_array[0].EXT_GW_FIELD_GWFLAGS, &download_speed, &upload_speed );
// is this voodoo ???
- tmp_gw_factor = ( ( ( on->router->accepted_sqr.wa_val/PROBE_TO100 ) *
- ( on->router->accepted_sqr.wa_val/PROBE_TO100 ) ) ) *
+ tmp_gw_factor = ( ( ( on->router->longtm_sqr.wa_val/PROBE_TO100 ) *
+ ( on->router->longtm_sqr.wa_val/PROBE_TO100 ) ) ) *
( download_speed / 64 ) ;
if ( tmp_gw_factor > max_gw_factor ||
( tmp_gw_factor == max_gw_factor &&
- on->router->accepted_sqr.wa_val > best_wa_val ) )
+ on->router->longtm_sqr.wa_val > best_wa_val ) )
tmp_curr_gw = gw_node;
break;
case 2: /* stable connection (use best statistic) */
- if ( on->router->accepted_sqr.wa_val > best_wa_val )
+ if ( on->router->longtm_sqr.wa_val > best_wa_val )
tmp_curr_gw = gw_node;
break;
default: /* fast-switch (use best statistic but change as soon as a better gateway appears) */
- if ( on->router->accepted_sqr.wa_val > best_wa_val )
+ if ( on->router->longtm_sqr.wa_val > best_wa_val )
tmp_curr_gw = gw_node;
break;
@@ -1702,7 +1905,7 @@
if ( tuno->tun_array[0].EXT_GW_FIELD_GWFLAGS > max_gw_class )
max_gw_class = tuno->tun_array[0].EXT_GW_FIELD_GWFLAGS;
- best_wa_val = MAX( best_wa_val, on->router->accepted_sqr.wa_val );
+ best_wa_val = MAX( best_wa_val, on->router->longtm_sqr.wa_val );
if ( tmp_gw_factor > max_gw_factor )
@@ -1716,7 +1919,7 @@
dbg( DBGL_SYS, DBGT_INFO,
"Preferred gateway found: %s (gw_flags: %i, packet_count: %i, ws: %i, gw_product: %i)",
on->orig_str, tuno->tun_array[0].EXT_GW_FIELD_GWFLAGS,
- on->router->accepted_sqr.wa_val/PROBE_TO100, on->pws, tmp_gw_factor );
+ on->router->longtm_sqr.wa_val/PROBE_TO100, on->pws, tmp_gw_factor );
break;
@@ -1792,8 +1995,8 @@
dbg_printf( cn, "%s %-15s %15s %3i, gw_class %2i - %i%s/%i%s, reliability: %i, supported tunnel types %s, %s \n",
curr_gateway == gw_node ? "=>" : " ",
- ipStr(on->orig) , ipStr(on->router->addr),
- gw_node->orig_node->router->accepted_sqr.wa_val/PROBE_TO100,
+ ipStr(on->orig) , ipStr(on->router->nnkey_addr),
+ gw_node->orig_node->router->longtm_sqr.wa_val/PROBE_TO100,
tuno->tun_array[0].EXT_GW_FIELD_GWFLAGS,
download_speed > 2048 ? download_speed / 1024 : download_speed,
download_speed > 2048 ? "MBit" : "KBit",
@@ -1852,7 +2055,7 @@
if ( cmd == OPT_APPLY ) {
- if ( Gateway_class && routing_class )
+ if ( /* Gateway_class && */ routing_class )
check_apply_parent_option( DEL, OPT_APPLY, _save, get_option(0,0,ARG_GW_CLASS), 0, cn );
}
@@ -1879,8 +2082,10 @@
pref_gateway = test_ip;
/* use routing class 3 if none specified */
+/*
if ( pref_gateway && !routing_class && !Gateway_class )
check_apply_parent_option( ADD, OPT_APPLY, _save, get_option(0,0,ARG_RT_CLASS), "3", cn );
+*/
}
@@ -1966,7 +2171,7 @@
Gateway_class = gateway_class;
- if ( gateway_class && routing_class )
+ if ( gateway_class /*&& routing_class*/ )
check_apply_parent_option( DEL, OPT_APPLY, _save, get_option(0,0,ARG_RT_CLASS), 0, cn );
dbg( DBGL_SYS, DBGT_INFO, "gateway class: %i -> propagating: %s", gateway_class, gwarg );
@@ -2016,15 +2221,19 @@
{ODI,5,0,ARG_UNRESP_GW_CHK, 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &unresp_gw_chk, 0, 1, 1, 0,
ARG_VALUE_FORM,"disable/enable unresponsive GW check (only relevant for GW clients in TWT mode)"},
-
+
+#ifndef LESS_OPTIONS
{ODI,5,0,ARG_TUN_LTIME, 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &Tun_leasetime, MIN_TUN_LTIME, MAX_TUN_LTIME, DEF_TUN_LTIME, 0,
ARG_VALUE_FORM,"set leasetime in seconds of virtual two-way-tunnel IPs"},
-
+#endif
+
{ODI,4,0,ARG_GWTUN_NETW, 0, A_PS1,A_ADM,A_INI,A_CFA,A_ANY, 0, 0, 0, 0, opt_gwtun_netw,
ARG_PREFIX_FORM,"set network used by two-way-tunnel gateway nodes\n"},
- {ODI,5,0,"tun_persist", 0, A_PS1,A_ADM,A_INI,A_CFA,A_ANY, &Tun_persist, 0, 1, 1, 0,
+#ifndef LESS_OPTIONS
+ {ODI,5,0,"tun_persist", 0, A_PS1,A_ADM,A_INI,A_CFA,A_ANY, &Tun_persist, 0, 1, DEF_TUN_PERSIST,0,
ARG_VALUE_FORM,"disable/enable ioctl TUNSETPERSIST for GW tunnels (disabling was required for openVZ emulation)" },
+#endif
{ODI,5,0,ARG_GATEWAYS, 0, A_PS0,A_USR,A_DYN,A_ARG,A_END, 0, 0, 0, 0, opt_gateways,0,
"show currently available gateways\n"}
Modified: trunk/batman-experimental/schedule.c
===================================================================
--- trunk/batman-experimental/schedule.c 2010-04-12 19:06:37 UTC (rev 1633)
+++ trunk/batman-experimental/schedule.c 2010-04-15 08:16:16 UTC (rev 1634)
@@ -35,11 +35,18 @@
#include "plugin.h"
#include "schedule.h"
+int32_t my_ogi; /* orginator message interval in miliseconds */
+int32_t ogi_pwrsave;
+
static int32_t pref_udpd_size = DEF_UDPD_SIZE;
//static int32_t aggr_p_ogi;
static int32_t aggr_interval;
+#ifndef NOPARANOIA
+#define DEF_SIM_PARA NO
+static int32_t sim_paranoia = DEF_SIM_PARA;
+#endif
static SIMPEL_LIST( send_list );
@@ -199,7 +206,9 @@
uint32_t whats_next( void ) {
struct list_head *list_pos, *tmp_pos, *prev_pos = (struct list_head*)&task_list;
-
+
+ paranoia( -500175, sim_paranoia );
+
list_for_each_safe( list_pos, tmp_pos, &task_list ) {
struct task_node *tn = list_entry( list_pos, struct task_node, list );
@@ -232,63 +241,51 @@
prof_start( PROF_send_aggregated_ogms );
struct list_head *if_pos;
-
uint8_t iftype;
/* send all the aggregated packets (which fit into max packet size) */
/* broadcast via lan interfaces first */
for ( iftype = VAL_DEV_LL_LAN; iftype <= VAL_DEV_LL_WLAN; iftype++ ) {
-
- list_for_each(if_pos, &if_list) {
-
- struct batman_if *bif = list_entry(if_pos, struct batman_if, list);
-
- dbgf_all( DBGT_INFO, "dev: %s, linklayer %d iftype %d len %d ...",
- bif->dev, bif->if_linklayer, iftype, bif->aggregation_len);
- if ( bif->if_linklayer == iftype &&
- bif->aggregation_len > (int32_t)sizeof( struct bat_header ) )
- {
-
- ((struct bat_header*)&(bif->aggregation_out))->version = COMPAT_VERSION;
-
- ((struct bat_header*)&(bif->aggregation_out))->link_flags = Link_flags;
-
-
- ((struct bat_header*)&(bif->aggregation_out))->size =
- (bif->aggregation_len)/4;
-
-
- if ( bif->aggregation_len > MAX_UDPD_SIZE || (bif->aggregation_len)%4 != 0) {
-
- dbg( DBGL_SYS, DBGT_ERR, "trying to send strange packet length %d oktets",
- bif->aggregation_len );
-
- cleanup_all( -500016 );
- }
-
- if (bif->if_active ) {
-
- if ( send_udp_packet( bif->aggregation_out, bif->aggregation_len,
- &bif->if_netwbrc_addr, bif->if_unicast_sock ) < 0 )
- {
-
- dbg_mute( 60, DBGL_SYS, DBGT_ERR,
- "send_aggregated_ogms() cant send via dev %s %s fd %d",
- bif->dev, bif->if_ip_str, bif->if_unicast_sock);
-
- }
- }
-
- bif->aggregation_len = sizeof( struct bat_header );
-
- }
-
- }
+ list_for_each(if_pos, &if_list) {
- }
-
+ struct batman_if *bif = list_entry(if_pos, struct batman_if, list);
+
+ dbgf_all(DBGT_INFO, "dev: %s, linklayer %d iftype %d len %d min_len %d...",
+ bif->dev, bif->if_linklayer, iftype, bif->aggregation_len,
+ (int32_t)sizeof ( struct bat_header));
+
+ if (bif->if_linklayer == iftype &&
+ bif->aggregation_len > (int32_t)sizeof ( struct bat_header)) {
+
+ struct bat_header *bat_hdr = (struct bat_header *) bif->aggregation_out;
+ bat_hdr->version = COMPAT_VERSION;
+ bat_hdr->link_flags = 0;
+ bat_hdr->size = (bif->aggregation_len) / 4;
+
+ if (bif->aggregation_len > MAX_UDPD_SIZE || (bif->aggregation_len) % 4 != 0) {
+
+ dbg(DBGL_SYS, DBGT_ERR, "trying to send strange packet length %d oktets",
+ bif->aggregation_len);
+
+ cleanup_all(-500016);
+ }
+
+ if (send_udp_packet(bif->aggregation_out, bif->aggregation_len,
+ &bif->if_netwbrc_addr, bif->if_unicast_sock) < 0) {
+ dbg_mute(60, DBGL_SYS, DBGT_ERR,
+ "send_aggregated_ogms() cant send via dev %s %s fd %d",
+ bif->dev, bif->if_ip_str, bif->if_unicast_sock);
+ }
+
+ bif->aggregation_len = sizeof ( struct bat_header);
+
+ }
+
+ }
+ }
+
prof_stop( PROF_send_aggregated_ogms );
return;
}
@@ -303,7 +300,7 @@
list_for_each( list_pos, &send_list ) {
struct send_node *send_node = list_entry( list_pos, struct send_node, list );
- struct bat_packet_ogm *ogm = ((struct bat_packet_ogm *)(send_node->ogm_buff));
+ struct bat_packet_ogm *ogm = send_node->ogm;
dbg_printf( cn, "%-15s (seqno %5d ttl %3d) at %u \n",
ipStr( ogm->orig ), ntohs(ogm->ogm_seqno), ogm->ogm_ttl, send_node->send_time );
@@ -368,11 +365,6 @@
-
-
-
-
-
void remove_outstanding_ogms( struct batman_if *bif ) {
struct send_node *send_node;
struct list_head *send_pos, *send_temp, *send_prev;
@@ -389,19 +381,16 @@
if ( send_node->if_outgoing == bif ) {
list_del( send_prev, send_pos, &send_list );
+ debugFree(send_node, 1502);
- if ( !send_node->own_if )
- debugFree( send_node, 1502 );
-
} else {
+ send_prev = send_pos;
- send_prev = send_pos;
-
}
}
}
-static void send_outstanding_ogms( void *unused ) {
+static void aggregate_outstanding_ogms( void *unused ) {
prof_start( PROF_send_outstanding_ogms );
struct send_node *send_node;
@@ -414,24 +403,10 @@
int dbg_if_out = 0;
#define MAX_DBG_IF_SIZE 200
static char dbg_if_str[ MAX_DBG_IF_SIZE ];
-
- //check that aggregation interval is not getting to big
- //uint16_t aggr_interval = (my_ogi/aggr_p_ogi > 3*MIN_OGI) ? 3*MIN_OGI : (my_ogi/aggr_p_ogi);
- register_task( (aggr_interval + rand_num( aggr_interval/2 )) - (aggr_interval/4), send_outstanding_ogms, NULL );
+ // ensuring that aggreg_interval is really an upper boundary
+ register_task( aggr_interval - 1 - rand_num( aggr_interval/10 ), aggregate_outstanding_ogms, NULL );
- if ( list_empty( &send_list ) ||
- GREAT_U32( (list_entry( (&send_list)->next, struct send_node, list ))->send_time, batman_time ) ) {
-
- prof_stop( PROF_send_outstanding_ogms );
- return;
- }
-
- dbgf_all( DBGT_INFO,
- "now %u, aggreg_interval %d, send_list holds packets to send",
- batman_time, aggr_interval );
-
-
prev_list_head = (struct list_head *)&send_list;
list_for_each_safe( send_pos, send_temp, &send_list ) {
@@ -476,11 +451,11 @@
// keep care to not aggregate more packets than would fit into max packet size
aggregated_size += send_node->ogm_buff_len;
- directlink = (((struct bat_packet_ogm *)send_node->ogm_buff)->flags & DIRECTLINK_FLAG );
- unidirectional = (((struct bat_packet_ogm *)send_node->ogm_buff)->flags & UNIDIRECTIONAL_FLAG );
- cloned = (((struct bat_packet_ogm *)send_node->ogm_buff)->flags & CLONED_FLAG );
+ directlink = (send_node->ogm->flags & DIRECTLINK_FLAG );
+ unidirectional = (send_node->ogm->flags & UNIDIRECTIONAL_FLAG );
+ cloned = (send_node->ogm->flags & CLONED_FLAG );
- ttl = ((struct bat_packet_ogm *)send_node->ogm_buff)->ogm_ttl;
+ ttl = send_node->ogm->ogm_ttl;
if_singlehomed = ( (send_node->own_if && send_node->if_outgoing->if_singlehomed) ? 1 : 0 );
@@ -508,7 +483,7 @@
//TODO: send only pure bat_packet_ogm, no extension headers.
memcpy( send_node->if_outgoing->aggregation_out +
send_node->if_outgoing->aggregation_len,
- send_node->ogm_buff, send_node->ogm_buff_len );
+ send_node->ogm, send_node->ogm_buff_len );
send_node->if_outgoing->aggregation_len += send_node->ogm_buff_len;
@@ -518,35 +493,44 @@
list_for_each(if_pos, &if_list) {
- bif = list_entry(if_pos, struct batman_if, list);
+ struct bat_packet_ogm *ogm;
+ bif = list_entry(if_pos, struct batman_if, list);
+
if ( !bif->if_active )
continue;
if ( ( send_node->send_bucket >= bif->if_send_clones ) ||
( if_singlehomed && send_node->if_outgoing != bif ) )
continue;
-
+
+ if (
+ // power-save mode enabled:
+ ogi_pwrsave > my_ogi &&
+ // we alone:
+ GREAT_U32(batman_time, bif->if_last_link_activity + COMMON_OBSERVATION_WINDOW) &&
+ (// not yet time for a neighbor-discovery hardbeat?:
+ send_node->own_if == 0 ||
+ send_node->if_outgoing != bif ||
+ LSEQ_U32(batman_time, bif->if_next_pwrsave_hardbeat)
+ ))
+ continue;
+
+
if ( (send_node->send_bucket + 100) < bif->if_send_clones )
send_node_done = NO;
+ ogm = (struct bat_packet_ogm*) (bif->aggregation_out + bif->aggregation_len);
- memcpy( (bif->aggregation_out + bif->aggregation_len),
- send_node->ogm_buff, send_node->ogm_buff_len );
+ memcpy( ogm, send_node->ogm, send_node->ogm_buff_len );
-
if ( send_node->iteration > bif->if_ant_diversity )
- ((struct bat_packet_ogm *)
- (bif->aggregation_out + bif->aggregation_len))->flags |= CLONED_FLAG;
-
-
+ ogm->flags |= CLONED_FLAG;
+
if ( ( directlink ) && ( send_node->if_outgoing == bif ) )
- ((struct bat_packet_ogm *)
- (bif->aggregation_out + bif->aggregation_len))->flags |= DIRECTLINK_FLAG;
-
+ ogm->flags |= DIRECTLINK_FLAG;
else
- ((struct bat_packet_ogm *)
- (bif->aggregation_out + bif->aggregation_len))->flags &= ~DIRECTLINK_FLAG;
+ ogm->flags &= ~DIRECTLINK_FLAG;
bif->aggregation_len += send_node->ogm_buff_len;
@@ -568,8 +552,8 @@
dbgf_all( DBGT_INFO,
"OG %-16s, seqno %5d, TTL %2d, IDF %d, UDF %d, CLF %d "
"iter %d len %3d max agg_size %3d IFs %s",
- ipStr( ((struct bat_packet_ogm *)send_node->ogm_buff)->orig ),
- ntohs( ((struct bat_packet_ogm *)send_node->ogm_buff)->ogm_seqno ),
+ ipStr( send_node->ogm->orig ),
+ ntohs( send_node->ogm->ogm_seqno ),
ttl, directlink, unidirectional, cloned, send_node->iteration,
send_node->ogm_buff_len, aggregated_size, dbg_if_str );
@@ -582,22 +566,15 @@
// trigger next seqno now where the first one of the current seqno has been send
if ( send_node->own_if && send_node->iteration == 1 ) {
send_node->if_outgoing->if_seqno++;
+ send_node->if_outgoing->send_own = 1;
}
// remove all the finished packets from send_list
if ( send_node_done ) {
list_del( prev_list_head, send_pos, &send_list );
+ debugFree(send_node, 1502);
- if ( !send_node->own_if ) {
-
- debugFree( send_node, 1502 );
-
- } else {
- // trigger the scheduling of the next own OGMs at the end of this function
- send_node->if_outgoing->send_own = 1;
- }
-
} else {
prev_list_head = &send_node->list;
@@ -618,20 +595,31 @@
list_for_each(if_pos, &if_list) {
bif = list_entry(if_pos, struct batman_if, list);
-
- // if own OGMs have been send during this call, schedule next one now
- if ( bif->send_own )
- schedule_own_ogm( bif );
- bif->send_own = 0;
-
-
if ( bif->aggregation_len != sizeof( struct bat_header ) ) {
dbgf( DBGL_SYS, DBGT_ERR,
"finished with dev %s and packet_out_len %d > %d",
- bif->dev, bif->aggregation_len, sizeof( struct bat_header ) );
+ bif->dev, bif->aggregation_len, (int)sizeof( struct bat_header ) );
}
-
+
+
+ // if own OGMs need to be send, schedule next one now
+ if ( bif->send_own ) {
+
+ schedule_own_ogm( bif );
+
+ if (GREAT_U32(batman_time, bif->if_next_pwrsave_hardbeat))
+ bif->if_next_pwrsave_hardbeat = batman_time + ((uint32_t) (ogi_pwrsave));
+
+ bif->send_own = 0;
+ }
+
+
+ // this timestamp may become invalid after U32 wrap-around
+ if (GREAT_U32(batman_time, bif->if_last_link_activity + (2 * COMMON_OBSERVATION_WINDOW)))
+ bif->if_last_link_activity = batman_time - COMMON_OBSERVATION_WINDOW;
+
+
}
prof_stop( PROF_send_outstanding_ogms );
@@ -644,7 +632,7 @@
prof_start( PROF_schedule_rcvd_ogm );
- struct send_node *send_node_new, *send_packet_tmp = NULL;
+ struct send_node *send_packet_tmp = NULL;
struct list_head *list_pos, *prev_list_head;
uint8_t with_unidirectional_flag = 0;
@@ -718,13 +706,14 @@
for( i=0; i<=EXT_TYPE_MAX; i++ )
snd_ext_total_len += mb->snd_ext_len[i];
- send_node_new = debugMalloc( sizeof(struct send_node) + sizeof(struct bat_packet_ogm) + snd_ext_total_len, 504 );
- memset( send_node_new, 0, sizeof( struct send_node ) );
- INIT_LIST_HEAD( &send_node_new->list );
+ struct send_node *sn = debugMalloc( sizeof(struct send_node) + sizeof(struct bat_packet_ogm) + snd_ext_total_len, 504 );
+ memset( sn, 0, sizeof( struct send_node ) );
+ INIT_LIST_HEAD( &sn->list );
- send_node_new->ogm_buff_len = sizeof(struct bat_packet_ogm) + snd_ext_total_len;
+ sn->ogm_buff_len = sizeof(struct bat_packet_ogm) + snd_ext_total_len;
+ sn->ogm = (struct bat_packet_ogm*)sn->_attached_ogm_buff;
- memcpy( send_node_new->ogm_buff, mb->bp.ogm, sizeof(struct bat_packet_ogm) );
+ memcpy( sn->ogm, mb->bp.ogm, sizeof(struct bat_packet_ogm) );
/* primary-interface-extension messages do not need to be rebroadcastes */
/* other extension messages only if not unidirectional and ttl > 1 */
@@ -735,7 +724,7 @@
if ( mb->snd_ext_len[i] ) {
- memcpy( &(send_node_new->ogm_buff[p]),
+ memcpy( &(((unsigned char*)(sn->ogm))[p]),
(unsigned char *)(mb->snd_ext_array[i]),
mb->snd_ext_len[i] );
@@ -743,35 +732,34 @@
}
}
- if ( p != send_node_new->ogm_buff_len ) {
- dbgf( DBGL_SYS, DBGT_ERR, "incorrect msg lengths %d != %d", p, send_node_new->ogm_buff_len );
+ if ( p != sn->ogm_buff_len ) {
+ dbgf( DBGL_SYS, DBGT_ERR, "incorrect msg lengths %d != %d", p, sn->ogm_buff_len );
}
- ((struct bat_packet_ogm *)send_node_new->ogm_buff)->ogm_ttl--;
- ((struct bat_packet_ogm *)send_node_new->ogm_buff)->prev_hop_id = neigh_id;
- ((struct bat_packet_ogm *)send_node_new->ogm_buff)->bat_size = (send_node_new->ogm_buff_len)>>2;
+ sn->ogm->ogm_ttl--;
+ sn->ogm->prev_hop_id = neigh_id;
+ sn->ogm->bat_size = (sn->ogm_buff_len)>>2;
- send_node_new->send_time = batman_time;
- send_node_new->own_if = 0;
+ sn->send_time = batman_time;
+ sn->own_if = 0;
- send_node_new->if_outgoing = mb->iif;
+ sn->if_outgoing = mb->iif;
- ((struct bat_packet_ogm *)send_node_new->ogm_buff)->flags = 0x00;
+ sn->ogm->flags = 0x00;
if ( with_unidirectional_flag )
- ((struct bat_packet_ogm *)send_node_new->ogm_buff)->flags |= UNIDIRECTIONAL_FLAG;
+ sn->ogm->flags |= UNIDIRECTIONAL_FLAG;
if ( directlink )
- ((struct bat_packet_ogm *)send_node_new->ogm_buff)->flags |= DIRECTLINK_FLAG;
+ sn->ogm->flags |= DIRECTLINK_FLAG;
if ( oCtx & HAS_CLONED_FLAG )
- ((struct bat_packet_ogm *)send_node_new->ogm_buff)->flags |= CLONED_FLAG;
+ sn->ogm->flags |= CLONED_FLAG;
/* change sequence number to network order */
- ((struct bat_packet_ogm *)send_node_new->ogm_buff)->ogm_seqno =
- htons( ((struct bat_packet_ogm *)send_node_new->ogm_buff)->ogm_seqno );
+ sn->ogm->ogm_seqno = htons(sn->ogm->ogm_seqno);
prev_list_head = (struct list_head *)&send_list;
@@ -780,9 +768,9 @@
send_packet_tmp = list_entry( list_pos, struct send_node, list );
- if ( GREAT_U32(send_packet_tmp->send_time, send_node_new->send_time) ) {
+ if ( GREAT_U32(send_packet_tmp->send_time, sn->send_time) ) {
- list_add_before( prev_list_head, list_pos, &send_node_new->list );
+ list_add_before( prev_list_head, list_pos, &sn->list );
break;
}
@@ -791,8 +779,8 @@
}
- if ( ( send_packet_tmp == NULL ) || ( LSEQ_U32(send_packet_tmp->send_time, send_node_new->send_time) ) )
- list_add_tail( &send_node_new->list, &send_list );
+ if ( ( send_packet_tmp == NULL ) || ( LSEQ_U32(send_packet_tmp->send_time, sn->send_time) ) )
+ list_add_tail( &sn->list, &send_list );
prof_stop( PROF_schedule_rcvd_ogm );
@@ -887,10 +875,11 @@
ext_p = 0;
ext_type++;
}
-
- if ( (int32_t)(sizeof(struct bat_packet_ogm) + done_p) != ((((struct bat_packet_common *)pos)->bat_size)<<2) ) {
+ if ((int32_t) (sizeof (struct bat_packet_ogm) + done_p) !=
+ ((((struct bat_packet_common *) pos)->bat_size) << 2)) {
+
udp_len = udp_len - ((((struct bat_packet_common *)pos)->bat_size)<<2);
pos = pos + ((((struct bat_packet_common *)pos)->bat_size)<<2);
@@ -898,7 +887,7 @@
"Drop packet! Rcvd corrupted packet size via NB %s: "
"processed bytes: %d , indicated bytes %d, flags. %X, remaining bytes %d",
mb->neigh_str,
- (sizeof(struct bat_packet_ogm) + done_p),
+ (int)(sizeof(struct bat_packet_ogm) + done_p),
((((struct bat_packet_common *)pos)->bat_size)<<2),
((struct bat_packet_ogm *)pos)->flags, udp_len );
@@ -983,35 +972,32 @@
((((struct bat_header *)pos)->size)<<2) > mb->total_length )
{
- if ( mb->total_length >= (int32_t)(sizeof(struct bat_header) /*+ sizeof(struct bat_packet_common) */) )
+ if ( mb->total_length >= (int32_t)(sizeof(struct bat_header) /*+ sizeof(struct bat_packet_common) */) ) {
dbg_mute( 60, DBGL_SYS, DBGT_WARN,
"Drop packet: rcvd incompatible batman packet via NB %s "
- "(version? %i, link_flags? %X, reserved? %X, size? %i), "
+ "(version? %i, reserved? %X, size? %i), "
"rcvd udp_len %d My version is %d",
mb->neigh_str,
((struct bat_header *)pos)->version,
- ((struct bat_header *)pos)->link_flags,
((struct bat_header *)pos)->reserved,
((struct bat_header *)pos)->size,
mb->total_length, COMPAT_VERSION );
-
- else
+
+ } else {
dbg_mute( 40, DBGL_SYS, DBGT_ERR, "Rcvd to small packet via NB %s, rcvd udp_len %i",
mb->neigh_str, mb->total_length );
-
+ }
+
prof_stop( PROF_process_packet );
return;
}
-
-
- mb->link_flags = ((struct bat_header *)pos)->link_flags;
- mb->neigh = rcvd_neighbor;
- dbgf_all( DBGT_INFO, "version? %i, link_flags? %X, "
+ mb->neigh = rcvd_neighbor;
+
+ dbgf_all( DBGT_INFO, "version? %i, "
"reserved? %X, size? %i, rcvd udp_len %d via NB %s %s %s",
((struct bat_header *)pos)->version,
- ((struct bat_header *)pos)->link_flags,
((struct bat_header *)pos)->reserved,
((struct bat_header *)pos)->size,
mb->total_length, mb->neigh_str, mb->iif->dev, mb->unicast?"UNICAST":"BRC" );
@@ -1073,6 +1059,8 @@
}
+ mb->iif->if_last_link_activity = batman_time;
+
strip_packet( mb, pos, udp_len );
prof_stop( PROF_process_packet );
@@ -1390,56 +1378,82 @@
-void schedule_own_ogm( struct batman_if *batman_if ) {
+void schedule_own_ogm( struct batman_if *bif ) {
prof_start( PROF_schedule_own_ogm );
- struct send_node *send_node_new, *send_packet_tmp = NULL;
+ struct send_node *send_packet_tmp = NULL;
struct list_head *list_pos, *prev_list_head;
-
- send_node_new = batman_if->own_send_node;
- memset( send_node_new, 0, sizeof( struct send_node) );
- INIT_LIST_HEAD( &send_node_new->list );
+ int sn_size = sizeof (struct send_node) +
+ ((bif == primary_if) ? MAX_UDPD_SIZE + 1 : sizeof (struct bat_packet_ogm) + sizeof (struct ext_packet));
- send_node_new->send_time = batman_if->if_seqno_schedule + my_ogi;
+ struct send_node *sn = (struct send_node*) debugMalloc(sn_size, 209);
+
+ memset(sn, 0, sizeof (struct send_node) + sizeof (struct bat_packet_ogm) );
+
+ INIT_LIST_HEAD( &sn->list );
+
+ sn->ogm = (struct bat_packet_ogm*) sn->_attached_ogm_buff;
+
+ sn->ogm->ext_msg = NO;
+ sn->ogm->bat_type = BAT_TYPE_OGM;
+ sn->ogm->ogx_flag = NO;
+ sn->ogm->ogm_ttl = bif->if_ttl;
+ sn->ogm->ogm_pws = my_pws;
+ sn->ogm->orig = bif->if_addr;
+ //sn->ogm->ogm_path_lounge = Signal_lounge;
+
+
+
+ sn->send_time = bif->if_seqno_schedule + my_ogi;
- if ( LESS_U32( send_node_new->send_time, batman_time ) ||
- GREAT_U32( send_node_new->send_time, batman_time + my_ogi ) )
+ if ( LESS_U32( sn->send_time, batman_time ) ||
+ GREAT_U32( sn->send_time, batman_time + my_ogi ) )
{
dbg_mute( 50, DBGL_SYS, DBGT_WARN,
"strange own OGM schedule, rescheduling IF %10s SQN %d from %d to %d. "
- "Maybe --%s too small, --%s to big or too much --%s",
- batman_if->dev, batman_if->if_seqno, send_node_new->send_time, batman_time + my_ogi,
- ARG_OGI_INTERVAL, ARG_AGGR_ITERVAL, ARG_WL_CLONES );
+ "Maybe we just woke up from power-save mode, --%s too small, --%s to big or too much --%s",
+ bif->dev, bif->if_seqno, sn->send_time, batman_time + my_ogi,
+ ARG_OGI, ARG_AGGR_IVAL, ARG_WL_CLONES );
- send_node_new->send_time = batman_time + my_ogi;// - (my_ogi/(2*aggr_p_ogi));
+ sn->send_time = batman_time + my_ogi;// - (my_ogi/(2*aggr_p_ogi));
}
- batman_if->if_seqno_schedule = send_node_new->send_time;
+ bif->if_seqno_schedule = sn->send_time;
- dbgf_all( DBGT_INFO, "for %s seqno %d at %d", batman_if->dev, batman_if->if_seqno, send_node_new->send_time );
+ dbgf_all( DBGT_INFO, "for %s seqno %d at %d", bif->dev, bif->if_seqno, sn->send_time );
- send_node_new->if_outgoing = batman_if;
- send_node_new->own_if = 1;
+ sn->if_outgoing = bif;
+ sn->own_if = 1;
uint32_t ogm_len = sizeof(struct bat_packet_ogm);
- unsigned char *what_p;
- int32_t what_len;
/* only primary interfaces send usual extension messages */
- if ( batman_if == primary_if ) {
+ if ( bif == primary_if ) {
uint16_t t;
for ( t=0; t<=EXT_TYPE_MAX; t++ ) {
+
+ int32_t what_len=0;
- if ( (what_len = cb_snd_ext_hook( t, send_node_new->ogm_buff + ogm_len )) != FAILURE )
- ogm_len += what_len;
-
- else
+ if ( (what_len = cb_snd_ext_hook( t, (unsigned char*)sn->ogm + ogm_len )) == FAILURE )
cleanup_all( -500040 - t );
-
+
+ if ( ogm_len+what_len > (uint32_t) pref_udpd_size) {
+
+ dbg(DBGL_SYS, DBGT_ERR,
+ "%s=%d exceeded by needed ogm + extension header length (%d+%d) "
+ "due to additional extension header 0x%X"
+ "you may increase %s or specify less tpye-0x%X extension headers",
+ ARG_UDPD_SIZE, pref_udpd_size, ogm_len, what_len, t, ARG_UDPD_SIZE, t);
+
+ cleanup_all(-500192);
+ //break;
+ }
+
+ ogm_len += what_len;
}
/* all non-primary interfaces send primary-interface extension message */
@@ -1448,22 +1462,19 @@
my_pip_extension_packet.EXT_PIP_FIELD_ADDR = primary_addr;
my_pip_extension_packet.EXT_PIP_FIELD_PIPSEQNO = htons( primary_if->if_seqno );
- what_len = sizeof(struct ext_packet);
- what_p = (unsigned char *)&my_pip_extension_packet;
-
- memcpy( (send_node_new->ogm_buff + ogm_len), what_p, what_len );
- ogm_len += what_len;
+ memcpy( (unsigned char*)sn->ogm + ogm_len, &my_pip_extension_packet, sizeof(struct ext_packet) );
+ ogm_len += sizeof(struct ext_packet);
}
- send_node_new->ogm_buff_len = ogm_len;
+ sn->ogm_buff_len = ogm_len;
- batman_if->own_ogm_out->ogm_seqno = htons( batman_if->if_seqno );
- batman_if->own_ogm_out->bat_size = ogm_len/4;
- batman_if->own_ogm_out->flags = 0;
+ sn->ogm->ogm_seqno = htons( bif->if_seqno );
+ sn->ogm->bat_size = ogm_len/4;
+ sn->ogm->flags = 0;
- batman_if->own_ogm_out->ogm_misc = MIN( s_curr_avg_cpu_load , 255 );
+ sn->ogm->ogm_misc = MIN( s_curr_avg_cpu_load , 255 );
prev_list_head = (struct list_head *)&send_list;
@@ -1471,9 +1482,9 @@
send_packet_tmp = list_entry( list_pos, struct send_node, list );
- if ( GREAT_U32(send_packet_tmp->send_time, send_node_new->send_time) ) {
+ if ( GREAT_U32(send_packet_tmp->send_time, sn->send_time) ) {
- list_add_before( prev_list_head, list_pos, &send_node_new->list );
+ list_add_before( prev_list_head, list_pos, &sn->list );
break;
}
@@ -1482,21 +1493,21 @@
}
- if ( ( send_packet_tmp == NULL ) || ( LSEQ_U32(send_packet_tmp->send_time, send_node_new->send_time) ) )
- list_add_tail( &send_node_new->list, &send_list );
+ if ( ( send_packet_tmp == NULL ) || ( LSEQ_U32(send_packet_tmp->send_time, sn->send_time) ) )
+ list_add_tail( &sn->list, &send_list );
list_for_each( list_pos, &link_list ) {
struct link_node *ln = list_entry(list_pos, struct link_node, list);
- struct link_node_dev *lndev = get_lndev( ln, batman_if, NO/*create*/ );
+ struct link_node_dev *lndev = get_lndev( ln, bif, NO/*create*/ );
- if ( lndev )
- update_queued_metric( 0, my_link_lounge, batman_if->if_seqno - OUT_SEQNO_OFFSET,
- &lndev->rtq_sqr, my_lws,
- batman_if->if_addr , ln->orig_node->orig, batman_if, "schedule_own_ogm()" );
-
- }
+ if ( lndev) {
+ update_lounged_metric(0, local_rtq_lounge,
+ bif->if_seqno - OUT_SEQNO_OFFSET, bif->if_seqno - OUT_SEQNO_OFFSET,
+ &lndev->rtq_sqr, local_lws);
+ }
+ }
prof_stop( PROF_schedule_own_ogm );
@@ -1510,20 +1521,25 @@
{ODI,5,0,0, 0, 0,0,0,0,0, 0, 0, 0, 0, 0,
0, "\nScheduling options:"},
-
- //dispatch.c
- /*
- {ODI,5,0,"aggreg_per_ogi", 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &aggr_p_ogi, MIN_AGGR_P_OGI, MAX_AGGR_P_OGI, DEF_AGGR_P_OGI, 0,
- ARG_VALUE_FORM, "set number of OGM aggregations per originator interval"},
- */
-//dispatch.c
- {ODI,5,0,ARG_AGGR_ITERVAL, 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &aggr_interval, 40, 4000, 300, 0,
+
+ {ODI,5,0,ARG_OGI, 'o',A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &my_ogi, MIN_OGI, MAX_OGI, DEF_OGI, 0,
+ ARG_VALUE_FORM, "set interval in ms with which new originator message (OGM) are send"},
+
+ {ODI,5,0,ARG_OGI_PWRSAVE, 0,A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &ogi_pwrsave, MIN_OGI, MAX_OGI, MIN_OGI, 0,
+ ARG_VALUE_FORM, "enable power-saving feature by setting increased OGI when no other nodes are in range"},
+
+ {ODI,5,0,ARG_AGGR_IVAL, 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &aggr_interval, MIN_AGGR_IVAL, MAX_AGGR_IVAL, DEF_AGGR_IVAL, 0,
ARG_VALUE_FORM, "set aggregation interval (SHOULD be smaller than the half of your and others OGM interval)"},
-
-// dispatch.c
{ODI,5,0,ARG_UDPD_SIZE, 0, A_PS1,A_ADM,A_DYI,A_CFA,A_ANY, &pref_udpd_size,MIN_UDPD_SIZE, MAX_UDPD_SIZE, DEF_UDPD_SIZE, 0,
ARG_VALUE_FORM, "set preferred udp-data size for send packets"}
+#ifndef LESS_OPTIONS
+#ifndef NOPARANOIA
+ ,{ODI,5,0,"simulate_cleanup", 0, A_PS1,A_ADM,A_DYI,A_ARG,A_ANY, &sim_paranoia, NO, YES, DEF_SIM_PARA, 0,
+ ARG_VALUE_FORM, "simulate paranoia and cleanup_all for testing"}
+#endif
+#endif
+
};
@@ -1543,7 +1559,7 @@
void start_schedule( void ) {
- register_task( 50+rand_num(100), send_outstanding_ogms, NULL );
+ register_task( 50+rand_num(100), aggregate_outstanding_ogms, NULL );
}
@@ -1556,10 +1572,9 @@
struct send_node *send_node = list_entry( list_pos, struct send_node, list );
list_del( (struct list_head *)&send_list, list_pos, &send_list );
+
+ debugFree(send_node, 1106);
- if ( !send_node->own_if )
- debugFree( send_node, 1106 );
-
}
list_for_each_safe( list_pos, list_pos_tmp, &task_list ) {
Modified: trunk/batman-experimental/schedule.h
===================================================================
--- trunk/batman-experimental/schedule.h 2010-04-12 19:06:37 UTC (rev 1633)
+++ trunk/batman-experimental/schedule.h 2010-04-15 08:16:16 UTC (rev 1634)
@@ -17,9 +17,20 @@
*
*/
+#define ARG_OGI "ogm_interval"
+#define DEF_OGI 1000
+#define MIN_OGI 50
+#define MAX_OGI 100000
+extern int32_t my_ogi; // my originator interval
-#define ARG_AGGR_ITERVAL "aggreg_interval"
+#define ARG_OGI_PWRSAVE "ogi_power_save"
+
+#define MIN_AGGR_IVAL 35
+#define MAX_AGGR_IVAL 4000
+#define DEF_AGGR_IVAL 500
+#define ARG_AGGR_IVAL "aggreg_interval"
+
void init_schedule( void );
void start_schedule( void );
void change_selects( void );
12 years, 9 months
r1633 - trunk/batman-adv-kernelland
by postmaster@open-mesh.net
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;
}
12 years, 9 months
r1632 - trunk/batman-adv-kernelland
by postmaster@open-mesh.net
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);
12 years, 9 months