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 );