Automated merge with http://gredler.at/hg/olsrd/
authorHannes Gredler <hannes@gredler.at>
Mon, 19 May 2008 12:14:25 +0000 (14:14 +0200)
committerHannes Gredler <hannes@gredler.at>
Mon, 19 May 2008 12:14:25 +0000 (14:14 +0200)
63 files changed:
Makefile.inc
files/olsrd.conf.default.lq
files/olsrd.conf.default.lq-fisheye
files/olsrd.conf.default.rfc
files/olsrd.conf.win32.lq
files/olsrd.conf.win32.rfc
lib/bmf/src/NetworkInterfaces.c
lib/dot_draw/src/olsrd_dot_draw.c
lib/httpinfo/src/admin_interface.c
lib/httpinfo/src/olsrd_httpinfo.c
lib/lq_etx_fpm/README_LQ_ETX_FPM
lib/lq_etx_fpm/src/lq_etx_fpm_plugin.c
lib/lq_etx_fpm/src/lq_etx_fpm_plugin.h
lib/nameservice/README_NAMESERVICE
lib/nameservice/src/nameservice.c
lib/tas/src/plugin.c
lib/txtinfo/src/olsrd_txtinfo.c
src/bsd/kernel_routes.c
src/bsd/net.c
src/cfgparser/cfgfile_gen.c
src/cfgparser/olsrd_conf.c
src/cfgparser/oparse.y
src/cfgparser/oscan.lex
src/common/avl.c
src/defs.h
src/duplicate_set.c
src/duplicate_set.h
src/fpm.c
src/hashing.c
src/hna_set.c
src/hna_set.h
src/interfaces.c
src/interfaces.h
src/link_set.c
src/link_set.h
src/lq_packet.c
src/lq_packet.h
src/lq_plugin.c
src/lq_plugin.h
src/lq_plugin_default.c [deleted file]
src/lq_plugin_default_float.c [new file with mode: 0644]
src/lq_plugin_default_float.h [moved from src/lq_plugin_default.h with 65% similarity]
src/lq_plugin_default_fpm.c [moved from lib/lq_etx_fpm/src/lq_etx_fpm.c with 53% similarity]
src/lq_plugin_default_fpm.h [moved from lib/lq_etx_fpm/src/lq_etx_fpm.h with 65% similarity]
src/main.c
src/mpr_selector_set.c
src/olsr.c
src/olsr_cfg.h
src/olsr_cookie.c
src/olsr_cookie.h
src/olsr_spf.c [moved from src/lq_route.c with 99% similarity]
src/olsr_spf.h [moved from src/lq_route.h with 97% similarity]
src/packet.c
src/process_routes.c
src/routing_table.c
src/routing_table.h
src/scheduler.c
src/scheduler.h
src/tc_set.c
src/tc_set.h
src/two_hop_neighbor_table.c
src/two_hop_neighbor_table.h
src/unix/ifnet.c

index 3f59450..056bf0c 100644 (file)
@@ -5,13 +5,13 @@
 #
 
 # activate debugging with 1 or deactivate with 0
-DEBUG ?= 0
+DEBUG ?= 1
 
 # compile OLSR_PRINTF out
-NO_DEBUG_MESSAGES ?= 0
+NO_DEBUG_MESSAGES ?= 1
 
 # the optimize option to be set for gcc
-OPTIMIZE ?= -O2
+OPTIMIZE ?= 
 
 # enable mudflap with 1 or deactivate with 0
 # you need a recent enough gcc and the libmudflap installed
@@ -97,7 +97,7 @@ ifeq ($(DEBUG),0)
 WARNINGS +=    -fomit-frame-pointer
 endif
 # we have small inline functions in src/lq_route.h which should always be inlined
-WARNINGS +=    -finline-limit=100
+WARNINGS +=    -finline-limit=350
 # These tell gcc to put each function and global variable in a separate section.
 # The linker can than remove all unreferenced section. But in the olsrd binary
 # unused doesn't imply unused at all since the function may be used by plugins,
@@ -179,7 +179,7 @@ OBJS +=             $(SRCS:%.c=%.o)
 # debugging or non-debugging flags
 ifeq ($(DEBUG),1)
 CPPFLAGS +=    -DDEBUG
-CFLAGS +=      -g
+CFLAGS +=      -ggdb
 else
 CPPFLAGS +=    -DNDEBUG
 endif
index 1b8cd05..012f841 100644 (file)
@@ -127,10 +127,15 @@ UseHysteresis     no
 
 LinkQualityLevel       2
 
-# Link quality window size
-# Defaults to 10
+# Link quality aging factor
+# Defaults to 0.1, smaller values mean faster reaction to changing links
 
-LinkQualityWinSize     12
+#LinkQualityAging 0.1 
+
+# Link quality algorithm
+# Defaults to "etx_fpm" for fixpoint based etx algorithm
+
+#LinkQualityAlgorithm    "etx_fpm"
 
 # Polling rate in seconds(float). 
 # Default value 0.05 sec
index c7e695a..21f0a0c 100644 (file)
@@ -239,10 +239,15 @@ UseHysteresis     no
 
 LinkQualityLevel       2
 
-# Link quality window size
-# Defaults to 10
+# Link quality aging factor
+# Defaults to 0.1, smaller values mean faster reaction to changing links
 
-LinkQualityWinSize     100
+#LinkQualityAging 0.1 
+
+# Link quality algorithm
+# Defaults to "etx_fpm" for fixpoint based etx algorithm
+
+#LinkQualityAlgorithm    "etx_fpm"
 
 # Polling rate in seconds(float). 
 # Default value 0.05 sec
index 11bb224..58f6c74 100644 (file)
@@ -122,10 +122,9 @@ HystThrLow 0.30
 
 #LinkQualityLevel      0
 
-# Link quality window size
-# Defaults to 10
-
-#LinkQualityWinSize    12
+# Link quality aging factor
+# Defaults to 0.05, smaller values mean larger LQ window size
+# LinkQualityAging 0.1 
 
 # Polling rate in seconds(float). 
 # Default value 0.05 sec
index f71f26a..caa572d 100644 (file)
@@ -31,11 +31,9 @@ ClearScreen          no
 \r
 LinkQualityLevel       2\r
 \r
-#\r
-# Windows size for packet loss calculation\r
-#\r
-\r
-LinkQualityWinSize     12\r
+# Link quality aging factor\r
+# Defaults to 0.05, smaller values mean larger LQ window size\r
+LinkQualityAging 0.1 \r
 \r
 #\r
 # Do not use hysteresis\r
index fe76d27..b388807 100644 (file)
@@ -31,11 +31,9 @@ ClearScreen          no
 \r
 LinkQualityLevel       0\r
 \r
-#\r
-# Windows size for packet loss calculation\r
-#\r
-\r
-LinkQualityWinSize     12\r
+# Link quality aging factor\r
+# Defaults to 0.05, smaller values mean larger LQ window size\r
+LinkQualityAging 0.1 \r
 \r
 #\r
 # Do not use hysteresis\r
index efbaaff..38f3c31 100644 (file)
@@ -61,7 +61,6 @@
 #include "ipcalc.h"
 #include "defs.h" /* olsr_cnf */
 #include "link_set.h" /* get_link_set() */
-#include "lq_route.h" /* MIN_LINK_QUALITY */
 #include "tc_set.h" /* olsr_lookup_tc_entry(), olsr_lookup_tc_edge() */
 #include "net_olsr.h" /* ipequal */
 #include "lq_plugin.h"
index 95c20d5..7b265d0 100644 (file)
@@ -265,9 +265,8 @@ ipc_action(int fd __attribute__((unused)))
     return;
   }
   olsr_printf(1, "(DOT DRAW)IPC: Connection from %s\n", inet_ntoa(pin.sin_addr));
-  close(ipc_connection); /* close connection after one output */
   pcf_event(1, 1, 1);
-  close(ipc_connection); // close connection after one output
+  close(ipc_connection); /* close connection after one output */
 }
 
 
index 781f8a8..335156c 100644 (file)
@@ -138,8 +138,8 @@ build_admin_body(char *buf, olsr_u32_t bufsize __attribute__((unused)))
   if(olsr_cnf->lq_level) {
     size += snprintf(&buf[size], bufsize-size, admin_basic_setting_int,
                      "LQ level:", "lq_level", 1, olsr_cnf->lq_level);
-    size += snprintf(&buf[size], bufsize-size, admin_basic_setting_int,
-                     "LQ winsize:", "lq_wsize", 2, olsr_cnf->lq_wsize);
+    size += snprintf(&buf[size], bufsize-size, admin_basic_setting_float,
+                     "LQ aging:", "lq_aging", 2, olsr_cnf->lq_aging);
   } else {
     size += snprintf(&buf[size], bufsize-size, "<td>LQ disabled</td>\n");
   }
index 3235478..00dc72f 100644 (file)
@@ -872,9 +872,9 @@ static int build_config_body(char *buf, olsr_u32_t bufsize)
     if (olsr_cnf->lq_level) {
       size += snprintf(&buf[size], bufsize-size,
                        "<td>LQ level: %d</td>\n"
-                       "<td>LQ winsize: %d</td>\n",
+                       "<td>LQ aging: %f</td>\n",
                        olsr_cnf->lq_level,
-                       olsr_cnf->lq_wsize);
+                       olsr_cnf->lq_aging);
     }
     size += snprintf(&buf[size], bufsize-size, "</tr></table>\n");
 
@@ -1053,6 +1053,7 @@ static int build_topo_body(char *buf, olsr_u32_t bufsize)
   OLSR_FOR_ALL_TC_ENTRIES(tc) {
       struct tc_edge_entry *tc_edge;
       OLSR_FOR_ALL_TC_EDGE_ENTRIES(tc, tc_edge) {
+       if (tc_edge->edge_inv)  {
           size += snprintf(&buf[size], bufsize-size, "<tr>");
           size += build_ipaddr_with_link(&buf[size], bufsize, &tc_edge->T_dest_addr, -1);
           size += build_ipaddr_with_link(&buf[size], bufsize, &tc->addr, -1);
@@ -1064,7 +1065,7 @@ static int build_topo_body(char *buf, olsr_u32_t bufsize)
                                get_linkcost_text(tc_edge->cost, OLSR_FALSE, &lqbuffer2));
           }
           size += snprintf(&buf[size], bufsize-size, "</tr>\n");
-
+       }
       } OLSR_FOR_ALL_TC_EDGE_ENTRIES_END(tc, tc_edge);
   } OLSR_FOR_ALL_TC_ENTRIES_END(tc);
 
index 8796b10..52ef2c7 100644 (file)
@@ -13,7 +13,6 @@ add in /etc/olsrd.conf:
 
 LoadPlugin "lq_etx_fpm.so.0.1"
 {
-    PlParam "alpha" "0.05"
 }
 
 
index 19158f2..eecf161 100644 (file)
@@ -64,11 +64,9 @@ int olsrd_plugin_interface_version(void)
     return PLUGIN_INTERFACE_VERSION;
 }
 
-
-static int set_alpha(const char *value, void *data __attribute__((unused)), set_plugin_parameter_addon addon __attribute__((unused)))
-{
-    set_lq_etx_fpm_alpha(atofpm(value));
-    return 0;
+int olsrd_plugin_init(void) {
+  set_lq_handler(&lq_etx_fpm_handler, LQ_ETX_FPM_HANDLER_NAME);
+  return 1;
 }
 
 /**
@@ -76,7 +74,6 @@ static int set_alpha(const char *value, void *data __attribute__((unused)), set_
  * Called for all plugin parameters
  */
 static const struct olsrd_plugin_parameters plugin_parameters[] = {
-    { .name = "alpha",   .set_plugin_parameter = &set_alpha,      .data = NULL },
 };
 
 void olsrd_get_plugin_parameters(const struct olsrd_plugin_parameters **params, int *size)
@@ -84,15 +81,6 @@ void olsrd_get_plugin_parameters(const struct olsrd_plugin_parameters **params,
     *params = plugin_parameters;
     *size = sizeof(plugin_parameters)/sizeof(*plugin_parameters);
 }
-/**
- * Initialize plugin
- * Called after all parameters are passed
- */
-int
-olsrd_plugin_init(void)
-{
-  return init_lq_etx_fpm();
-}
 
 
 /****************************************************************************
index 2fc2e04..d56cf6f 100644 (file)
@@ -48,9 +48,6 @@
 
 
 /* Initialization function */
-int
-olsrd_plugin_init(void);
-
 int 
 olsrd_plugin_interface_version(void);
 
index 3b5149e..d9598f3 100644 (file)
@@ -101,6 +101,23 @@ PlParam "latlon-infile" "name-of-input.txt"
        latitude and longitude to this file. Will overwrite the
        "lat" and "lon" parameters during runtime.
 
+PlParam "sighup-pid-file" "/path/to/pidfile.pid"
+        (*nix systems only) Sends a HUP signal to the process specified
+        by the pidfile (usually /var/run/dnsmasq.pid) when the host name
+        table changes. This is useful for letting dnsmasq or bind know
+        they have to reload their hosts file.
+
+PlParam "name-change-script" "/path/to/script"
+        Script to execute when there is a change in the hosts names
+        table. Useful for executing a script that uses the hosts file
+        to keep a website or a database updated.
+
+PlParam "services-change-script" "/path/to/script"
+        Similar to the previous parameter. Script to execute when there
+        is a change in the services list propagated by the nameserver
+        plugin. Useful for executing a script that uses the services file
+        to keep a website or a database updated.
+
 ---------------------------------------------------------------------
 SAMPLE CONFIG
 ---------------------------------------------------------------------
@@ -135,15 +152,22 @@ UNIX VARIANTS:
        if you want to make the names available via ordinary DNS
        you can use dnsmasq to read the hosts file and serve it to
        users. add "addn-hosts=/var/run/hosts_olsr" to dnsmasq.conf 
-       and restart dnsmasq
+        and:
+               PlParam "sighup-pid-file" "/var/run/dnsmasq.pid"
+
+        to your nameservice plugin configuration.
+
+        This is especially usefull for infrastructure mesh networks that
+        can't afford to run olsrd on all the clients but wish to provide
+        DNS to them. This is solved by running dnsmasq and olsrd with
+        this setup on "edge" nodes that provide connectivity.
 
 WINDOWS:
 
 * overwrite C:\WINDOWS\system32\drivers\etc\hosts
        be sure you have nothing in the file which you still need 
        and configure the plugin with
-       PlParam "filename" "C:\WINDOWS\system32\drivers\etc\hosts"
-
+        PlParam "hosts-file" "C:\WINDOWS\system32\drivers\etc\hosts"
 
 ---------------------------------------------------------------------
 TODO
index ca11ebd..645dc64 100644 (file)
@@ -43,6 +43,9 @@
 #include <ctype.h>
 #include <sys/types.h>
 #include <regex.h>
+#include <sys/stat.h>
+#include <signal.h>
+#include <fcntl.h>
 
 #include "olsr.h"
 #include "ipcalc.h"
 
 /* config parameters */
 static char my_hosts_file[MAX_FILE + 1];
+static char my_sighup_pid_file[MAX_FILE + 1];
+
 static char my_add_hosts[MAX_FILE + 1];
 static char my_suffix[MAX_SUFFIX];
 static int my_interval = EMISSION_INTERVAL;
 static double my_timeout = NAME_VALID_TIME;
 static char my_resolv_file[MAX_FILE +1];
 static char my_services_file[MAX_FILE + 1];
+static char my_name_change_script[MAX_FILE + 1];
+static char my_services_change_script[MAX_FILE + 1];
 static char latlon_in_file[MAX_FILE + 1];
 static char my_latlon_file[MAX_FILE + 1];
 float my_lat = 0.0, my_lon = 0.0;
@@ -145,12 +152,15 @@ name_constructor(void)
        strcpy(my_hosts_file, "/var/run/hosts_olsr");
        strcpy(my_services_file, "/var/run/services_olsr");
        strcpy(my_resolv_file, "/var/run/resolvconf_olsr");
+       *my_sighup_pid_file = 0;
 #endif
 
        my_suffix[0] = '\0';
        my_add_hosts[0] = '\0';
        my_latlon_file[0] = '\0';
        latlon_in_file[0] = '\0';
+       my_name_change_script[0] = '\0';
+       my_services_change_script[0] = '\0';
        
        /* init the lists heads */
        for(i = 0; i < HASHSIZE; i++) {
@@ -240,7 +250,10 @@ static int set_nameservice_float(const char *value, void *data, set_plugin_param
 static const struct olsrd_plugin_parameters plugin_parameters[] = {
     { .name = "interval",      .set_plugin_parameter = &set_plugin_int,         .data = &my_interval },
     { .name = "timeout",       .set_plugin_parameter = &set_nameservice_float,  .data = &my_timeout },
+    { .name = "sighup-pid-file",.set_plugin_parameter = &set_plugin_string,      .data = &my_sighup_pid_file, .addon = {sizeof(my_sighup_pid_file)} },
     { .name = "hosts-file",    .set_plugin_parameter = &set_plugin_string,      .data = &my_hosts_file,    .addon = {sizeof(my_hosts_file)} },
+    { .name = "name-change-script", .set_plugin_parameter = &set_plugin_string,  .data = &my_name_change_script, .addon = {sizeof(my_name_change_script)} },
+    { .name = "services-change-script", .set_plugin_parameter = &set_plugin_string, .data = &my_services_change_script, .addon = {sizeof(my_services_change_script)} },
     { .name = "resolv-file",   .set_plugin_parameter = &set_plugin_string,      .data = &my_resolv_file,   .addon = {sizeof(my_resolv_file)} },
     { .name = "suffix",        .set_plugin_parameter = &set_plugin_string,      .data = &my_suffix,        .addon = {sizeof(my_suffix)} },
     { .name = "add-hosts",     .set_plugin_parameter = &set_plugin_string,      .data = &my_add_hosts,     .addon = {sizeof(my_add_hosts)} },
@@ -1008,6 +1021,51 @@ insert_new_name_in_list(union olsr_ip_addr *originator,
        }
 }
 
+#ifndef WIN32
+static void
+send_sighup_to_pidfile(char * pid_file){
+       int fd;
+       int i=0;
+       int result;
+       pid_t ipid;
+       char line[20];
+       char * endptr;
+
+       fd = open(pid_file, O_RDONLY);
+       if (fd<0) {
+               OLSR_PRINTF(2, "NAME PLUGIN: can't open file %s\n", pid_file);
+               return;
+       }
+
+       while (i<19) {
+               result = read(fd, line+i, 19-i);
+               if (!result) { /* EOF */
+                       break;
+               } else if (result>0) {
+                       i += result;
+               } else if(errno!=EINTR && errno!=EAGAIN) {
+                       OLSR_PRINTF(2, "NAME PLUGIN: can't read file %s\n", pid_file);
+                       return;
+               }
+       }
+       line[i]=0;
+       close(fd);
+       ipid = strtol(line, &endptr, 0);
+       if (endptr==line) {
+               OLSR_PRINTF(2, "NAME PLUGIN: invalid pid at file %s\n", pid_file);
+               return; 
+       }
+
+       result=kill(ipid, SIGHUP);
+       if (result==0){
+               OLSR_PRINTF(2, "NAME PLUGIN: SIGHUP sent to pid %i\n", ipid);   
+       } else {
+               OLSR_PRINTF(2, "NAME PLUGIN: failed to send SIGHUP to pid %i\n", ipid);
+       }
+
+}
+#endif
+
 /**
  * write names to a file in /etc/hosts compatible format
  */
@@ -1131,7 +1189,22 @@ write_hosts_file(void)
        }
          
        fclose(hosts);
+
+#ifndef WIN32
+       if (*my_sighup_pid_file)
+               send_sighup_to_pidfile(my_sighup_pid_file);
+#endif
        name_table_changed = OLSR_FALSE;
+
+       // Executes my_name_change_script after writing the hosts file
+        if (my_name_change_script[0] != '\0') {
+               if(system(my_name_change_script) != -1) {
+                       OLSR_PRINTF(2, "NAME PLUGIN: Name changed, %s executed\n", my_name_change_script);
+               }
+               else {
+                       OLSR_PRINTF(2, "NAME PLUGIN: WARNING! Failed to execute %s on hosts change\n", my_name_change_script);
+               }
+       }
 }
 
 
@@ -1201,6 +1274,16 @@ write_services_file(void)
          
        fclose(services_file);
        service_table_changed = OLSR_FALSE;
+       
+       // Executes my_services_change_script after writing the services file
+       if (my_services_change_script[0] != '\0') {
+               if(system(my_services_change_script) != -1) {
+                       OLSR_PRINTF(2, "NAME PLUGIN: Service changed, %s executed\n", my_services_change_script);
+               }
+               else {
+                       OLSR_PRINTF(2, "NAME PLUGIN: WARNING! Failed to execute %s on service change\n", my_services_change_script);
+               }
+       }
 }
 
 /**
index cfc9e7d..7c626a3 100644 (file)
@@ -64,7 +64,6 @@
 #include <hna_set.h>
 #include <routing_table.h>
 #include <olsr_protocol.h>
-#include <lq_route.h>
 #include <mpr_selector_set.h>
 #include <duplicate_set.h>
 #include <lq_plugin.h>
index 3ae0ca3..9252f03 100644 (file)
@@ -400,6 +400,7 @@ static void ipc_print_topology(void)
     OLSR_FOR_ALL_TC_ENTRIES(tc) {
         struct tc_edge_entry *tc_edge;
         OLSR_FOR_ALL_TC_EDGE_ENTRIES(tc, tc_edge) {
+               if (tc_edge->edge_inv)  {
             struct ipaddr_str dstbuf, addrbuf;
             struct lqtextbuffer lqbuffer1, lqbuffer2;
             ipc_sendf( "%s\t%s\t%s\t%s\n", 
@@ -407,7 +408,7 @@ static void ipc_print_topology(void)
                        olsr_ip_to_string(&addrbuf, &tc->addr), 
                        get_tc_edge_entry_text(tc_edge, &lqbuffer1),
                        get_linkcost_text(tc_edge->cost, OLSR_FALSE, &lqbuffer2));
-
+               }
         } OLSR_FOR_ALL_TC_EDGE_ENTRIES_END(tc, tc_edge);
     } OLSR_FOR_ALL_TC_ENTRIES_END(tc);
 
index 6161b04..b866566 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
  * The olsr.org Optimized Link-State Routing daemon(olsrd)
  * Copyright (c) 2004, Thomas Lopatic (thomas@lopatic.de)
 #include "ipcalc.h"
 
 #include <net/if_dl.h>
-#include <ifaddrs.h>
+#include <net/ifaddrs.h>
+
+#ifdef _WRS_KERNEL
+#include <wrn/coreip/net/route.h>
+#include <m2Lib.h>
+#define OLSR_PID taskIdSelf ()
+#else
+#define OLSR_PID getpid ()
+#endif
 
 static unsigned int seq = 0;
 
-static int add_del_route(const struct rt_entry *rt, int add)
+/*
+ * Sends an add or delete message via the routing socket.
+ * The message consists of:
+ *  - a header i.e. struct rt_msghdr
+ *  - 0-8 socket address structures
+ */
+static int
+add_del_route(const struct rt_entry *rt, int add)
 {
-  struct rt_msghdr *rtm;
+  struct rt_msghdr *rtm;              /* message to configure a route */
+                                       /* contains data to be written to the
+                                          routing socket */
   unsigned char buff[512];
-  unsigned char *walker;
-  struct sockaddr_in sin;
-  struct sockaddr_dl *sdl;
+  unsigned char *walker;              /* points within the buffer */
+  struct sockaddr_in sin;             /* internet style sockaddr */
+  struct sockaddr_dl *sdl;            /* link level sockaddr */
   struct ifaddrs *addrs;
   struct ifaddrs *awalker;
   const struct rt_nexthop *nexthop;
-  union olsr_ip_addr mask;
-  int step, step2;
-  int len;
-  int flags;
+  union olsr_ip_addr mask;            /* netmask as ip address */
+  int sin_size, sdl_size;              /* size of addresses - e.g. destination
+                                          (payload of the message) */
+  int len;                             /* message size written to routing socket */
 
   if (add) {
-      OLSR_PRINTF(2, "KERN: Adding %s\n", olsr_rtp_to_string(rt->rt_best));
+    OLSR_PRINTF(2, "KERN: Adding %s\n", olsr_rtp_to_string(rt->rt_best));
   } else {
-      OLSR_PRINTF(2, "KERN: Deleting %s\n", olsr_rt_to_string(rt));
+    OLSR_PRINTF(2, "KERN: Deleting %s\n", olsr_rt_to_string(rt));
   }
 
-  memset(buff, 0, sizeof (buff));
-  memset(&sin, 0, sizeof (sin));
+  memset(buff, 0, sizeof(buff));
+  memset(&sin, 0, sizeof(sin));
 
-  sin.sin_len = sizeof (sin);
+  sin.sin_len = sizeof(sin);
   sin.sin_family = AF_INET;
 
-  step = 1 + ((sizeof (struct sockaddr_in) - 1) | 3);
-  step2 = 1 + ((sizeof (struct sockaddr_dl) - 1) | 3);
-
-  rtm = (struct rt_msghdr *)buff;
-
-  flags = olsr_rt_flags(rt);
+  sin_size = 1 + ((sizeof(struct sockaddr_in) - 1) | 3);
+  sdl_size = 1 + ((sizeof(struct sockaddr_dl) - 1) | 3);
 
-  // the host is directly reachable, so use cloning and a /32 net
-  // routing table entry
+  /**********************************************************************
+   *                  FILL THE ROUTING MESSAGE HEADER
+   **********************************************************************/
 
-  if ((flags & RTF_GATEWAY) == 0)
-  {
-    flags |= RTF_CLONING;
-    flags &= ~RTF_HOST;
-  }
+  /* position header to the beginning of the buffer */
+  rtm = (struct rt_msghdr *)buff;
 
   rtm->rtm_version = RTM_VERSION;
-  rtm->rtm_type = (add != 0) ? RTM_ADD : RTM_DELETE;
-  rtm->rtm_index = 0;
-  rtm->rtm_flags = flags;
-  rtm->rtm_addrs = RTA_DST | RTA_NETMASK | RTA_GATEWAY;
+  rtm->rtm_type = add ? RTM_ADD : RTM_DELETE;
+  rtm->rtm_index = 0;          /* is ignored in outgoing messages */
+  /* RTF_UP [and RTF_HOST and/or RTF_GATEWAY] */
+  rtm->rtm_flags = olsr_rt_flags(rt);
+  rtm->rtm_pid = OLSR_PID;
   rtm->rtm_seq = ++seq;
 
-  walker = buff + sizeof (struct rt_msghdr);
+  /* walk to the end of the header */
+  walker = buff + sizeof(struct rt_msghdr);
+
+  /**********************************************************************
+   *                  SET  DESTINATION OF THE ROUTE
+   **********************************************************************/
+
+  rtm->rtm_addrs = RTA_DST;    /* part of the header */
 
   sin.sin_addr = rt->rt_dst.prefix.v4;
+  OLSR_PRINTF(8, "\t- Destination of the route: %s\n", inet_ntoa(sin.sin_addr));
 
-  memcpy(walker, &sin, sizeof (sin));
-  walker += step;
+  /* change proto or tos here */
+  OLSR_PRINTF(8, "\t- Setting Protocol: 0\n");
+  ((struct sockaddr_rt *)(&sin))->srt_proto = 0;
+  OLSR_PRINTF(8, "\t- Setting TOS: 0\n");
+  ((struct sockaddr_rt *)(&sin))->srt_tos = 0;
 
-  nexthop = olsr_get_nh(rt);
-  if ((flags & RTF_GATEWAY) != 0)
-  {
-    sin.sin_addr = nexthop->gateway.v4;
+  memcpy(walker, &sin, sizeof(sin));
+  walker += sin_size;
 
-    memcpy(walker, &sin, sizeof (sin));
-    walker += step;
-  }
+  /**********************************************************************
+   *                  SET GATEWAY OF THE ROUTE
+   **********************************************************************/
 
-  // the host is directly reachable, so add the output interface's
-  // MAC address
+  if (add || (rtm->rtm_addrs & RTF_GATEWAY)) {
+    rtm->rtm_addrs |= RTA_GATEWAY;     /* part of the header */
+    nexthop = olsr_get_nh(rt);
 
-  else
-  {
-    if (getifaddrs(&addrs))
-    {
-      fprintf(stderr, "getifaddrs() failed\n");
-      return -1;
+    if ((rtm->rtm_flags & RTF_GATEWAY)) {      /* GATEWAY */
+      sin.sin_addr = nexthop->gateway.v4;
+
+      memcpy(walker, &sin, sizeof(sin));
+      walker += sin_size;
+
+      OLSR_PRINTF(8, "\t- Gateway of the route: %s\n", inet_ntoa(sin.sin_addr));
     }
+    /* NO GATEWAY - destination is directly reachable */
+    else {
+      rtm->rtm_flags |= RTF_CLONING;   /* part of the header! */
+
+      /*
+       * Host is directly reachable, so add the output interface MAC address.
+       */
+      if (getifaddrs(&addrs)) {
+       fprintf(stderr, "\ngetifaddrs() failed\n");
+       return -1;
+      }
+
+      for (awalker = addrs; awalker != NULL; awalker = awalker->ifa_next)
+       if (awalker->ifa_addr->sa_family == AF_LINK &&
+           strcmp(awalker->ifa_name,
+                  if_ifwithindex_name(nexthop->iif_index)) == 0)
+         break;
+
+      if (awalker == NULL) {
+       fprintf(stderr, "\nInterface %s not found\n",
+               if_ifwithindex_name(nexthop->iif_index));
+       freeifaddrs(addrs);
+       return -1;
+      }
+
+      /* sdl is "struct sockaddr_dl" */
+      sdl = (struct sockaddr_dl *)awalker->ifa_addr;
+#ifdef DEBUG
+      OLSR_PRINTF(8,"\t- Link layer address of the non gateway route: %s\n",
+                  LLADDR(sdl));
+#endif
 
-    for (awalker = addrs; awalker != NULL; awalker = awalker->ifa_next)
-      if (awalker->ifa_addr->sa_family == AF_LINK &&
-          strcmp(awalker->ifa_name, if_ifwithindex_name(nexthop->iif_index)) == 0)
-        break;
+      memcpy(walker, sdl, sdl->sdl_len);
+      walker += sdl_size;
 
-    if (awalker == NULL)
-    {
-      fprintf(stderr, "interface %s not found\n", if_ifwithindex_name(nexthop->iif_index));
       freeifaddrs(addrs);
-      return -1;
     }
+  } else {
+    /* Route with no gateway is deleted */
+  }
 
-    sdl = (struct sockaddr_dl *)awalker->ifa_addr;
+  /**********************************************************************
+   *                         SET  NETMASK
+   **********************************************************************/
 
-    memcpy(walker, sdl, sdl->sdl_len);
-    walker += step2;
+  if ((rtm->rtm_flags & RTF_HOST)) {
+    OLSR_PRINTF(8, "\t- No netmask needed for a host route.\n");
+  } else {                     /* NO! hoste route */
 
-    freeifaddrs(addrs);
-  }
+    rtm->rtm_addrs |= RTA_NETMASK; /* part of the header */
 
-  if (!olsr_prefix_to_netmask(&mask, rt->rt_dst.prefix_len)) {
-    return -1;
+    if (!olsr_prefix_to_netmask(&mask, rt->rt_dst.prefix_len)) {
+      return -1;
+    }
+    sin.sin_addr = mask.v4;
+
+    memcpy(walker, &sin, sizeof(sin));
+    walker += sin_size;
+
+    OLSR_PRINTF(8, "\t- Netmask of the route: %s\n", inet_ntoa(sin.sin_addr));
   }
-  sin.sin_addr = mask.v4;
 
-  memcpy(walker, &sin, sizeof (sin));
-  walker += step;
+  /**********************************************************************
+   *           WRITE CONFIGURATION MESSAGE TO THE ROUTING SOCKET
+   **********************************************************************/
 
   rtm->rtm_msglen = (unsigned short)(walker - buff);
 
   len = write(olsr_cnf->rts, buff, rtm->rtm_msglen);
+  OLSR_PRINTF(8, "\nWrote %d bytes to rts socket (FD=%d)\n", len,
+             olsr_cnf->rts);
 
-  if (len < rtm->rtm_msglen)
-    fprintf(stderr, "cannot write to routing socket: %s\n", strerror(errno));
+  if (0 != rtm->rtm_errno || len < rtm->rtm_msglen) {
+    fprintf(stderr,
+           "\nCannot write to routing socket: (rtm_errno= 0x%x) (last error message: %s)\n",
+           rtm->rtm_errno, strerror(errno));
+  }
+
+  OLSR_PRINTF(8,
+             "\nWriting the following information to routing socket (message header):"
+             "\n\trtm_msglen: %u" "\n\trtm_version: %u" "\n\trtm_type: %u"
+             "\n\trtm_index: %u" "\n\trtm_flags: 0x%x" "\n\trtm_addrs: %u"
+             "\n\trtm_pid: 0x%x" "\n\trtm_seq: %u" "\n\trtm_errno: 0x%x"
+             "\n\trtm_use %u" "\n\trtm_inits: %u\n",
+             (unsigned int)rtm->rtm_msglen, (unsigned int)rtm->rtm_version,
+             (unsigned int)rtm->rtm_type, (unsigned int)rtm->rtm_index,
+             (unsigned int)rtm->rtm_flags, (unsigned int)rtm->rtm_addrs,
+             (unsigned int)rtm->rtm_pid, (unsigned int)rtm->rtm_seq,
+             (unsigned int)rtm->rtm_errno, (unsigned int)rtm->rtm_use,
+             (unsigned int)rtm->rtm_inits);
 
   return 0;
 }
 
-int olsr_ioctl_add_route(const struct rt_entry *rt)
+int
+olsr_ioctl_add_route(const struct rt_entry *rt)
 {
   return add_del_route(rt, 1);
 }
 
-int olsr_ioctl_del_route(const struct rt_entry *rt)
+int
+olsr_ioctl_del_route(const struct rt_entry *rt)
 {
   return add_del_route(rt, 0);
 }
 
-static int add_del_route6(const struct rt_entry *rt, int add)
+static int
+add_del_route6(const struct rt_entry *rt, int add)
 {
   struct rt_msghdr *rtm;
   unsigned char buff[512];
@@ -188,22 +270,22 @@ static int add_del_route6(const struct rt_entry *rt, int add)
   int len;
 
   if (add) {
-      OLSR_PRINTF(2, "KERN: Adding %s\n", olsr_rtp_to_string(rt->rt_best));
+    OLSR_PRINTF(2, "KERN: Adding %s\n", olsr_rtp_to_string(rt->rt_best));
   } else {
-      OLSR_PRINTF(2, "KERN: Deleting %s\n", olsr_rt_to_string(rt));
+    OLSR_PRINTF(2, "KERN: Deleting %s\n", olsr_rt_to_string(rt));
   }
 
-  memset(buff, 0, sizeof (buff));
-  memset(&sin6, 0, sizeof (sin6));
-  memset(&sdl, 0, sizeof (sdl));
+  memset(buff, 0, sizeof(buff));
+  memset(&sin6, 0, sizeof(sin6));
+  memset(&sdl, 0, sizeof(sdl));
 
-  sin6.sin6_len = sizeof (sin6);
+  sin6.sin6_len = sizeof(sin6);
   sin6.sin6_family = AF_INET6;
-  sdl.sdl_len = sizeof (sdl);
+  sdl.sdl_len = sizeof(sdl);
   sdl.sdl_family = AF_LINK;
 
-  step = 1 + ((sizeof (struct sockaddr_in6) - 1) | 3);
-  step_dl = 1 + ((sizeof (struct sockaddr_dl) - 1) | 3);
+  step = 1 + ((sizeof(struct sockaddr_in6) - 1) | 3);
+  step_dl = 1 + ((sizeof(struct sockaddr_dl) - 1) | 3);
 
   rtm = (struct rt_msghdr *)buff;
   rtm->rtm_version = RTM_VERSION;
@@ -213,53 +295,54 @@ static int add_del_route6(const struct rt_entry *rt, int add)
   rtm->rtm_addrs = RTA_DST | RTA_GATEWAY;
   rtm->rtm_seq = ++seq;
 
-  walker = buff + sizeof (struct rt_msghdr);
+  walker = buff + sizeof(struct rt_msghdr);
 
-  memcpy(&sin6.sin6_addr.s6_addr, &rt->rt_dst.prefix.v6, sizeof(struct in6_addr));
+  memcpy(&sin6.sin6_addr.s6_addr, &rt->rt_dst.prefix.v6,
+        sizeof(struct in6_addr));
 
-  memcpy(walker, &sin6, sizeof (sin6));
+  memcpy(walker, &sin6, sizeof(sin6));
   walker += step;
 
   nexthop = olsr_get_nh(rt);
-  if ((rtm->rtm_flags & RTF_GATEWAY) != 0)
-  {
-    memcpy(&sin6.sin6_addr.s6_addr, &nexthop->gateway.v6, sizeof(struct in6_addr));
+  if ((rtm->rtm_flags & RTF_GATEWAY) != 0) {
+    memcpy(&sin6.sin6_addr.s6_addr, &nexthop->gateway.v6,
+          sizeof(struct in6_addr));
 
     memset(&sin6.sin6_addr.s6_addr, 0, 8);
     sin6.sin6_addr.s6_addr[0] = 0xfe;
     sin6.sin6_addr.s6_addr[1] = 0x80;
     sin6.sin6_scope_id = nexthop->iif_index;
 #ifdef __KAME__
-    *(u_int16_t *)&sin6.sin6_addr.s6_addr[2] = htons(sin6.sin6_scope_id);
+    *(u_int16_t *) & sin6.sin6_addr.s6_addr[2] = htons(sin6.sin6_scope_id);
     sin6.sin6_scope_id = 0;
 #endif
-    memcpy(walker, &sin6, sizeof (sin6));
+    memcpy(walker, &sin6, sizeof(sin6));
     walker += step;
   }
 
-  // the host is directly reachable, so add the output interface's address
+  /* the host is directly reachable, so add the output interface's address */
 
-  else
-  {
-    memcpy(&sin6.sin6_addr.s6_addr,  &rt->rt_dst.prefix.v6, sizeof(struct in6_addr));
+  else {
+    memcpy(&sin6.sin6_addr.s6_addr, &rt->rt_dst.prefix.v6,
+          sizeof(struct in6_addr));
     memset(&sin6.sin6_addr.s6_addr, 0, 8);
     sin6.sin6_addr.s6_addr[0] = 0xfe;
     sin6.sin6_addr.s6_addr[1] = 0x80;
     sin6.sin6_scope_id = nexthop->iif_index;
 #ifdef __KAME__
-    *(u_int16_t *)&sin6.sin6_addr.s6_addr[2] = htons(sin6.sin6_scope_id);
+    *(u_int16_t *) & sin6.sin6_addr.s6_addr[2] = htons(sin6.sin6_scope_id);
     sin6.sin6_scope_id = 0;
 #endif
 
-    memcpy(walker, &sin6, sizeof (sin6));
+    memcpy(walker, &sin6, sizeof(sin6));
     walker += step;
     rtm->rtm_flags |= RTF_GATEWAY;
   }
 
-  if ((rtm->rtm_flags & RTF_HOST) == 0)
-  {
-    olsr_prefix_to_netmask((union olsr_ip_addr *)&sin6.sin6_addr, rt->rt_dst.prefix_len);
-    memcpy(walker, &sin6, sizeof (sin6));
+  if ((rtm->rtm_flags & RTF_HOST) == 0) {
+    olsr_prefix_to_netmask((union olsr_ip_addr *)&sin6.sin6_addr,
+                          rt->rt_dst.prefix_len);
+    memcpy(walker, &sin6, sizeof(sin6));
     walker += step;
     rtm->rtm_addrs |= RTA_NETMASK;
   }
@@ -275,7 +358,7 @@ static int add_del_route6(const struct rt_entry *rt, int add)
     struct rt_msghdr *drtm;
     unsigned char dbuff[512];
 
-    memset(dbuff, 0, sizeof (dbuff));
+    memset(dbuff, 0, sizeof(dbuff));
     drtm = (struct rt_msghdr *)dbuff;
     drtm->rtm_version = RTM_VERSION;
     drtm->rtm_type = RTM_DELETE;
@@ -284,10 +367,10 @@ static int add_del_route6(const struct rt_entry *rt, int add)
     drtm->rtm_flags = olsr_rt_flags(rt);
     drtm->rtm_seq = ++seq;
 
-    walker = dbuff + sizeof (struct rt_msghdr);
+    walker = dbuff + sizeof(struct rt_msghdr);
     memcpy(&sin6.sin6_addr.s6_addr, &rt->rt_dst.prefix.v6,
-       sizeof(struct in6_addr));
-    memcpy(walker, &sin6, sizeof (sin6));
+          sizeof(struct in6_addr));
+    memcpy(walker, &sin6, sizeof(sin6));
     walker += step;
     drtm->rtm_msglen = (unsigned short)(walker - dbuff);
     len = write(olsr_cnf->rts, dbuff, drtm->rtm_msglen);
@@ -302,12 +385,14 @@ static int add_del_route6(const struct rt_entry *rt, int add)
   return 0;
 }
 
-int olsr_ioctl_add_route6(const struct rt_entry *rt)
+int
+olsr_ioctl_add_route6(const struct rt_entry *rt)
 {
   return add_del_route6(rt, 1);
 }
 
-int olsr_ioctl_del_route6(const struct rt_entry *rt)
+int
+olsr_ioctl_del_route6(const struct rt_entry *rt)
 {
   return add_del_route6(rt, 0);
 }
index 401b38c..7515f68 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
  * The olsr.org Optimized Link-State Routing daemon(olsrd)
  * Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
 #include "../defs.h"
 #include "../net_os.h"
 #include "../ipcalc.h"
-#include "../parser.h" /* dnc: needed for call to packet_parser() */
+#include "../parser.h"         /* dnc: needed for call to packet_parser() */
 #include "../olsr_protocol.h"
 
-#include <sys/param.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <stdio.h>
 #include <netinet/in.h>
 #include <net/if.h>
 
+#ifdef _WRS_KERNEL
+#include <vxWorks.h>
+#include "wrn/coreip/netinet6/in6_var.h"
+#include <sockLib.h>
+#include <sys/socket.h>
+#include "wrn/coreip/net/ifaddrs.h"
+#include <selectLib.h>
+#include <logLib.h>
+#define syslog(a, b) fdprintf(a, b);
+#else
+#include <sys/param.h>
+#endif
+
+
 #ifdef __NetBSD__
 #include <net/if_ether.h>
 #endif
@@ -68,7 +82,7 @@
 #include <netinet/ip_icmp.h>
 #include <netinet/icmp_var.h>
 #include <netinet/icmp6.h>
-#include <netinet6/in6_var.h> /* For struct in6_ifreq */
+#include <netinet6/in6_var.h>  /* For struct in6_ifreq */
 #include <ifaddrs.h>
 #include <sys/uio.h>
 #include <net80211/ieee80211.h>
 #include <libnet.h>
 #endif /* SPOOF */
 
-//#define      SIOCGIFGENERIC  _IOWR('i', 58, struct ifreq)    /* generic IF get op */
-//#define SIOCGWAVELAN SIOCGIFGENERIC
+#if 0
+#define        SIOCGIFGENERIC  _IOWR('i', 58, struct ifreq)    /* generic IF get op */
+#define SIOCGWAVELAN SIOCGIFGENERIC
+#endif
 
 #include <sys/sysctl.h>
 
@@ -107,13 +123,14 @@ static int ignore_redir;
 static int send_redir;
 static int gateway;
 
-static int set_sysctl_int(const char *name, int new)
+static int
+set_sysctl_int(const char *name, int new)
 {
   int old;
 #if __MacOSX__ || __OpenBSD__
-  size_t len = sizeof (old);
+  size_t len = sizeof(old);
 #else
-  unsigned int len = sizeof (old);
+  unsigned int len = sizeof(old);
 #endif
 
 #ifdef __OpenBSD__
@@ -125,50 +142,45 @@ static int set_sysctl_int(const char *name, int new)
   mib[2] = IPPROTO_IP;
   mib[3] = IPCTL_FORWARDING;
 
-  if (!strcmp(name, "net.inet6.ip6.forwarding"))
-  {
+  if (!strcmp(name, "net.inet6.ip6.forwarding")) {
     mib[1] = PF_INET6;
     mib[2] = IPPROTO_IPV6;
-  }
-  else if (!strcmp(name, "net.inet.icmp.rediraccept"))
-  {
+  } else if (!strcmp(name, "net.inet.icmp.rediraccept")) {
     mib[2] = IPPROTO_ICMP;
     mib[3] = ICMPCTL_REDIRACCEPT;
-  }
-  else if (!strcmp(name, "net.inet6.icmp6.rediraccept"))
-  {
+  } else if (!strcmp(name, "net.inet6.icmp6.rediraccept")) {
     mib[2] = IPPROTO_ICMPV6;
     mib[3] = ICMPV6CTL_REDIRACCEPT;
-  }
-  else if (!strcmp(name, "net.inet.ip.redirect"))
-  {
+  } else if (!strcmp(name, "net.inet.ip.redirect")) {
     mib[3] = IPCTL_SENDREDIRECTS;
-  }
-  else if (!strcmp(name, "net.inet6.ip6.redirect"))
-  {
+  } else if (!strcmp(name, "net.inet6.ip6.redirect")) {
     mib[1] = PF_INET6;
     mib[2] = IPPROTO_IPV6;
     mib[3] = IPCTL_SENDREDIRECTS;
   }
 
-  if (sysctl(mib, 4, &old, &len, &new, sizeof (new)) < 0)
+  if (sysctl(mib, 4, &old, &len, &new, sizeof(new)) < 0)
     return -1;
 #else
 
-  if (sysctlbyname(name, &old, &len, &new, sizeof (new)) < 0)
+  if (sysctlbyname((char *)name, &old, &len, &new, sizeof(new)) < 0)
     return -1;
 #endif
 
   return old;
 }
 
-int enable_ip_forwarding(int version)
+int
+enable_ip_forwarding(int version)
 {
-  const char *name = version == AF_INET ? "net.inet.ip.forwarding" : "net.inet6.ip6.forwarding";
+  const char *name =
+    version == AF_INET ? "net.inet.ip.forwarding" : "net.inet6.ip6.forwarding";
 
   gateway = set_sysctl_int(name, 1);
   if (gateway < 0) {
-    fprintf(stderr, "Cannot enable IP forwarding. Please enable IP forwarding manually. Continuing in 3 seconds...\n");
+    fprintf(stderr,
+           "Cannot enable IP forwarding. Please enable IP forwarding manually."
+            " Continuing in 3 seconds...\n");
     sleep(3);
   }
 
@@ -180,7 +192,7 @@ disable_redirects_global(int version)
 {
   const char *name;
 
-  // do not accept ICMP redirects
+  /* do not accept ICMP redirects */
 
 #ifdef __OpenBSD__
   if (version == AF_INET)
@@ -190,13 +202,10 @@ disable_redirects_global(int version)
 
   ignore_redir = set_sysctl_int(name, 0);
 #elif defined __FreeBSD__ || defined __MacOSX__
-  if (version == AF_INET)
-  {
+  if (version == AF_INET) {
     name = "net.inet.icmp.drop_redirect";
     ignore_redir = set_sysctl_int(name, 1);
-  }
-  else
-  {
+  } else {
     name = "net.inet6.icmp6.rediraccept";
     ignore_redir = set_sysctl_int(name, 0);
   }
@@ -209,13 +218,14 @@ disable_redirects_global(int version)
   ignore_redir = set_sysctl_int(name, 1);
 #endif
 
-  if (ignore_redir < 0)
-    {
-      fprintf(stderr, "Cannot disable incoming ICMP redirect messages. Please disable them manually. Continuing in 3 seconds...\n");
-      sleep(3);
-    }
+  if (ignore_redir < 0) {
+    fprintf(stderr,
+           "Cannot disable incoming ICMP redirect messages. "
+            "Please disable them manually. Continuing in 3 seconds...\n");
+    sleep(3);
+  }
 
-  // do not send ICMP redirects
+  /* do not send ICMP redirects */
 
   if (version == AF_INET)
     name = "net.inet.ip.redirect";
@@ -223,48 +233,66 @@ disable_redirects_global(int version)
     name = "net.inet6.ip6.redirect";
 
   send_redir = set_sysctl_int(name, 0);
-  if (send_redir < 0)
-    {
-      fprintf(stderr, "Cannot disable outgoing ICMP redirect messages. Please disable them manually. Continuing in 3 seconds...\n");
-      sleep(3);
-    }
+  if (send_redir < 0) {
+    fprintf(stderr,
+           "Cannot disable outgoing ICMP redirect messages. "
+            "Please disable them manually. Continuing in 3 seconds...\n");
+    sleep(3);
+  }
 
   return 1;
 }
 
-int disable_redirects(const char *if_name __attribute__((unused)), struct interface *iface __attribute__((unused)), int version __attribute__((unused)))
+int
+disable_redirects(const char *if_name
+                 __attribute__ ((unused)), struct interface *iface
+                 __attribute__ ((unused)), int version
+                 __attribute__ ((unused)))
 {
-  // this function gets called for each interface olsrd uses; however,
-  // FreeBSD can only globally control ICMP redirects, and not on a
-  // per-interface basis; hence, only disable ICMP redirects in the "global"
-  // function
+  /*
+   *  this function gets called for each interface olsrd uses; however,
+   * FreeBSD can only globally control ICMP redirects, and not on a
+   * per-interface basis; hence, only disable ICMP redirects in the "global"
+   * function
+   */
   return 1;
 }
 
-int deactivate_spoof(const char *if_name __attribute__((unused)), struct interface *iface __attribute__((unused)), int version __attribute__((unused)))
+int
+deactivate_spoof(const char *if_name
+                __attribute__ ((unused)), struct interface *iface
+                __attribute__ ((unused)), int version __attribute__ ((unused)))
 {
   return 1;
 }
 
-int restore_settings(int version)
+int
+restore_settings(int version)
 {
-  // reset IP forwarding
-  const char *name = version == AF_INET ? "net.inet.ip.forwarding" : "net.inet6.ip6.forwarding";
+  /* reset IP forwarding */
+  const char *name =
+    version == AF_INET ? "net.inet.ip.forwarding" : "net.inet6.ip6.forwarding";
 
   set_sysctl_int(name, gateway);
 
-  // reset incoming ICMP redirects
+  /* reset incoming ICMP redirects */
 
 #ifdef __OpenBSD__
-  name = version == AF_INET ? "net.inet.icmp.rediraccept"   : "net.inet6.icmp6.rediraccept";
+  name =
+    version ==
+    AF_INET ? "net.inet.icmp.rediraccept" : "net.inet6.icmp6.rediraccept";
 #elif defined __FreeBSD__ || defined __MacOSX__
-  name = version == AF_INET ? "net.inet.icmp.drop_redirect" : "net.inet6.icmp6.rediraccept";
+  name =
+    version ==
+    AF_INET ? "net.inet.icmp.drop_redirect" : "net.inet6.icmp6.rediraccept";
 #else
-  name = version == AF_INET ? "net.inet.icmp.drop_redirect" : "net.inet6.icmp6.drop_redirect";
+  name =
+    version ==
+    AF_INET ? "net.inet.icmp.drop_redirect" : "net.inet6.icmp6.drop_redirect";
 #endif
   set_sysctl_int(name, ignore_redir);
 
-  // reset outgoing ICMP redirects
+  /* reset outgoing ICMP redirects */
   name = version == AF_INET ? "net.inet.ip.redirect" : "net.inet6.ip6.redirect";
   set_sysctl_int(name, send_redir);
   return 1;
@@ -284,187 +312,169 @@ gethemusocket(struct sockaddr_in *pin)
   OLSR_PRINTF(1, "       Connecting to switch daemon port 10150...");
 
 
-  if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) 
-    {
-      perror("hcsocket");
-      syslog(LOG_ERR, "hcsocket: %m");
-      return (-1);
-    }
+  if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+    perror("hcsocket");
+    syslog(LOG_ERR, "hcsocket: %m");
+    return (-1);
+  }
 
-  if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) 
-    {
-      perror("SO_REUSEADDR failed");
-      close(sock);
-      return (-1);
-    }
+  if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) {
+    perror("SO_REUSEADDR failed");
+    close(sock);
+    return (-1);
+  }
   /* connect to PORT on HOST */
-  if (connect(sock,(struct sockaddr *) pin, sizeof(*pin)) < 0) 
-    {
-      printf("FAILED\n");
-      fprintf(stderr, "Error connecting %d - %s\n", errno, strerror(errno));
-      printf("connection refused\n");
-      close(sock);
-      return (-1);
-    }
+  if (connect(sock, (struct sockaddr *)pin, sizeof(*pin)) < 0) {
+    printf("FAILED\n");
+    fprintf(stderr, "Error connecting %d - %s\n", errno, strerror(errno));
+    printf("connection refused\n");
+    close(sock);
+    return (-1);
+  }
 
   printf("OK\n");
 
-  /* Keep TCP socket blocking */  
+  /* Keep TCP socket blocking */
   return (sock);
 }
 
 
 int
-getsocket(int bufspace, char *int_name __attribute__((unused)))
+getsocket(int bufspace, char *int_name __attribute__ ((unused)))
 {
   struct sockaddr_in sin;
   int on;
   int sock = socket(AF_INET, SOCK_DGRAM, 0);
-  if (sock < 0) 
-    {
-      perror("socket");
-      syslog(LOG_ERR, "socket: %m");
-      return -1;
-    }
+  if (sock < 0) {
+    perror("socket");
+    syslog(LOG_ERR, "socket: %m");
+    return -1;
+  }
 
   on = 1;
-  if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0)
-    {
-      perror("setsockopt");
-      syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");
-      close(sock);
-      return -1;
-    }
+  if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&on, sizeof(on)) < 0) {
+    perror("setsockopt");
+    syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m");
+    close(sock);
+    return -1;
+  }
 
-  if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) 
-    {
-      perror("SO_REUSEADDR failed");
-      close(sock);
-      return -1;
-    }
+  if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) {
+    perror("SO_REUSEADDR failed");
+    close(sock);
+    return -1;
+  }
 
-  if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)) < 0) 
-    {
-      perror("SO_REUSEPORT failed");
-      close(sock);
-      return -1;
-    }
+  if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (char *)&on, sizeof(on)) < 0) {
+    perror("SO_REUSEPORT failed");
+    close(sock);
+    return -1;
+  }
 
-  if (setsockopt(sock, IPPROTO_IP, IP_RECVIF, &on, sizeof(on)) < 0) 
-    {
-      perror("IP_RECVIF failed");
-      close(sock);
-      return -1;
-    }
+  if (setsockopt(sock, IPPROTO_IP, IP_RECVIF, (char *)&on, sizeof(on)) < 0) {
+    perror("IP_RECVIF failed");
+    close(sock);
+    return -1;
+  }
 
-  for (on = bufspace; ; on -= 1024) 
-    {
-      if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &on, sizeof (on)) == 0)
-       break;
-      if (on <= 8*1024) 
-       {
-         perror("setsockopt");
-         syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m");
-         break;
-       }
+  for (on = bufspace;; on -= 1024) {
+    if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&on, sizeof(on)) == 0)
+      break;
+    if (on <= 8 * 1024) {
+      perror("setsockopt");
+      syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m");
+      break;
     }
+  }
 
-  memset(&sin, 0, sizeof (sin));
+  memset(&sin, 0, sizeof(sin));
   sin.sin_family = AF_INET;
   sin.sin_port = htons(OLSRPORT);
   sin.sin_addr.s_addr = INADDR_ANY;
-  if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) 
-    {
-      perror("bind");
-      syslog(LOG_ERR, "bind: %m");
-      close(sock);
-      return -1;
-    }
+  if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
+    perror("bind");
+    syslog(LOG_ERR, "bind: %m");
+    close(sock);
+    return -1;
+  }
 
   on = fcntl(sock, F_GETFL);
   if (on == -1) {
-      syslog(LOG_ERR, "fcntl (F_GETFL): %m\n");
+    syslog(LOG_ERR, "fcntl (F_GETFL): %m\n");
   } else {
-      if (fcntl(sock, F_SETFL, on|O_NONBLOCK) == -1) {
-          syslog(LOG_ERR, "fcntl O_NONBLOCK: %m\n");
-      }
+    if (fcntl(sock, F_SETFL, on | O_NONBLOCK) == -1) {
+      syslog(LOG_ERR, "fcntl O_NONBLOCK: %m\n");
+    }
   }
   return (sock);
 }
 
-int getsocket6(int bufspace, char *int_name __attribute__((unused)))
+int
+getsocket6(int bufspace, char *int_name __attribute__ ((unused)))
 {
   struct sockaddr_in6 sin;
   int on;
   int sock = socket(AF_INET6, SOCK_DGRAM, 0);
 
-  if (sock < 0) 
-    {
-      perror("socket");
-      syslog(LOG_ERR, "socket: %m");
-      return -1;
-    }
-
-  for (on = bufspace; ; on -= 1024) 
-    {
-      if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &on, sizeof (on)) == 0)
-          break;
-      if (on <= 8*1024) 
-       {
-         perror("setsockopt");
-         syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m");
-         break;
-       }
-    }
+  if (sock < 0) {
+    perror("socket");
+    syslog(LOG_ERR, "socket: %m");
+    return -1;
+  }
 
-  if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) 
-    {
-      perror("SO_REUSEADDR failed");
-      close(sock);
-      return -1;
+  for (on = bufspace;; on -= 1024) {
+    if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&on, sizeof(on)) == 0)
+      break;
+    if (on <= 8 * 1024) {
+      perror("setsockopt");
+      syslog(LOG_ERR, "setsockopt SO_RCVBUF: %m");
+      break;
     }
+  }
 
-  if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)) < 0) 
-    {
-      perror("SO_REUSEPORT failed");
-      close(sock);
-      return -1;
-    }
+  if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) {
+    perror("SO_REUSEADDR failed");
+    close(sock);
+    return -1;
+  }
 
+  if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, (char *)&on, sizeof(on)) < 0) {
+    perror("SO_REUSEPORT failed");
+    close(sock);
+    return -1;
+  }
 #ifdef IPV6_RECVPKTINFO
-  if (setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on)) < 0)
-    {
-      perror("IPV6_RECVPKTINFO failed");
-      close(sock);
-      return -1;
-    }
+  if (setsockopt(sock, IPPROTO_IPV6, IPV6_RECVPKTINFO, (char *)&on, sizeof(on))
+      < 0) {
+    perror("IPV6_RECVPKTINFO failed");
+    close(sock);
+    return -1;
+  }
 #elif defined IPV6_PKTINFO
-  if (setsockopt(sock, IPPROTO_IPV6, IPV6_PKTINFO, &on, sizeof(on)) < 0)
-    {
-      perror("IPV6_PKTINFO failed");
-      close(sock);
-      return -1;
-    }
+  if (setsockopt(sock, IPPROTO_IPV6, IPV6_PKTINFO, (char *)&on, sizeof(on)) < 0) {
+    perror("IPV6_PKTINFO failed");
+    close(sock);
+    return -1;
+  }
 #endif
 
   memset(&sin, 0, sizeof(sin));
   sin.sin6_family = AF_INET6;
   sin.sin6_port = htons(OLSRPORT);
-  if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0)
-    {
-      perror("bind");
-      syslog(LOG_ERR, "bind: %m");
-      close(sock);
-      return -1;
-    }
+  if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
+    perror("bind");
+    syslog(LOG_ERR, "bind: %m");
+    close(sock);
+    return -1;
+  }
 
   on = fcntl(sock, F_GETFL);
   if (on == -1) {
-      syslog(LOG_ERR, "fcntl (F_GETFL): %m\n");
+    syslog(LOG_ERR, "fcntl (F_GETFL): %m\n");
   } else {
-      if (fcntl(sock, F_SETFL, on|O_NONBLOCK) == -1) {
-          syslog(LOG_ERR, "fcntl O_NONBLOCK: %m\n");
-      }
+    if (fcntl(sock, F_SETFL, on | O_NONBLOCK) == -1) {
+      syslog(LOG_ERR, "fcntl O_NONBLOCK: %m\n");
+    }
   }
   return sock;
 }
@@ -481,40 +491,39 @@ join_mcast(struct interface *ifs, int sock)
   mcastreq.ipv6mr_multiaddr = ifs->int6_multaddr.sin6_addr;
   mcastreq.ipv6mr_interface = ifs->if_index;
 
-  OLSR_PRINTF(3, "Interface %s joining multicast %s...", ifs->int_name, olsr_ip_to_string(&addrstr, (union olsr_ip_addr *)&ifs->int6_multaddr.sin6_addr));
+  OLSR_PRINTF(3, "Interface %s joining multicast %s...", ifs->int_name,
+             olsr_ip_to_string(&addrstr,
+                               (union olsr_ip_addr *)&ifs->int6_multaddr.
+                               sin6_addr));
 
   /* rfc 3493 */
 #ifdef IPV6_JOIN_GROUP
   /* Join reciever group */
-  if(setsockopt(sock, 
-               IPPROTO_IPV6, 
-               IPV6_JOIN_GROUP, 
-               (char *)&mcastreq, 
-               sizeof(struct ipv6_mreq)) 
-     < 0)
+  if (setsockopt(sock,
+                IPPROTO_IPV6,
+                IPV6_JOIN_GROUP, (char *)&mcastreq, sizeof(struct ipv6_mreq))
+      < 0)
 #else /* rfc 2133, obsoleted */
   /* Join receiver group */
-  if(setsockopt(sock, 
-               IPPROTO_IPV6, 
-               IPV6_ADD_MEMBERSHIP, 
-               (char *)&mcastreq, 
-               sizeof(struct ipv6_mreq)) < 0)
-#endif 
-    {
-      perror("Join multicast send");
-      return -1;
-    }
+  if (setsockopt(sock,
+                IPPROTO_IPV6,
+                IPV6_ADD_MEMBERSHIP,
+                (char *)&mcastreq, sizeof(struct ipv6_mreq)) < 0)
+#endif
+  {
+    perror("Join multicast send");
+    return -1;
+  }
 
-  
-  if(setsockopt(sock, 
-               IPPROTO_IPV6, 
-               IPV6_MULTICAST_IF, 
-               (char *)&mcastreq.ipv6mr_interface, 
-               sizeof(mcastreq.ipv6mr_interface)) < 0)
-    {
-      perror("Set multicast if");
-      return -1;
-    }
+
+  if (setsockopt(sock,
+                IPPROTO_IPV6,
+                IPV6_MULTICAST_IF,
+                (char *)&mcastreq.ipv6mr_interface,
+                sizeof(mcastreq.ipv6mr_interface)) < 0) {
+    perror("Set multicast if");
+    return -1;
+  }
 
 
   OLSR_PRINTF(3, "OK\n");
@@ -524,7 +533,8 @@ join_mcast(struct interface *ifs, int sock)
 
 
 
-int get_ipv6_address(char *ifname, struct sockaddr_in6 *saddr6, int scope_in)
+int
+get_ipv6_address(char *ifname, struct sockaddr_in6 *saddr6, int scope_in)
 {
   struct ifaddrs *ifap, *ifa;
   const struct sockaddr_in6 *sin6 = NULL;
@@ -533,59 +543,47 @@ int get_ipv6_address(char *ifname, struct sockaddr_in6 *saddr6, int scope_in)
   int s6;
   u_int32_t flags6;
 
-  if (getifaddrs(&ifap) != 0)
-    {
-      OLSR_PRINTF(3, "get_ipv6_address: getifaddrs() failed.\n");
-      return 0;
-    }
+  if (getifaddrs(&ifap) != 0) {
+    OLSR_PRINTF(3, "get_ipv6_address: getifaddrs() failed.\n");
+    return 0;
+  }
 
-  for (ifa = ifap; ifa; ifa = ifa->ifa_next)
-    {
-      if (ifa->ifa_addr->sa_family == AF_INET6 &&
-          strcmp(ifa->ifa_name, ifname) == 0)
-        {
-         sin6 = (const struct sockaddr_in6 *)ifa->ifa_addr;
-         if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
-           continue;
-         strncpy(ifr6.ifr_name, ifname, sizeof(ifr6.ifr_name));
-         if ((s6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
-           {
-             OLSR_PRINTF(3, "socket(AF_INET6,SOCK_DGRAM)");
-             break;
-           }
-         ifr6.ifr_addr = *sin6;
-         if (ioctl(s6, SIOCGIFAFLAG_IN6, &ifr6) < 0)
-           {
-             OLSR_PRINTF(3, "ioctl(SIOCGIFAFLAG_IN6)");
-             close(s6);
-             break;
-           }
-         close(s6);
-         flags6 = ifr6.ifr_ifru.ifru_flags6;
-         if ((flags6 & IN6_IFF_ANYCAST) != 0)
-           continue;
-         if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))
-           {
-             if (scope_in)
-               {
-                 memcpy(&saddr6->sin6_addr, &sin6->sin6_addr,
-                        sizeof(struct in6_addr));
-                 found = 1;
-                 break;
-               }
-           }
-         else
-           {
-             if (scope_in == 0)
-               {
-                 memcpy(&saddr6->sin6_addr, &sin6->sin6_addr,
-                        sizeof(struct in6_addr));
-                 found = 1;
-                 break;
-               }
-           }
+  for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+    if ((ifa->ifa_addr->sa_family == AF_INET6) &&
+       (strcmp(ifa->ifa_name, ifname) == 0)) {
+      sin6 = (const struct sockaddr_in6 *)(ifa->ifa_addr);
+      if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
+       continue;
+      strncpy(ifr6.ifr_name, ifname, sizeof(ifr6.ifr_name));
+      if ((s6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
+       OLSR_PRINTF(3, "socket(AF_INET6,SOCK_DGRAM)");
+       break;
+      }
+      ifr6.ifr_addr = *sin6;
+      if (ioctl(s6, SIOCGIFAFLAG_IN6, (int)&ifr6) < 0) {
+       OLSR_PRINTF(3, "ioctl(SIOCGIFAFLAG_IN6)");
+       close(s6);
+       break;
+      }
+      close(s6);
+      flags6 = ifr6.ifr_ifru.ifru_flags6;
+      if ((flags6 & IN6_IFF_ANYCAST) != 0)
+       continue;
+      if (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
+       if (scope_in) {
+         memcpy(&saddr6->sin6_addr, &sin6->sin6_addr, sizeof(struct in6_addr));
+         found = 1;
+         break;
+       }
+      } else {
+       if (scope_in == 0) {
+         memcpy(&saddr6->sin6_addr, &sin6->sin6_addr, sizeof(struct in6_addr));
+         found = 1;
+         break;
        }
+      }
     }
+  }
   freeifaddrs(ifap);
   if (found)
     return 1;
@@ -605,12 +603,11 @@ static u_int16_t ip_id = 0;
 #endif /* SPOOF */
 
 ssize_t
-olsr_sendto(int s, 
-           const void *buf, 
-           size_t len, 
-           int flags __attribute__((unused)), 
-           const struct sockaddr *to, 
-           socklen_t tolen)
+olsr_sendto(int s,
+           const void *buf,
+           size_t len,
+           int flags __attribute__ ((unused)),
+           const struct sockaddr *to, socklen_t tolen)
 {
 #ifdef SPOOF
   /* IPv4 for now! */
@@ -618,89 +615,84 @@ olsr_sendto(int s,
   libnet_t *context;
   char errbuf[LIBNET_ERRBUF_SIZE];
   libnet_ptag_t udp_tag, ip_tag, ether_tag;
-  unsigned char enet_broadcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+  unsigned char enet_broadcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
   int status;
-  struct sockaddr_in *to_in = (struct sockaddr_in *) to;
+  struct sockaddr_in *to_in = (struct sockaddr_in *)to;
   u_int32_t destip;
   struct interface *iface;
 
   udp_tag = ip_tag = ether_tag = 0;
   destip = to_in->sin_addr.s_addr;
-  iface = if_ifwithsock (s);
+  iface = if_ifwithsock(s);
 
   /* initialize libnet */
   context = libnet_init(LIBNET_LINK, iface->int_name, errbuf);
-  if (context == NULL)
-    {
-      OLSR_PRINTF (1, "libnet init: %s\n", libnet_geterror (context));
-      return (0);
-    }
+  if (context == NULL) {
+    OLSR_PRINTF(1, "libnet init: %s\n", libnet_geterror(context));
+    return (0);
+  }
 
   /* initialize IP ID field if necessary */
-  if (ip_id == 0)
-    {
-      ip_id = (u_int16_t) (arc4random () & 0xffff);
-    }
+  if (ip_id == 0) {
+    ip_id = (u_int16_t) (arc4random() & 0xffff);
+  }
 
-  udp_tag = libnet_build_udp (698,                             /* src port */
-                             698,                              /* dest port */
-                             LIBNET_UDP_H + len,               /* length */
-                             0,                                /* checksum */
-                             buf,                              /* payload */
-                             len,                              /* payload size */
-                             context,                          /* context */
-                             udp_tag);                         /* pblock */
-  if (udp_tag == -1)
-    {
-      OLSR_PRINTF (1, "libnet UDP header: %s\n", libnet_geterror (context));
-       return (0);
-    }
+  udp_tag = libnet_build_udp(698,      /* src port */
+                            698,       /* dest port */
+                            LIBNET_UDP_H + len,        /* length */
+                            0, /* checksum */
+                            buf,       /* payload */
+                            len,       /* payload size */
+                            context,   /* context */
+                            udp_tag);  /* pblock */
+  if (udp_tag == -1) {
+    OLSR_PRINTF(1, "libnet UDP header: %s\n", libnet_geterror(context));
+    return (0);
+  }
 
-  ip_tag = libnet_build_ipv4 (LIBNET_IPV4_H + LIBNET_UDP_H + len, /* len */
-                             0,                                /* TOS */
-                             ip_id++,                          /* IP id */
-                             0,                                /* IP frag */
-                             1,                                /* IP TTL */
-                             IPPROTO_UDP,                      /* protocol */
-                             0,                                /* checksum */
-                             libnet_get_ipaddr4 (context),     /* src IP */
-                             destip,                           /* dest IP */
-                             NULL,                             /* payload */
-                             0,                                /* payload len */
-                             context,                          /* context */
-                             ip_tag);                          /* pblock */
-  if (ip_tag == -1)
-    {
-      OLSR_PRINTF (1, "libnet IP header: %s\n", libnet_geterror (context));
-      return (0);
-    }
+  ip_tag = libnet_build_ipv4(LIBNET_IPV4_H + LIBNET_UDP_H + len,       /* len */
+                            0, /* TOS */
+                            ip_id++,   /* IP id */
+                            0, /* IP frag */
+                            1, /* IP TTL */
+                            IPPROTO_UDP,       /* protocol */
+                            0, /* checksum */
+                            libnet_get_ipaddr4(context),       /* src IP */
+                            destip,    /* dest IP */
+                            NULL,      /* payload */
+                            0, /* payload len */
+                            context,   /* context */
+                            ip_tag);   /* pblock */
+  if (ip_tag == -1) {
+    OLSR_PRINTF(1, "libnet IP header: %s\n", libnet_geterror(context));
+    return (0);
+  }
 
-  ether_tag = libnet_build_ethernet (enet_broadcast,           /* ethernet dest */
-                                    libnet_get_hwaddr (context), /* ethernet source */
-                                    ETHERTYPE_IP,              /* protocol type */
-                                    NULL,                      /* payload */
-                                    0,                         /* payload size */
-                                    context,                   /* libnet handle */
-                                    ether_tag);                /* pblock tag */
-  if (ether_tag == -1)
-    {
-      OLSR_PRINTF (1, "libnet ethernet header: %s\n", libnet_geterror (context));
-      return (0);
-    }
-  status = libnet_write (context);
-  if (status == -1)
-    {
-      OLSR_PRINTF (1, "libnet packet write: %s\n", libnet_geterror (context));
-      return (0);
-    }
+  ether_tag = libnet_build_ethernet(enet_broadcast,    /* ethernet dest */
+                                   libnet_get_hwaddr(context), /* ethernet source */
+                                   ETHERTYPE_IP,       /* protocol type */
+                                   NULL,       /* payload */
+                                   0,  /* payload size */
+                                   context,    /* libnet handle */
+                                   ether_tag); /* pblock tag */
+  if (ether_tag == -1) {
+    OLSR_PRINTF(1, "libnet ethernet header: %s\n", libnet_geterror(context));
+    return (0);
+  }
 
-  libnet_destroy (context);
+  status = libnet_write(context);
+  if (status == -1) {
+    OLSR_PRINTF(1, "libnet packet write: %s\n", libnet_geterror(context));
+    return (0);
+  }
+
+  libnet_destroy(context);
 
   return (len);
 
 #else
-  return sendto(s, buf, len, flags, to, tolen);
+  return sendto(s, (caddr_t) buf, (int)len, flags, (struct sockaddr *)to,
+               tolen);
 #endif
 }
 
@@ -709,23 +701,22 @@ olsr_sendto(int s,
  * Wrapper for recvfrom(2)
  */
 
-ssize_t  
-olsr_recvfrom(int  s, 
-             void *buf, 
-             size_t len, 
-             int flags __attribute__((unused)), 
-             struct sockaddr *from,
-             socklen_t *fromlen)
+ssize_t
+olsr_recvfrom(int s,
+             void *buf,
+             size_t len,
+             int flags __attribute__ ((unused)),
+             struct sockaddr *from, socklen_t * fromlen)
 {
   struct msghdr mhdr;
   struct iovec iov;
   union {
-       struct cmsghdr cmsg;
-       unsigned char chdr[4096];
+    struct cmsghdr cmsg;
+    unsigned char chdr[4096];
   } cmu;
   struct cmsghdr *cm;
   struct sockaddr_dl *sdl;
-  struct sockaddr_in *sin = (struct sockaddr_in *) from; //XXX
+  struct sockaddr_in *sin = (struct sockaddr_in *)from;
   struct sockaddr_in6 *sin6;
   struct in6_addr *iaddr6;
   struct in6_pktinfo *pkti;
@@ -741,55 +732,49 @@ olsr_recvfrom(int  s,
   mhdr.msg_namelen = *fromlen;
   mhdr.msg_iov = &iov;
   mhdr.msg_iovlen = 1;
-  mhdr.msg_control = (caddr_t) &cmu;
-  mhdr.msg_controllen = sizeof (cmu);
+  mhdr.msg_control = (caddr_t) & cmu;
+  mhdr.msg_controllen = sizeof(cmu);
 
   iov.iov_len = len;
   iov.iov_base = buf;
 
-  count = recvmsg (s, &mhdr, MSG_DONTWAIT);
-  if (count <= 0)
-    {
-      return (count);
-    }
+  count = recvmsg(s, &mhdr, MSG_DONTWAIT);
+  if (count <= 0) {
+    return (count);
+  }
 
   /* this needs to get communicated back to caller */
   *fromlen = mhdr.msg_namelen;
-  if (olsr_cnf->ip_version == AF_INET6)
-    {
-      for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&mhdr); cm;
-          cm = (struct cmsghdr *)CMSG_NXTHDR(&mhdr, cm))
-       {
-         if (cm->cmsg_level == IPPROTO_IPV6 && cm->cmsg_type == IPV6_PKTINFO)
-           {
-             pkti = (struct in6_pktinfo *) CMSG_DATA(cm);
-             iaddr6 = &pkti->ipi6_addr;
-             if_indextoname(pkti->ipi6_ifindex, iname);
-           }
-       }
-    }
-  else
-    {
-      cm = &cmu.cmsg;
-      sdl = (struct sockaddr_dl *) CMSG_DATA (cm);
-      memset (iname, 0, sizeof (iname));
-      memcpy (iname, sdl->sdl_data, sdl->sdl_nlen);
+  if (olsr_cnf->ip_version == AF_INET6) {
+    for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&mhdr); cm;
+        cm = (struct cmsghdr *)CMSG_NXTHDR(&mhdr, cm)) {
+      if (cm->cmsg_level == IPPROTO_IPV6 && cm->cmsg_type == IPV6_PKTINFO) {
+       pkti = (struct in6_pktinfo *)CMSG_DATA(cm);
+       iaddr6 = &pkti->ipi6_addr;
+       if_indextoname(pkti->ipi6_ifindex, iname);
+      }
     }
+  } else {
+    cm = &cmu.cmsg;
+    sdl = (struct sockaddr_dl *)CMSG_DATA(cm);
+    memset(iname, 0, sizeof(iname));
+    memcpy(iname, sdl->sdl_data, sdl->sdl_nlen);
+  }
 
-  ifc = if_ifwithsock (s);
+  ifc = if_ifwithsock(s);
 
   sin6 = (struct sockaddr_in6 *)from;
-  OLSR_PRINTF (4, "%d bytes from %s, socket associated %s really received on %s\n",
-              count,          
-               inet_ntop(olsr_cnf->ip_version, olsr_cnf->ip_version == AF_INET6 ?
-                         (char *)&sin6->sin6_addr : (char *)&sin->sin_addr, addrstr, sizeof(addrstr)),
-              ifc->int_name,
-              iname);
-
-  if (strcmp (ifc->int_name, iname) != 0)
-    {
-      return (0);
-    }
+  OLSR_PRINTF(4,
+             "%d bytes from %s, socket associated %s really received on %s\n",
+             count, inet_ntop(olsr_cnf->ip_version,
+                              olsr_cnf->ip_version ==
+                              AF_INET6 ? (char *)&sin6->
+                              sin6_addr : (char *)&sin->sin_addr, addrstr,
+                              sizeof(addrstr)), ifc->int_name, iname);
+
+  if (strcmp(ifc->int_name, iname) != 0) {
+    return (0);
+  }
 
   return (count);
 }
@@ -800,23 +785,18 @@ olsr_recvfrom(int  s,
 
 int
 olsr_select(int nfds,
-           fd_set *readfds,
-           fd_set *writefds,
-           fd_set *exceptfds,
-           struct timeval *timeout)
+           fd_set * readfds,
+           fd_set * writefds, fd_set * exceptfds, struct timeval *timeout)
 {
-  return select(nfds,
-               readfds,
-               writefds,
-               exceptfds,
-               timeout);
+  return select(nfds, readfds, writefds, exceptfds, timeout);
 }
 
 
-int 
+int
 check_wireless_interface(char *ifname)
 {
 #if defined __FreeBSD__ &&  !defined FBSD_NO_80211
+
 /* From FreeBSD ifconfig/ifieee80211.c ieee80211_status() */
   struct ieee80211req ireq;
   u_int8_t data[32];
@@ -831,9 +811,9 @@ check_wireless_interface(char *ifname)
   struct ieee80211_nodereq nr;
   bzero(&nr, sizeof(nr));
   strlcpy(nr.nr_ifname, ifname, sizeof(nr.nr_ifname));
-  return (ioctl(olsr_cnf->ioctl_s, SIOCG80211FLAGS, &nr) >=0) ? 1: 0;
+  return (ioctl(olsr_cnf->ioctl_s, SIOCG80211FLAGS, &nr) >= 0) ? 1 : 0;
 #else
-  ifname = NULL; /* squelsh compiler warning */
+  ifname = NULL;               /* squelsh compiler warning */
   return 0;
 #endif
 }
@@ -843,29 +823,25 @@ check_wireless_interface(char *ifname)
 int
 calculate_if_metric(char *ifname)
 {
-  if(check_wireless_interface(ifname))
-    {
-      /* Wireless */
-      return 1;
-    }
-  else
-    {
-      /* Ethernet */
+  if (check_wireless_interface(ifname)) {
+    /* Wireless */
+    return 1;
+  } else {
+    /* Ethernet */
 #if 0
-      /* Andreas: Perhaps SIOCGIFMEDIA is the way to do this? */
-      struct ifmediareq ifm;
+    /* Andreas: Perhaps SIOCGIFMEDIA is the way to do this? */
+    struct ifmediareq ifm;
 
-      memset(&ifm, 0, sizeof(ifm));
-      strlcpy(ifm.ifm_name, ifname, sizeof(ifm.ifm_name));
-
-      if(ioctl(olsr_cnf->ioctl_s, SIOCGIFMEDIA, &ifm) < 0)
-       {
-         OLSR_PRINTF(1, "Error SIOCGIFMEDIA(%s)\n", ifm.ifm_name);
-         return WEIGHT_ETHERNET_DEFAULT;
-       }
+    memset(&ifm, 0, sizeof(ifm));
+    strlcpy(ifm.ifm_name, ifname, sizeof(ifm.ifm_name));
 
-      OLSR_PRINTF(1, "%s: STATUS 0x%08x\n", ifm.ifm_name, ifm.ifm_status);
-#endif
+    if (ioctl(olsr_cnf->ioctl_s, SIOCGIFMEDIA, &ifm) < 0) {
+      OLSR_PRINTF(1, "Error SIOCGIFMEDIA(%s)\n", ifm.ifm_name);
       return WEIGHT_ETHERNET_DEFAULT;
     }
+
+    OLSR_PRINTF(1, "%s: STATUS 0x%08x\n", ifm.ifm_name, ifm.ifm_status);
+#endif
+    return WEIGHT_ETHERNET_DEFAULT;
+  }
 }
index a592fe0..9c0e22e 100644 (file)
@@ -182,8 +182,8 @@ olsrd_write_cnf(struct olsrd_config *cnf, const char *fname)
   fprintf(fd, "# Fish Eye algorithm\n# 0 = do not use fish eye\n# 1 = use fish eye\n\n");
   fprintf(fd, "LinkQualityFishEye\t%d\n\n", cnf->lq_fish);
 
-  fprintf(fd, "# Link quality window size\n\n");
-  fprintf(fd, "LinkQualityWinSize\t%d\n\n", cnf->lq_wsize);
+  fprintf(fd, "# Link quality aging factor\n\n");
+  fprintf(fd, "LinkQualityAging\t%f\n\n", cnf->lq_aging);
 
   fprintf(fd, "# NAT threshold\n\n");
   fprintf(fd, "NatThreshold\t%f\n\n", cnf->lq_nat_thresh);
@@ -466,8 +466,8 @@ olsrd_write_cnf_buf(struct olsrd_config *cnf, char *buf, olsr_u32_t bufsize)
   WRITE_TO_BUF("# Link quality level\n# 0 = do not use link quality\n# 1 = use link quality for MPR selection\n# 2 = use link quality for MPR selection and routing\n\n");
   WRITE_TO_BUF("LinkQualityLevel\t%d\n\n", cnf->lq_level);
 
-  WRITE_TO_BUF("# Link quality window size\n\n");
-  WRITE_TO_BUF("LinkQualityWinSize\t%d\n\n", cnf->lq_wsize);
+  WRITE_TO_BUF("# Link quality aging factor\n\n");
+  WRITE_TO_BUF("LinkQualityAging\t%f\n\n", cnf->lq_aging);
 
   WRITE_TO_BUF("# NAT threshold\n\n");
   WRITE_TO_BUF("NatThreshold\t%f\n\n", cnf->lq_nat_thresh);
index 7ee2454..293d3d0 100644 (file)
@@ -291,9 +291,9 @@ olsrd_sanity_check_cnf(struct olsrd_config *cnf)
     }
 
   /* Link quality window size */
-  if(cnf->lq_level && (cnf->lq_wsize < MIN_LQ_WSIZE || cnf->lq_wsize > MAX_LQ_WSIZE))
+  if(cnf->lq_level && (cnf->lq_aging < MIN_LQ_AGING || cnf->lq_aging > MAX_LQ_AGING))
     {
-      fprintf(stderr, "LQ window size %d is not allowed\n", cnf->lq_wsize);
+      fprintf(stderr, "LQ aging factor %f is not allowed\n", cnf->lq_aging);
       return -1;
     }
 
@@ -335,7 +335,7 @@ olsrd_sanity_check_cnf(struct olsrd_config *cnf)
           io->hello_params.validity_time = NEIGHB_HOLD_TIME;
 
         else
-          io->hello_params.validity_time = cnf->lq_wsize * io->hello_params.emission_interval;
+          io->hello_params.validity_time = (int)(REFRESH_INTERVAL / cnf->lq_aging);
       }
 
       if(io->hello_params.emission_interval < cnf->pollrate ||
@@ -469,7 +469,8 @@ set_default_cnf(struct olsrd_config *cnf)
     cnf->lq_fish = DEF_LQ_FISH;
     cnf->lq_dlimit = DEF_LQ_DIJK_LIMIT;
     cnf->lq_dinter = DEF_LQ_DIJK_INTER;
-    cnf->lq_wsize = DEF_LQ_WSIZE;
+    cnf->lq_aging = DEF_LQ_AGING;
+    cnf->lq_algorithm = NULL;
     cnf->lq_nat_thresh = DEF_LQ_NAT_THRESH;
     cnf->clear_screen = DEF_CLEAR_SCREEN;
 
@@ -591,8 +592,10 @@ olsrd_print_cnf(struct olsrd_config *cnf)
 
   printf("LQ Dijkstra limit: %d, %0.2f\n", cnf->lq_dlimit, cnf->lq_dinter);
 
-  printf("LQ window size   : %d\n", cnf->lq_wsize);
+  printf("LQ aging factor  : %f\n", cnf->lq_aging);
 
+  printf("LQ algorithm name: %s\n", cnf->lq_algorithm ? cnf->lq_algorithm : "default");
+  
   printf("NAT threshold    : %f\n", cnf->lq_nat_thresh);
 
   printf("Clear screen     : %s\n", cnf->clear_screen ? "yes" : "no");
index a107e74..9f99078 100644 (file)
@@ -2,7 +2,7 @@
 
 /*
  * The olsr.org Optimized Link-State Routing daemon(olsrd)
- * Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
+ * Copyright (c) 2004, Andreas Tnnesen(andreto@olsr.org)
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without 
@@ -189,6 +189,8 @@ static int add_ipv6_addr(YYSTYPE ipaddr_arg, YYSTYPE prefixlen_arg)
 %token TOK_LQ_FISH
 %token TOK_LQ_DLIMIT
 %token TOK_LQ_WSIZE
+%token TOK_LQ_AGING
+%token TOK_LQ_PLUGIN
 %token TOK_LQ_NAT_THRESH
 %token TOK_LQ_MULT
 %token TOK_CLEAR_SCREEN
@@ -243,10 +245,12 @@ stmt:       idebug
           | atcredundancy
           | amprcoverage
           | alq_level
+          | alq_plugin
           | alq_fish
           | alq_dlimit
           | anat_thresh
           | alq_wsize
+          | alq_aging
           | bclear_screen
           | vcomment
 ;
@@ -984,8 +988,22 @@ alq_dlimit: TOK_LQ_DLIMIT TOK_INTEGER TOK_FLOAT
 
 alq_wsize: TOK_LQ_WSIZE TOK_INTEGER
 {
-  PARSER_DEBUG_PRINTF("Link quality window size %d\n", $2->integer);
-  olsr_cnf->lq_wsize = $2->integer;
+  free($2);
+}
+;
+
+alq_aging: TOK_LQ_AGING TOK_FLOAT
+{
+  PARSER_DEBUG_PRINTF("Link quality aging factor %f\n", $2->floating);
+  olsr_cnf->lq_aging = $2->floating;
+  free($2);
+}
+;
+
+alq_plugin: TOK_LQ_PLUGIN TOK_STRING
+{
+  olsr_cnf->lq_algorithm = $2->string;
+  PARSER_DEBUG_PRINTF("LQ Algorithm: %s\n", $2->string);
   free($2);
 }
 ;
index 7519098..acb3f91 100644 (file)
@@ -2,7 +2,7 @@
 
 /*
  * The olsr.org Optimized Link-State Routing daemon(olsrd)
- * Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
+ * Copyright (c) 2004, Andreas Tnnesen(andreto@olsr.org)
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without 
@@ -383,6 +383,16 @@ IPV6ADDR {IP6PAT1}|{IP6PAT2}|{IP6PAT3}|{IP6PAT4}|{IP6PAT5}|{IP6PAT6}|{IP6PAT7}|{
     return TOK_LQ_DLIMIT;
 }
 
+"LinkQualityAging" {
+    yylval = NULL;
+    return TOK_LQ_AGING;
+}
+
+"LinkQualityAlgorithm" {
+    yylval = NULL;
+    return TOK_LQ_PLUGIN;
+}
+
 "LinkQualityWinSize" {
     yylval = NULL;
     return TOK_LQ_WSIZE;
index 265d9e0..cce14c9 100644 (file)
@@ -82,7 +82,8 @@ avl_init(struct avl_tree *tree, avl_tree_comp comp)
   tree->first = NULL;
   tree->last = NULL;
   tree->count = 0;
-  tree->comp = comp;
+  
+  tree->comp = comp == avl_comp_ipv4 ? NULL : comp;
 }
 
 static struct avl_node *
index 9a4784a..7eb4964 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * The olsr.org Optimized Link-State Routing daemon(olsrd)
- * Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
+ * Copyright (c) 2004, Andreas Tnnesen(andreto@olsr.org)
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without 
index 1c00d54..d0cf130 100644 (file)
@@ -1,7 +1,11 @@
 /*
  * The olsr.org Optimized Link-State Routing daemon(olsrd)
+<<<<<<< /home/rogge/develop/olsrd/olsrd-linkset-refactoring/src/duplicate_set.c
+ * Copyright (c) 2008 Henning Rogge <rogge@fgan.de>
+=======
  * Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
  * Copyright (c) 2008 Henning Rogge <rogge@fgan.de>
+>>>>>>> /tmp/duplicate_set.c~other.bvK6d3
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without 
@@ -133,9 +137,3 @@ int olsr_shall_process_message(void *ip, olsr_u16_t seqnr) {
 void olsr_print_duplicate_table(void) {
   /* XXX FIXME */
 }
-
-/*
- * Local Variables:
- * c-basic-offset: 2
- * End:
- */
index e421345..f1745b7 100644 (file)
@@ -1,7 +1,11 @@
 /*
  * The olsr.org Optimized Link-State Routing daemon(olsrd)
+<<<<<<< /home/rogge/develop/olsrd/olsrd-linkset-refactoring/src/duplicate_set.h
+ * Copyright (c) 2008 Henning Rogge <rogge@fgan.de>
+=======
  * Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
  * Copyright (c) 2008 Henning Rogge <rogge@fgan.de>
+>>>>>>> /tmp/duplicate_set.h~other.fO3lgV
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without 
@@ -39,8 +43,8 @@
  *
  */
 
-#ifndef DUPLICATE_SET_H_
-#define DUPLICATE_SET_H_
+#ifndef DUPLICATE_SET_2_H_
+#define DUPLICATE_SET_2_H_
 
 #include "common/avl.h"
 #include "olsr.h"
@@ -58,7 +62,7 @@ struct duplicate_entry *olsr_create_duplicate_entry(void *ip, olsr_u16_t seqnr);
 int olsr_shall_process_message(void *ip, olsr_u16_t seqnr);
 void olsr_print_duplicate_table(void);
 
-#endif /*DUPLICATE_SET_H_*/
+#endif /*DUPLICATE_SET_2_H_*/
 
 /*
  * Local Variables:
index 72fb64a..252ee9b 100644 (file)
--- a/src/fpm.c
+++ b/src/fpm.c
@@ -43,6 +43,7 @@
 #include "fpm.h"
 
 #ifdef USE_FPM
+#undef NDEBUG
 
 #ifndef NDEBUG
 
index d04e20e..59b4fc5 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
  * The olsr.org Optimized Link-State Routing daemon(olsrd)
  * Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
 #include "hashing.h"
 #include "defs.h"
 
+/*
+ * Taken from lookup2.c by Bob Jenkins.  (http://burtleburtle.net/bob/c/lookup2.c).
+ * --------------------------------------------------------------------
+ * lookup2.c, by Bob Jenkins, December 1996, Public Domain.
+ * You can use this free for any purpose.  It has no warranty.
+ * --------------------------------------------------------------------
+ */
+
+#define __jhash_mix(a, b, c) \
+{ \
+  a -= b; a -= c; a ^= (c>>13); \
+  b -= c; b -= a; b ^= (a<<8); \
+  c -= a; c -= b; c ^= (b>>13); \
+  a -= b; a -= c; a ^= (c>>12);  \
+  b -= c; b -= a; b ^= (a<<16); \
+  c -= a; c -= b; c ^= (b>>5); \
+  a -= b; a -= c; a ^= (c>>3);  \
+  b -= c; b -= a; b ^= (a<<10); \
+  c -= a; c -= b; c ^= (b>>15); \
+}
+
+static inline olsr_u32_t
+jenkins_hash(const olsr_u8_t * k, olsr_u32_t length)
+{
+  /* k: the key
+   * length: length of the key
+   * initval: the previous hash, or an arbitrary value
+   */
+  olsr_u32_t a, b, c, len;
+
+  /* Set up the internal state */
+  len = length;
+  a = b = 0x9e3779b9;          /* the golden ratio; an arbitrary value */
+  c = 0;                       /* the previous hash value */
+
+  /* handle most of the key */
+  while (len >= 12) {
+    a += (k[0] + ((olsr_u32_t) k[1] << 8) + ((olsr_u32_t) k[2] << 16)
+         + ((olsr_u32_t) k[3] << 24));
+    b += (k[4] + ((olsr_u32_t) k[5] << 8) + ((olsr_u32_t) k[6] << 16)
+         + ((olsr_u32_t) k[7] << 24));
+    c += (k[8] + ((olsr_u32_t) k[9] << 8) + ((olsr_u32_t) k[10] << 16)
+         + ((olsr_u32_t) k[11] << 24));
+
+    __jhash_mix(a, b, c);
+
+    k += 12;
+    len -= 12;
+  }
+
+  c += length;
+  switch (len) {
+  case 11:
+    c += ((olsr_u32_t) k[10] << 24);
+  case 10:
+    c += ((olsr_u32_t) k[9] << 16);
+  case 9:
+    c += ((olsr_u32_t) k[8] << 8);
+    /* the first byte of c is reserved for the length */
+  case 8:
+    b += ((olsr_u32_t) k[7] << 24);
+  case 7:
+    b += ((olsr_u32_t) k[6] << 16);
+  case 6:
+    b += ((olsr_u32_t) k[5] << 8);
+  case 5:
+    b += k[4];
+  case 4:
+    a += ((olsr_u32_t) k[3] << 24);
+  case 3:
+    a += ((olsr_u32_t) k[2] << 16);
+  case 2:
+    a += ((olsr_u32_t) k[1] << 8);
+  case 1:
+    a += k[0];
+  }
+  __jhash_mix(a, b, c);
+
+  return c;
+}
+
+
 /**
- * Hashing function. Creates a key based on
- * an 32-bit address.
+ * Hashing function. Creates a key based on an IP address.
  * @param address the address to hash
  * @return the hash(a value in the (0 to HASHMASK-1) range)
  */
-olsr_u32_t olsr_ip_hashing(const union olsr_ip_addr * address)
+olsr_u32_t
+olsr_ip_hashing(const union olsr_ip_addr *address)
 {
   olsr_u32_t hash;
-  if(olsr_cnf->ip_version == AF_INET) {
-    /* IPv4 */  
-    const olsr_u8_t * const v4x = (const olsr_u8_t *)&address->v4;
-    hash = v4x[0] ^ v4x[1] ^ v4x[2] ^ v4x[3];
-  } else {
-    /* IPv6 */
-    const char * const tmp = (const char *)&address->v6;
-    hash = ntohl(*tmp);
+
+  switch (olsr_cnf->ip_version) {
+  case AF_INET:
+    hash = jenkins_hash((const olsr_u8_t *)&address->v4,
+                        sizeof(olsr_u32_t));
+    break;
+  case AF_INET6:
+    hash = jenkins_hash((const olsr_u8_t *)&address->v6,
+                       sizeof(struct in6_addr));
+    break;
+  default:
+    hash = 0;
+    break;
+
   }
   return hash & HASHMASK;
 }
index 3a8f58f..86ba3a1 100644 (file)
@@ -233,11 +233,6 @@ olsr_expire_hna_net_entry(void *context)
     DEQUEUE_ELEM(hna_gw);
     free(hna_gw);
   }
-
-  DEQUEUE_ELEM(net_to_delete);
-  free(net_to_delete);
-
-  changes_hna = OLSR_TRUE;
 }
 
 /**
index 1d268f7..450298d 100644 (file)
@@ -99,9 +99,6 @@ olsr_add_hna_net(struct hna_entry *, const union olsr_ip_addr *, olsr_u8_t);
 void
 olsr_update_hna_entry(const union olsr_ip_addr *, const union olsr_ip_addr *, olsr_u8_t, const float);
 
-void
-olsr_time_out_hna_set(void *);
-
 void
 olsr_print_hna_set(void);
 
index 606980d..48a7df8 100644 (file)
@@ -335,7 +335,6 @@ del_ifchgf(int (*f)(struct interface *, int))
 
   return 0;
 }
-
 /*
  * Local Variables:
  * c-basic-offset: 2
index 8ed76f1..6f1419a 100644 (file)
@@ -118,7 +118,6 @@ struct olsr_netbuf
   int reserved;   /* Plugins can reserve space in buffers */
 };
 
-
 /**
  *A struct containing all necessary information about each
  *interface participating in the OLSRD routing
@@ -135,14 +134,16 @@ struct interface
   /* IP independent */
   union         olsr_ip_addr ip_addr;
   int           is_hcif;                        /* Is this a emulated host-client if? */
-  int           olsr_socket;                    /* The broadcast socket for this interface */
-  int          int_metric;                     /* metric of interface */
-  int           int_mtu;                        /* MTU of interface */
-  int          int_flags;                      /* see below */
-  int           if_index;                       /* Kernels index of this interface */
-  int           is_wireless;                    /* wireless interface or not*/
+  
+  int           olsr_socket;        /* The broadcast socket for this interface */
+  
+  int            int_metric;                   /* metric of interface */
+  int           int_mtu;        /* MTU of interface */
+  int            int_flags;                    /* see below */
+  int           if_index;       /* Kernels index of this interface */
+  int           is_wireless;    /* wireless interface or not*/
   char         *int_name;                      /* from kernel if structure */
-  olsr_u16_t    olsr_seqnum;                    /* Olsr message seqno */
+  olsr_u16_t    olsr_seqnum;    /* Olsr message seqno */
 
   /* Periodic message generation timers */
   struct timer_entry *hello_gen_timer;
index 5854b51..9cf614c 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
  * The olsr.org Optimized Link-State Routing daemon(olsrd)
  * Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
@@ -38,7 +39,6 @@
  *
  */
 
-
 /*
  * Link sensing database for the OLSR routing daemon
  */
@@ -51,7 +51,7 @@
 #include "neighbor_table.h"
 #include "olsr.h"
 #include "scheduler.h"
-#include "lq_route.h"
+#include "olsr_spf.h"
 #include "net_olsr.h"
 #include "ipcalc.h"
 #include "lq_plugin.h"
 /* head node for all link sets */
 struct list_node link_entry_head;
 
-olsr_bool link_changes; /* is set if changes occur in MPRS set */ 
+olsr_bool link_changes;                       /* is set if changes occur in MPRS set */
 
 void
-signal_link_changes(olsr_bool val) /* XXX ugly */
-{
+signal_link_changes(olsr_bool val)
+{                              /* XXX ugly */
   link_changes = val;
 }
 
-static int
-check_link_status(const struct hello_message *message, const struct interface *in_if);
-
-static struct link_entry *
-add_link_entry(const union olsr_ip_addr *, const union olsr_ip_addr *, const union olsr_ip_addr *, double, double, const struct interface *);
-
-static int
-get_neighbor_status(const union olsr_ip_addr *);
+/* Prototypes. */
+static int check_link_status(const struct hello_message *message,
+                             const struct interface *in_if);
+static struct link_entry *add_link_entry(const union olsr_ip_addr *,
+                                        const union olsr_ip_addr *,
+                                        const union olsr_ip_addr *, double,
+                                        double, const struct interface *);
+static int get_neighbor_status(const union olsr_ip_addr *);
 
 void
 olsr_init_link_set(void)
@@ -89,226 +89,208 @@ olsr_init_link_set(void)
  * Get the status of a link. The status is based upon different
  * timeouts in the link entry.
  *
- *@param remote address of the remote interface
- *
- *@return the link status of the link
+ * @param remote address of the remote interface
+ * @return the link status of the link
  */
 int
 lookup_link_status(const struct link_entry *entry)
 {
 
-  if(entry == NULL || list_is_empty(&link_entry_head)) {
+  if (entry == NULL || list_is_empty(&link_entry_head)) {
     return UNSPEC_LINK;
   }
 
   /*
    * Hysteresis
    */
-  if(olsr_cnf->use_hysteresis)
-    {
-      /*
-       if L_LOST_LINK_time is not expired, the link is advertised
-       with a link type of LOST_LINK.
-      */
+  if (olsr_cnf->use_hysteresis) {
 
-      if(!TIMED_OUT(entry->L_LOST_LINK_time))
-       return LOST_LINK;
-      /*
-       otherwise, if L_LOST_LINK_time is expired and L_link_pending
-       is set to "true", the link SHOULD NOT be advertised at all;
-      */
-      if(entry->L_link_pending == 1)
-       {
+    /*
+     * if L_LOST_LINK_time is not expired, the link is advertised
+     * with a link type of LOST_LINK.
+     */
+
+    if (!TIMED_OUT(entry->L_LOST_LINK_time)) {
+      return LOST_LINK;
+    }
+
+    /*
+     * otherwise, if L_LOST_LINK_time is expired and L_link_pending
+     * is set to "true", the link SHOULD NOT be advertised at all;
+     */
+    if (entry->L_link_pending == 1) {
 #ifndef NODEBUG
-          struct ipaddr_str buf;
-         OLSR_PRINTF(3, "HYST[%s]: Setting to HIDE\n", olsr_ip_to_string(&buf, &entry->neighbor_iface_addr));
+      struct ipaddr_str buf;
+      OLSR_PRINTF(3, "HYST[%s]: Setting to HIDE\n",
+                 olsr_ip_to_string(&buf, &entry->neighbor_iface_addr));
 #endif
-         return HIDE_LINK;
-       }
-      /*
-       otherwise, if L_LOST_LINK_time is expired and L_link_pending
-       is set to "false", the link is advertised as described
-       previously in section 6.
-      */
+      return HIDE_LINK;
     }
 
+    /*
+     * otherwise, if L_LOST_LINK_time is expired and L_link_pending
+     * is set to "false", the link is advertised as described
+     * previously in section 6.
+     */
+  }
+
   if (entry->link_sym_timer) {
     return SYM_LINK;
   }
 
-  if(!TIMED_OUT(entry->ASYM_time))
+  if (!TIMED_OUT(entry->ASYM_time)) {
     return ASYM_LINK;
+  }
 
   return LOST_LINK;
-
-
 }
 
 
 /**
- *Find the "best" link status to a
- *neighbor
- *
- *@param address the address to check for
+ * Find the "best" link status to a neighbor
  *
- *@return SYM_LINK if a symmetric link exists 0 if not
+ * @param address the address to check for
+ * @return SYM_LINK if a symmetric link exists 0 if not
  */
 static int
 get_neighbor_status(const union olsr_ip_addr *address)
 {
   const union olsr_ip_addr *main_addr;
-  struct interface   *ifs;
-
-  //printf("GET_NEIGHBOR_STATUS\n");
+  struct interface *ifs;
 
   /* Find main address */
-  if(!(main_addr = mid_lookup_main_addr(address)))
+  if (!(main_addr = mid_lookup_main_addr(address)))
     main_addr = address;
 
-  //printf("\tmain: %s\n", olsr_ip_to_string(main_addr));
-
   /* Loop trough local interfaces to check all possebilities */
-  for(ifs = ifnet; ifs != NULL; ifs = ifs->int_next)
-    {
-      struct mid_address   *aliases;
-      struct link_entry  *lnk = lookup_link_entry(main_addr, NULL, ifs);
-
-      //printf("\tChecking %s->", olsr_ip_to_string(&ifs->ip_addr));
-      //printf("%s : ", olsr_ip_to_string(main_addr)); 
-      if(lnk != NULL)
-       {
-         //printf("%d\n", lookup_link_status(link));
-         if(lookup_link_status(lnk) == SYM_LINK)
-           return SYM_LINK;
-       }
-      /* Get aliases */
-      for(aliases = mid_lookup_aliases(main_addr);
-         aliases != NULL;
-         aliases = aliases->next_alias)
-       {
-         //printf("\tChecking %s->", olsr_ip_to_string(&ifs->ip_addr));
-         //printf("%s : ", olsr_ip_to_string(&aliases->address)); 
-            lnk = lookup_link_entry(&aliases->alias, NULL, ifs);
-            if(lnk != NULL)
-           {
-             //printf("%d\n", lookup_link_status(link));
-
-             if(lookup_link_status(lnk) == SYM_LINK)
-               return SYM_LINK;
-           }
-       }
+  for (ifs = ifnet; ifs != NULL; ifs = ifs->int_next) {
+    struct mid_address *aliases;
+    struct link_entry *lnk = lookup_link_entry(main_addr, NULL, ifs);
+
+    if (lnk != NULL) {
+      if (lookup_link_status(lnk) == SYM_LINK)
+       return SYM_LINK;
+    }
+
+    /* Get aliases */
+    for (aliases = mid_lookup_aliases(main_addr);
+        aliases != NULL; aliases = aliases->next_alias) {
+
+      lnk = lookup_link_entry(&aliases->alias, NULL, ifs);
+      if (lnk && (lookup_link_status(lnk) == SYM_LINK)) {
+         return SYM_LINK;
+      }
     }
-  
+  }
+
   return 0;
 }
 
 /**
  * Find best link to a neighbor
  */
-
 struct link_entry *
 get_best_link_to_neighbor(const union olsr_ip_addr *remote)
 {
   const union olsr_ip_addr *main_addr;
   struct link_entry *walker, *good_link, *backup_link;
+  struct interface *tmp_if;
   int curr_metric = MAX_IF_METRIC;
   olsr_linkcost curr_lcost = LINK_COST_BROKEN;
-  
-  // main address lookup
+  olsr_linkcost tmp_lc;
 
+  /* main address lookup */
   main_addr = mid_lookup_main_addr(remote);
 
-  // "remote" *already is* the main address
-
-  if (main_addr == NULL)
+  /* "remote" *already is* the main address */
+  if (!main_addr) {
     main_addr = remote;
+  }
 
-  // we haven't selected any links, yet
-
+  /* we haven't selected any links, yet */
   good_link = NULL;
   backup_link = NULL;
 
-  // loop through all links that we have
-
+  /* loop through all links that we have */
   OLSR_FOR_ALL_LINK_ENTRIES(walker) {
 
     /* if this is not a link to the neighour in question, skip */
     if (!ipequal(&walker->neighbor->neighbor_main_addr, main_addr))
       continue;
 
-    // handle the non-LQ, RFC-compliant case
+    if (olsr_cnf->lq_level == 0) {
 
-    if (olsr_cnf->lq_level == 0)
-    {
-      struct interface *tmp_if;
+      /*
+       * handle the non-LQ, RFC-compliant case
+       */
 
-      // find the interface for the link - we select the link with the
-      // best local interface metric
+      /*
+       * find the interface for the link.
+       * we select the link with the best local interface metric.
+       */
       tmp_if = walker->if_name ? if_ifwithname(walker->if_name) :
-              if_ifwithaddr(&walker->local_iface_addr);
+       if_ifwithaddr(&walker->local_iface_addr);
 
-      if(!tmp_if)
+      if (!tmp_if) {
        continue;
+      }
 
-      // is this interface better than anything we had before?
-
+      /*
+       * is this interface better than anything we had before ?
+       * use the requested remote interface address as a tie-breaker
+       */
       if ((tmp_if->int_metric < curr_metric) ||
-          // use the requested remote interface address as a tie-breaker
-          ((tmp_if->int_metric == curr_metric) && 
-           ipequal(&walker->local_iface_addr, remote)))
-      {
-        // memorize the interface's metric
-
-        curr_metric = tmp_if->int_metric;
-
-        // prefer symmetric links over asymmetric links
-
-        if (lookup_link_status(walker) == SYM_LINK)
-          good_link = walker;
-
-        else
-          backup_link = walker;
+         ((tmp_if->int_metric == curr_metric) &&
+          ipequal(&walker->local_iface_addr, remote))) {
+
+       /* memorize the interface's metric */
+       curr_metric = tmp_if->int_metric;
+
+       /* prefer symmetric links over asymmetric links */
+       if (lookup_link_status(walker) == SYM_LINK) {
+         good_link = walker;
+        } else {
+         backup_link = walker;
+        }
       }
-    }
-
-    // handle the LQ, non-RFC compliant case
-
-    else
-    {
-      olsr_linkcost tmp_lc;
-
-      // get the link cost
+    } else {
 
-      tmp_lc = walker->linkcost; 
-
-      // is this link better than anything we had before?
-             
-      if((tmp_lc < curr_lcost) ||
-         // use the requested remote interface address as a tie-breaker
-         ((tmp_lc == curr_lcost) && ipequal(&walker->local_iface_addr, remote)))
-      {
-        // memorize the link quality
-
-        curr_lcost = tmp_lc;
-
-        // prefer symmetric links over asymmetric links
+      /*
+       * handle the LQ, non-RFC compliant case.
+       */
 
-        if(lookup_link_status(walker) == SYM_LINK)
-          good_link = walker;
+      /* get the link cost */
+      tmp_lc = walker->linkcost;
 
-        else
-          backup_link = walker;
+      /*
+       * is this link better than anything we had before ?
+       * use the requested remote interface address as a tie-breaker.
+       */
+      if ((tmp_lc < curr_lcost) ||
+          ((tmp_lc == curr_lcost) &&
+           ipequal(&walker->local_iface_addr, remote))) {
+
+       /* memorize the link quality */
+       curr_lcost = tmp_lc;
+
+       /* prefer symmetric links over asymmetric links */
+       if (lookup_link_status(walker) == SYM_LINK) {
+         good_link = walker;
+        } else {
+         backup_link = walker;
+        }
       }
     }
   } OLSR_FOR_ALL_LINK_ENTRIES_END(walker);
 
-  // if we haven't found any symmetric links, try to return an
-  // asymmetric link
-
+  /*
+   * if we haven't found any symmetric links, try to return an asymmetric link.
+   */
   return good_link ? good_link : backup_link;
 }
 
-static void set_loss_link_multiplier(struct link_entry *entry)
+static void
+set_loss_link_multiplier(struct link_entry *entry)
 {
   struct interface *inter;
   struct olsr_if *cfg_inter;
@@ -316,41 +298,40 @@ static void set_loss_link_multiplier(struct link_entry *entry)
   float val = -1.0;
   union olsr_ip_addr null_addr;
 
-  // find the interface for the link
-
+  /* find the interface for the link */
   inter = if_ifwithaddr(&entry->local_iface_addr);
 
-  // find the interface configuration for the interface
-
-  for (cfg_inter = olsr_cnf->interfaces; cfg_inter != NULL;
-       cfg_inter = cfg_inter->next)
-    if (cfg_inter->interf == inter)
+  /* find the interface configuration for the interface */
+  for (cfg_inter = olsr_cnf->interfaces; cfg_inter;
+       cfg_inter = cfg_inter->next) {
+    if (cfg_inter->interf == inter) {
       break;
+    }
+  }
 
-  // create a null address for comparison
-
-  memset(&null_addr, 0, sizeof (union olsr_ip_addr));
-
-  // loop through the multiplier entries
+  /* create a null address for comparison */
+  memset(&null_addr, 0, sizeof(union olsr_ip_addr));
 
-  for (mult = cfg_inter->cnf->lq_mult; mult != NULL; mult = mult->next)
-  {
-    // use the default multiplier only if there isn't any entry that
-    // has a matching IP address
+  /* loop through the multiplier entries */
+  for (mult = cfg_inter->cnf->lq_mult; mult != NULL; mult = mult->next) {
 
+    /*
+     * use the default multiplier only if there isn't any entry that
+     * has a matching IP address.
+     */
     if ((ipequal(&mult->addr, &null_addr) && val < 0.0) ||
-        ipequal(&mult->addr, &entry->neighbor_iface_addr))
+       ipequal(&mult->addr, &entry->neighbor_iface_addr)) {
       val = mult->val;
+    }
   }
 
-  // if we have not found an entry, then use the default multiplier
-
-  if (val < 0)
+  /* if we have not found an entry, then use the default multiplier */
+  if (val < 0) {
     val = 1.0;
+  }
 
-  // store the multiplier
-
-  entry->loss_link_multiplier = val;
+  /* store the multiplier */
+  entry->loss_link_multiplier = (olsr_u32_t) (val * 65536);
 }
 
 /*
@@ -397,6 +378,7 @@ olsr_delete_link_entry_by_ip(const union olsr_ip_addr *int_addr)
   OLSR_FOR_ALL_LINK_ENTRIES(link) {
     if (ipequal(int_addr, &link->local_iface_addr)) {
       olsr_delete_link_entry(link);
+      break;
     }
   } OLSR_FOR_ALL_LINK_ENTRIES_END(link);
 }
@@ -408,7 +390,7 @@ static void
 olsr_expire_link_loss_timer(void *context)
 {
   struct link_entry *link;
-  
+
   link = (struct link_entry *)context;
 
   /* count the lost packet */
@@ -416,7 +398,7 @@ olsr_expire_link_loss_timer(void *context)
 
   /* next timeout in 1.0 x htime */
   olsr_change_timer(link->link_loss_timer, link->loss_hello_int * MSEC_PER_SEC,
-                    OLSR_LINK_LOSS_JITTER, OLSR_TIMER_PERIODIC);
+                   OLSR_LINK_LOSS_JITTER, OLSR_TIMER_PERIODIC);
 }
 
 /**
@@ -428,15 +410,15 @@ olsr_expire_link_sym_timer(void *context)
   struct link_entry *link;
 
   link = (struct link_entry *)context;
-  link->link_sym_timer = NULL; /* be pedandic */
+  link->link_sym_timer = NULL; /* be pedandic */
 
   if (link->prev_status != SYM_LINK) {
     return;
-  } 
+  }
 
   link->prev_status = lookup_link_status(link);
   update_neighbor_status(link->neighbor,
-                         get_neighbor_status(&link->neighbor_iface_addr));
+                        get_neighbor_status(&link->neighbor_iface_addr));
   changes_neighborhood = OLSR_TRUE;
 }
 
@@ -456,19 +438,19 @@ olsr_expire_link_hello_timer(void *context)
   link->L_link_quality = olsr_hyst_calc_instability(link->L_link_quality);
 
   OLSR_PRINTF(1, "HYST[%s] HELLO timeout %f\n",
-              olsr_ip_to_string(&buf, &link->neighbor_iface_addr),
-              link->L_link_quality);
+             olsr_ip_to_string(&buf, &link->neighbor_iface_addr),
+             link->L_link_quality);
 
   /* Update hello_timeout - NO SLACK THIS TIME */
   olsr_change_timer(link->link_hello_timer, link->last_htime * MSEC_PER_SEC,
-                    OLSR_LINK_JITTER, OLSR_TIMER_PERIODIC);
+                   OLSR_LINK_JITTER, OLSR_TIMER_PERIODIC);
 
   /* Update hysteresis values */
   olsr_process_hysteresis(link);
-         
+
   /* update neighbor status */
   update_neighbor_status(link->neighbor,
-                         get_neighbor_status(&link->neighbor_iface_addr));
+                        get_neighbor_status(&link->neighbor_iface_addr));
 
   /* Update seqno - not mentioned in the RFC... kind of a hack.. */
   link->olsr_seqno++;
@@ -483,7 +465,7 @@ olsr_expire_link_entry(void *context)
   struct link_entry *link;
 
   link = (struct link_entry *)context;
-  link->link_timer = NULL; /* be pedandic */
+  link->link_timer = NULL;     /* be pedandic */
 
   olsr_delete_link_entry(link);
 }
@@ -495,32 +477,32 @@ void
 olsr_set_link_timer(struct link_entry *link, unsigned int rel_timer)
 {
   olsr_set_timer(&link->link_timer, rel_timer, OLSR_LINK_JITTER,
-                 OLSR_TIMER_ONESHOT, &olsr_expire_link_entry, link, 0);
+                OLSR_TIMER_ONESHOT, &olsr_expire_link_entry, link, 0);
 }
 
 /**
- *Nothing mysterious here.
- *Adding a new link entry to the link set.
+ * Nothing mysterious here.
+ * Adding a new link entry to the link set.
  *
- *@param local the local IP address
- *@param remote the remote IP address
- *@param remote_main the remote nodes main address
- *@param vtime the validity time of the entry
- *@param htime the HELLO interval of the remote node
- *@param local_if the local interface
+ * @param local the local IP address
+ * @param remote the remote IP address
+ * @param remote_main the remote nodes main address
+ * @param vtime the validity time of the entry
+ * @param htime the HELLO interval of the remote node
+ * @param local_if the local interface
+ * @return the new link_entry
  */
-
 static struct link_entry *
 add_link_entry(const union olsr_ip_addr *local,
-               const union olsr_ip_addr *remote,
-               const union olsr_ip_addr *remote_main,
-               double vtime,
-               double htime,
-               const struct interface *local_if)
+              const union olsr_ip_addr *remote,
+              const union olsr_ip_addr *remote_main,
+              double vtime, double htime, const struct interface *local_if)
 {
   struct link_entry *new_link;
   struct neighbor_entry *neighbor;
-  struct link_entry *tmp_link_set = lookup_link_entry(remote, remote_main, local_if);
+  struct link_entry *tmp_link_set;
+
+  tmp_link_set = lookup_link_entry(remote, remote_main, local_if);
   if (tmp_link_set) {
     return tmp_link_set;
   }
@@ -535,21 +517,23 @@ add_link_entry(const union olsr_ip_addr *local,
 #ifndef NODEBUG
     struct ipaddr_str localbuf, rembuf;
 #endif
-    OLSR_PRINTF(1, "Adding %s=>%s to link set\n", olsr_ip_to_string(&localbuf, local), olsr_ip_to_string(&rembuf, remote));
+    OLSR_PRINTF(1, "Adding %s=>%s to link set\n",
+               olsr_ip_to_string(&localbuf, local), olsr_ip_to_string(&rembuf,
+                                                                      remote));
   }
 #endif
 
   /* a new tuple is created with... */
-
   new_link = olsr_malloc_link_entry("new link entry");
-  
+
   /* copy if_name, if it is defined */
-  if (local_if->int_name)
-    {
-      new_link->if_name = olsr_malloc(strlen(local_if->int_name)+1, "target of if_name in new link entry");
-      strcpy(new_link->if_name, local_if->int_name);
-    } else 
-      new_link->if_name = NULL;
+  if (local_if->int_name) {
+    new_link->if_name =
+      olsr_malloc(strlen(local_if->int_name) + 1,
+                 "target of if_name in new link entry");
+    strcpy(new_link->if_name, local_if->int_name);
+  } else
+    new_link->if_name = NULL;
 
   /* shortcut to interface. XXX refcount */
   new_link->inter = local_if;
@@ -558,8 +542,8 @@ add_link_entry(const union olsr_ip_addr *local,
    * L_local_iface_addr = Address of the interface
    * which received the HELLO message
    */
-  //printf("\tLocal IF: %s\n", olsr_ip_to_string(local));
   new_link->local_iface_addr = *local;
+
   /* L_neighbor_iface_addr = Source Address */
   new_link->neighbor_iface_addr = *remote;
 
@@ -569,28 +553,26 @@ add_link_entry(const union olsr_ip_addr *local,
   new_link->prev_status = ASYM_LINK;
 
   /* HYSTERESIS */
-  if(olsr_cnf->use_hysteresis)
-    {
-      new_link->L_link_pending = 1;
-      new_link->L_LOST_LINK_time = GET_TIMESTAMP(vtime*1000);
-      olsr_update_hysteresis_hello(new_link, htime);
-      new_link->last_htime = htime;
-      new_link->olsr_seqno = 0;
-      new_link->olsr_seqno_valid = OLSR_FALSE;
-    }
+  if (olsr_cnf->use_hysteresis) {
+    new_link->L_link_pending = 1;
+    new_link->L_LOST_LINK_time = GET_TIMESTAMP(vtime * 1000);
+    olsr_update_hysteresis_hello(new_link, htime);
+    new_link->last_htime = htime;
+    new_link->olsr_seqno = 0;
+    new_link->olsr_seqno_valid = OLSR_FALSE;
+  }
 
   new_link->L_link_quality = 0.0;
 
-  if (olsr_cnf->lq_level > 0)
-    {
-      new_link->loss_hello_int = htime;
+  if (olsr_cnf->lq_level > 0) {
+    new_link->loss_hello_int = htime;
 
-      olsr_set_timer(&new_link->link_loss_timer, htime * 1500,
-                     OLSR_LINK_LOSS_JITTER, OLSR_TIMER_PERIODIC,
-                     &olsr_expire_link_loss_timer, new_link, 0);
+    olsr_set_timer(&new_link->link_loss_timer, htime * 1500,
+                  OLSR_LINK_LOSS_JITTER, OLSR_TIMER_PERIODIC,
+                  &olsr_expire_link_loss_timer, new_link, 0);
 
-      set_loss_link_multiplier(new_link);
-    }
+    set_loss_link_multiplier(new_link);
+  }
 
   new_link->linkcost = LINK_COST_BROKEN;
 
@@ -603,16 +585,16 @@ add_link_entry(const union olsr_ip_addr *local,
 
   /* Neighbor MUST exist! */
   neighbor = olsr_lookup_neighbor_table(remote_main);
-  if(neighbor == NULL)
-    {
+  if (!neighbor) {
 #ifdef DEBUG
 #ifndef NODEBUG
-      struct ipaddr_str buf;
+    struct ipaddr_str buf;
 #endif
-      OLSR_PRINTF(3, "ADDING NEW NEIGHBOR ENTRY %s FROM LINK SET\n", olsr_ip_to_string(&buf, remote_main));
+    OLSR_PRINTF(3, "ADDING NEW NEIGHBOR ENTRY %s FROM LINK SET\n",
+               olsr_ip_to_string(&buf, remote_main));
 #endif
-      neighbor = olsr_insert_neighbor_table(remote_main);
-    }
+    neighbor = olsr_insert_neighbor_table(remote_main);
+  }
 
   neighbor->linkcount++;
   new_link->neighbor = neighbor;
@@ -633,37 +615,37 @@ check_neighbor_link(const union olsr_ip_addr *int_addr)
   struct link_entry *link;
 
   OLSR_FOR_ALL_LINK_ENTRIES(link) {
-    if (ipequal(int_addr, &link->neighbor_iface_addr))
+    if (ipequal(int_addr, &link->neighbor_iface_addr)) {
       return lookup_link_status(link);
+    }
   } OLSR_FOR_ALL_LINK_ENTRIES_END(link);
 
   return UNSPEC_LINK;
 }
 
-
 /**
- *Lookup a link entry
- *
- *@param remote the remote interface address
- *@param remote_main the remote nodes main address
- *@param local the local interface address
+ * Lookup a link entry
  *
- *@return the link entry if found, NULL if not
+ * @param remote the remote interface address
+ * @param remote_main the remote nodes main address
+ * @param local the local interface address
+ * @return the link entry if found, NULL if not
  */
 struct link_entry *
 lookup_link_entry(const union olsr_ip_addr *remote,
-                  const union olsr_ip_addr *remote_main,
-                  const struct interface *local)
+                 const union olsr_ip_addr *remote_main,
+                 const struct interface *local)
 {
   struct link_entry *link;
 
   OLSR_FOR_ALL_LINK_ENTRIES(link) {
-    if(ipequal(remote, &link->neighbor_iface_addr) &&
-       (link->if_name ? !strcmp(link->if_name, local->int_name)
-        : ipequal(&local->ip_addr, &link->local_iface_addr)) &&
+    if (ipequal(remote, &link->neighbor_iface_addr) &&
+       (link->if_name ? !strcmp(link->if_name, local->int_name)
+        : ipequal(&local->ip_addr, &link->local_iface_addr)) &&
 
-       /* check the remote-main address only if there is one given */
-       (!remote_main || ipequal(remote_main, &link->neighbor->neighbor_main_addr))) {
+       /* check the remote-main address only if there is one given */
+       (!remote_main
+        || ipequal(remote_main, &link->neighbor->neighbor_main_addr))) {
       return link;
     }
   } OLSR_FOR_ALL_LINK_ENTRIES_END(link);
@@ -671,99 +653,80 @@ lookup_link_entry(const union olsr_ip_addr *remote,
   return NULL;
 }
 
-
-
-
-
-
-
 /**
- *Update a link entry. This is the "main entrypoint" in
- *the link-sensing. This function is called from the HELLO
- *parser function.
- *It makes sure a entry is updated or created.
+ * Update a link entry. This is the "main entrypoint" in
+ * the link-sensing. This function is called from the HELLO
+ * parser function. It makes sure a entry is updated or created.
  *
- *@param local the local IP address
- *@param remote the remote IP address
- *@param message the HELLO message
- *@param in_if the interface on which this HELLO was received
- *
- *@return the link_entry struct describing this link entry
+ * @param local the local IP address
+ * @param remote the remote IP address
+ * @param message the HELLO message
+ * @param in_if the interface on which this HELLO was received
+ * @return the link_entry struct describing this link entry
  */
 struct link_entry *
-update_link_entry(const union olsr_ip_addr *local, 
-                 const union olsr_ip_addr *remote, 
-                 const struct hello_message *message, 
+update_link_entry(const union olsr_ip_addr *local,
+                 const union olsr_ip_addr *remote,
+                 const struct hello_message *message,
                  const struct interface *in_if)
 {
   struct link_entry *entry;
 
   /* Add if not registered */
-  entry = add_link_entry(local, remote, &message->source_addr, message->vtime, message->htime, in_if);
+  entry =
+    add_link_entry(local, remote, &message->source_addr, message->vtime,
+                  message->htime, in_if);
 
   /* Update ASYM_time */
-  //printf("Vtime is %f\n", message->vtime);
-  /* L_ASYM_time = current time + validity time */
   entry->vtime = message->vtime;
-  entry->ASYM_time = GET_TIMESTAMP(message->vtime*1000);
-  
+  entry->ASYM_time = GET_TIMESTAMP(message->vtime * 1000);
+
   entry->prev_status = check_link_status(message, in_if);
-  
-  //printf("Status %d\n", status);
-  
-  switch(entry->prev_status)
-    {
-    case(LOST_LINK):
-      olsr_stop_timer(entry->link_sym_timer);
-      entry->link_sym_timer = NULL;
-      break;
-    case(SYM_LINK):
-    case(ASYM_LINK):
-      /* L_SYM_time = current time + validity time */
-      olsr_set_timer(&entry->link_sym_timer, message->vtime * MSEC_PER_SEC,
-                     OLSR_LINK_SYM_JITTER, OLSR_TIMER_ONESHOT,
-                     &olsr_expire_link_sym_timer, entry, 0);
-
-      /* L_time = L_SYM_time + NEIGHB_HOLD_TIME */
-      olsr_set_link_timer(entry, (message->vtime + NEIGHB_HOLD_TIME) *
-                          MSEC_PER_SEC);
-      break;
-    default:;
-    }
+
+  switch (entry->prev_status) {
+  case (LOST_LINK):
+    olsr_stop_timer(entry->link_sym_timer);
+    entry->link_sym_timer = NULL;
+    break;
+  case (SYM_LINK):
+  case (ASYM_LINK):
+
+    /* L_SYM_time = current time + validity time */
+    olsr_set_timer(&entry->link_sym_timer, message->vtime * MSEC_PER_SEC,
+                  OLSR_LINK_SYM_JITTER, OLSR_TIMER_ONESHOT,
+                  &olsr_expire_link_sym_timer, entry, 0);
+
+    /* L_time = L_SYM_time + NEIGHB_HOLD_TIME */
+    olsr_set_link_timer(entry, (message->vtime + NEIGHB_HOLD_TIME) *
+                       MSEC_PER_SEC);
+    break;
+  default:;
+  }
 
   /* L_time = max(L_time, L_ASYM_time) */
-  if(entry->link_timer && (entry->link_timer->timer_clock < entry->ASYM_time)) {
+  if (entry->link_timer && (entry->link_timer->timer_clock < entry->ASYM_time)) {
     olsr_set_link_timer(entry, TIME_DUE(entry->ASYM_time));
   }
 
-
-  /*
-  printf("Updating link LOCAL: %s ", olsr_ip_to_string(local));
-  printf("REMOTE: %s\n", olsr_ip_to_string(remote));
-  printf("VTIME: %f ", message->vtime);
-  printf("STATUS: %d\n", status);
-  */
-
   /* Update hysteresis values */
-  if(olsr_cnf->use_hysteresis)
+  if (olsr_cnf->use_hysteresis)
     olsr_process_hysteresis(entry);
 
   /* Update neighbor */
   update_neighbor_status(entry->neighbor, get_neighbor_status(remote));
 
-  return entry;  
+  return entry;
 }
 
 
 /**
- * Fuction that updates all registered pointers to
+ * Function that updates all registered pointers to
  * one neighbor entry with another pointer
  * Used by MID updates.
  *
- *@old the pointer to replace
- *@new the pointer to use instead of "old"
- *
- *@return the number of entries updated
+ * @old the pointer to replace
+ * @new the pointer to use instead of "old"
+ * @return the number of entries updated
  */
 int
 replace_neighbor_link_set(const struct neighbor_entry *old,
@@ -775,7 +738,7 @@ replace_neighbor_link_set(const struct neighbor_entry *old,
   if (list_is_empty(&link_entry_head)) {
     return retval;
   }
-      
+
   OLSR_FOR_ALL_LINK_ENTRIES(link) {
 
     if (link->neighbor == old) {
@@ -797,76 +760,78 @@ replace_neighbor_link_set(const struct neighbor_entry *old,
  *@return the link status
  */
 static int
-check_link_status(const struct hello_message *message, const struct interface *in_if)
+check_link_status(const struct hello_message *message,
+                 const struct interface *in_if)
 {
   int ret = UNSPEC_LINK;
-  struct hello_neighbor  *neighbors;
+  struct hello_neighbor *neighbors;
 
   neighbors = message->neighbors;
-  
-  while(neighbors!=NULL)
-    {
-      /*
-       * Note: If a neigh has 2 cards we can reach, the neigh
-       * will send a Hello with the same IP mentined twice
-       */
-      if(ipequal(&neighbors->address, &in_if->ip_addr))
-        {
-         //printf("ok");
-         ret = neighbors->link;
-         if (SYM_LINK == ret) break;
-       }
-
-      neighbors = neighbors->next; 
+  while (neighbors) {
+
+    /*
+     * Note: If a neigh has 2 cards we can reach, the neigh
+     * will send a Hello with the same IP mentined twice
+     */
+    if (ipequal(&neighbors->address, &in_if->ip_addr)) {
+      ret = neighbors->link;
+      if (SYM_LINK == ret) {
+       break;
+      }
     }
-
+    neighbors = neighbors->next;
+  }
 
   return ret;
 }
 
-void olsr_print_link_set(void)
+void
+olsr_print_link_set(void)
 {
 #ifndef NODEBUG
   /* The whole function makes no sense without it. */
   struct link_entry *walker;
   const int addrsize = olsr_cnf->ip_version == AF_INET ? 15 : 39;
 
-  OLSR_PRINTF(0, "\n--- %s ---------------------------------------------------- LINKS\n\n",
-              olsr_wallclock_string());
-  OLSR_PRINTF(1, "%-*s  %-6s %-6s %-6s %-6s %-6s %s\n", addrsize,
-              "IP address", "hyst", "LQ", "lost", "total","NLQ", "ETX");
+  OLSR_PRINTF(0,
+             "\n--- %s ---------------------------------------------------- LINKS\n\n",
+             olsr_wallclock_string());
+  OLSR_PRINTF(1, "%-*s  %-6s %-14s %s\n", addrsize, "IP address", "hyst",
+             "      LQ      ", "ETX");
 
   OLSR_FOR_ALL_LINK_ENTRIES(walker) {
 
     struct ipaddr_str buf;
     struct lqtextbuffer lqbuffer1, lqbuffer2;
-    OLSR_PRINTF(1, "%-*s  %5.3f  %-13s %s\n",
-                addrsize, olsr_ip_to_string(&buf, &walker->neighbor_iface_addr),
-                walker->L_link_quality,
-                get_link_entry_text(walker, &lqbuffer1),
-                get_linkcost_text(walker->linkcost, OLSR_FALSE, &lqbuffer2));
+    OLSR_PRINTF(1, "%-*s  %5.3f  %-14s %s\n",
+               addrsize, olsr_ip_to_string(&buf, &walker->neighbor_iface_addr),
+               walker->L_link_quality,
+               get_link_entry_text(walker, &lqbuffer1),
+               get_linkcost_text(walker->linkcost, OLSR_FALSE, &lqbuffer2));
   } OLSR_FOR_ALL_LINK_ENTRIES_END(walker);
 #endif
 }
 
-void olsr_update_packet_loss_hello_int(struct link_entry *entry,
-                                       double loss_hello_int)
+/*
+ * called for every LQ HELLO message.
+ * update the timeout with the htime value from the message
+ */
+void
+olsr_update_packet_loss_hello_int(struct link_entry *entry,
+                                 double loss_hello_int)
 {
-  // called for every LQ HELLO message - update the timeout
-  // with the htime value from the message
-
   entry->loss_hello_int = loss_hello_int;
 }
 
-void olsr_update_packet_loss(struct link_entry *entry)
+void
+olsr_update_packet_loss(struct link_entry *entry)
 {
   olsr_update_packet_loss_worker(entry, OLSR_FALSE);
 
-  // timeout for the first lost packet is 1.5 x htime
-
+  /* timeout for the first lost packet is 1.5 x htime */
   olsr_set_timer(&entry->link_loss_timer, entry->loss_hello_int * 1500,
-                 OLSR_LINK_LOSS_JITTER, OLSR_TIMER_PERIODIC,
-                 &olsr_expire_link_loss_timer, entry, 0);
+                OLSR_LINK_LOSS_JITTER, OLSR_TIMER_PERIODIC,
+                &olsr_expire_link_loss_timer, entry, 0);
 }
 
 /*
index 26a58b1..f8d15c3 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
  * The olsr.org Optimized Link-State Routing daemon(olsrd)
  * Copyright (c) 2004, Andreas TÃ\83¸nnesen(andreto@olsr.org)
@@ -38,7 +39,6 @@
  *
  */
 
-
 /*
  * Link sensing database for the OLSR routing daemon
  */
@@ -52,8 +52,7 @@
 
 #define MID_ALIAS_HACK_VTIME  10.0
 
-struct link_entry
-{
+struct link_entry {
   union olsr_ip_addr local_iface_addr;
   union olsr_ip_addr neighbor_iface_addr;
   const struct interface *inter;
@@ -66,12 +65,12 @@ struct link_entry
   olsr_u8_t prev_status;
 
   /*
-   *Hysteresis
+   * Hysteresis
    */
   float L_link_quality;
   int L_link_pending;
   clock_t L_LOST_LINK_time;
-  struct timer_entry *link_hello_timer; /* When we should receive a new HELLO */
+  struct timer_entry *link_hello_timer;        /* When we should receive a new HELLO */
   double last_htime;
   olsr_bool olsr_seqno_valid;
   olsr_u16_t olsr_seqno;
@@ -82,22 +81,23 @@ struct link_entry
   double loss_hello_int;
   struct timer_entry *link_loss_timer;
 
-  float loss_link_multiplier; // user defined multiplies for link quality
-  
-  // cost of this link
+  /* user defined multiplies for link quality, multiplied with 65536 */
+  olsr_u32_t loss_link_multiplier;
+
+  /* cost of this link */
   olsr_linkcost linkcost;
 
-  struct list_node link_list; /* double linked list of all link entries */
-  char                  linkquality[0];
+  struct list_node link_list;         /* double linked list of all link entries */
+  char linkquality[0];
 };
 
 /* inline to recast from link_list back to link_entry */
 LISTNODE2STRUCT(list2link, struct link_entry, link_list);
 
-#define OLSR_LINK_JITTER       5 /* percent */
-#define OLSR_LINK_HELLO_JITTER 0 /* percent jitter */
-#define OLSR_LINK_SYM_JITTER   0 /* percent jitter */
-#define OLSR_LINK_LOSS_JITTER  0 /* percent jitter */
+#define OLSR_LINK_JITTER       5       /* percent */
+#define OLSR_LINK_HELLO_JITTER 0       /* percent jitter */
+#define OLSR_LINK_SYM_JITTER   0       /* percent jitter */
+#define OLSR_LINK_LOSS_JITTER  0       /* percent jitter */
 
 /* deletion safe macro for link entry traversal */
 #define OLSR_FOR_ALL_LINK_ENTRIES(link) \
@@ -116,41 +116,32 @@ extern olsr_bool link_changes;
 
 /* Function prototypes */
 
-void olsr_set_link_timer(struct link_entry *, unsigned int );
+void olsr_set_link_timer(struct link_entry *, unsigned int);
 void olsr_init_link_set(void);
 void olsr_delete_link_entry_by_ip(const union olsr_ip_addr *);
 void olsr_expire_link_hello_timer(void *);
 void olsr_update_packet_loss_worker(struct link_entry *, olsr_bool);
-void signal_link_changes(olsr_bool); /* XXX ugly */
-
-
-struct link_entry *
-get_best_link_to_neighbor(const union olsr_ip_addr *);
-
-struct link_entry *
-lookup_link_entry(const union olsr_ip_addr *, const union olsr_ip_addr *remote_main, const struct interface *);
-
-struct link_entry *
-update_link_entry(const union olsr_ip_addr *, const union olsr_ip_addr *, const struct hello_message *, const struct interface *);
-
-int
-check_neighbor_link(const union olsr_ip_addr *);
+void signal_link_changes(olsr_bool);   /* XXX ugly */
 
-int
-replace_neighbor_link_set(const struct neighbor_entry *,
-                         struct neighbor_entry *);
 
-int
-lookup_link_status(const struct link_entry *);
+struct link_entry *get_best_link_to_neighbor(const union olsr_ip_addr *);
 
-void 
-olsr_update_packet_loss_hello_int(struct link_entry *, double);
+struct link_entry *lookup_link_entry(const union olsr_ip_addr *,
+                                    const union olsr_ip_addr *remote_main,
+                                    const struct interface *);
 
-void 
-olsr_update_packet_loss(struct link_entry *entry);
+struct link_entry *update_link_entry(const union olsr_ip_addr *,
+                                    const union olsr_ip_addr *,
+                                    const struct hello_message *,
+                                    const struct interface *);
 
-void 
-olsr_print_link_set(void);
+int check_neighbor_link(const union olsr_ip_addr *);
+int replace_neighbor_link_set(const struct neighbor_entry *,
+                           struct neighbor_entry *);
+int lookup_link_status(const struct link_entry *);
+void olsr_update_packet_loss_hello_int(struct link_entry *, double);
+void olsr_update_packet_loss(struct link_entry *entry);
+void olsr_print_link_set(void);
 
 #endif
 
index 46b93b2..88e1d3c 100644 (file)
@@ -123,7 +123,6 @@ create_lq_hello(struct lq_hello_message *lq_hello, struct interface *outif)
     neigh->addr = walker->neighbor_iface_addr;
       
     // queue the neighbour entry
-
     neigh->next = lq_hello->neigh;
     lq_hello->neigh = neigh;
 
@@ -241,8 +240,29 @@ create_lq_tc(struct lq_tc_message *lq_tc, struct interface *outif)
     }
 
     /* Queue the neighbour entry. */
-    neigh->next = lq_tc->neigh;
-    lq_tc->neigh = neigh;
+
+    // TODO: ugly hack until neighbor table is ported to avl tree
+    
+    if (lq_tc->neigh == NULL || avl_comp_default(&lq_tc->neigh->address, &neigh->address) > 0) {
+      neigh->next = lq_tc->neigh;
+      lq_tc->neigh = neigh;
+    }
+    else {
+      struct tc_mpr_addr *last = lq_tc->neigh, *n = last->next;
+      
+      while (n) {
+        if (avl_comp_default(&n->address, &neigh->address) > 0) {
+          break;
+        }
+        last = n;
+        n = n->next;
+      }
+      neigh->next = n;
+      last->next = neigh;
+    }
+
+    // neigh->next = lq_tc->neigh;
+    // lq_tc->neigh = neigh;
 
   } OLSR_FOR_ALL_NBR_ENTRIES_END(walker);
 }
@@ -471,6 +491,35 @@ serialize_lq_hello(struct lq_hello_message *lq_hello, struct interface *outif)
   net_outbuffer_push(outif, msg_buffer, size + off);
 }
 
+static olsr_u8_t
+calculate_border_flag(void *lower_border, void *higher_border) {
+       olsr_u8_t *lower = lower_border;
+       olsr_u8_t *higher = higher_border;
+       olsr_u8_t bitmask;
+       olsr_u8_t part, bitpos;
+       
+       for (part = 0; part < olsr_cnf->ipsize; part ++) {
+               if (lower[part] != higher[part]) {
+                       break;
+               }
+       }
+       
+       if (part == olsr_cnf->ipsize) { // same IPs ?
+               return 0;
+       }
+       
+       // look for first bit of difference
+       bitmask = 0xfe;
+       for (bitpos = 0; bitpos < 8; bitpos++, bitmask <<= 1) {
+               if ((lower[part] & bitmask) == (higher[part] & bitmask)) {
+                       break;
+               }
+       }
+       
+  bitpos += 8 * (olsr_cnf->ipsize - part - 1);
+       return bitpos + 1;
+}
+
 static void
 serialize_lq_tc(struct lq_tc_message *lq_tc, struct interface *outif)
 {
@@ -479,6 +528,9 @@ serialize_lq_tc(struct lq_tc_message *lq_tc, struct interface *outif)
   struct tc_mpr_addr *neigh;
   unsigned char *buff;
 
+  union olsr_ip_addr *last_ip = NULL;
+  olsr_u8_t left_border_flag = 0xff;
+  
   // leave space for the OLSR header
 
   off = common_size();
@@ -488,8 +540,9 @@ serialize_lq_tc(struct lq_tc_message *lq_tc, struct interface *outif)
   head = (struct lq_tc_header *)(msg_buffer + off);
 
   head->ansn = htons(lq_tc->ansn);
-  head->reserved = 0;
-
+  head->lower_border = 0;
+  head->upper_border = 0;
+  
   // 'off' is the offset of the byte following the LQ_TC header
 
   off += sizeof (struct lq_tc_header);
@@ -534,6 +587,10 @@ serialize_lq_tc(struct lq_tc_message *lq_tc, struct interface *outif)
     // TODO sizeof_tc_lq function required
       if ((int)(size + olsr_cnf->ipsize + 4) > rem)
         {
+         head->lower_border = left_border_flag;
+         head->upper_border = calculate_border_flag(last_ip, &neigh->address);
+         left_border_flag = head->upper_border;
+         
           // finalize the OLSR header
 
           lq_tc->comm.size = size + off;
@@ -554,6 +611,10 @@ serialize_lq_tc(struct lq_tc_message *lq_tc, struct interface *outif)
 
       // add the current neighbor's IP address
       genipcopy(buff + size, &neigh->address);
+      
+      // remember last ip
+      last_ip = (union olsr_ip_addr *)(buff+size);
+      
       size += olsr_cnf->ipsize;
 
       // add the corresponding link quality
@@ -562,6 +623,8 @@ serialize_lq_tc(struct lq_tc_message *lq_tc, struct interface *outif)
 
   // finalize the OLSR header
 
+  head->lower_border = left_border_flag;
+  head->upper_border = 0xff;
   lq_tc->comm.size = size + off;
 
   serialize_common((struct olsr_common *)lq_tc);
index 2b0670f..de8952f 100644 (file)
@@ -137,7 +137,8 @@ struct lq_tc_message
 struct lq_tc_header
 {
   olsr_u16_t ansn;
-  olsr_u16_t reserved;
+  olsr_u8_t lower_border;
+  olsr_u8_t upper_border;
 };
 
 static INLINE void        pkt_get_u8(const olsr_u8_t **p, olsr_u8_t  *var)         { *var =       *(const olsr_u8_t *)(*p);          *p += sizeof(olsr_u8_t); }
index b4e8ee0..526c846 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
  * The olsr.org Optimized Link-State Routing daemon(olsrd)
  * Copyright (c) 2008 Henning Rogge <rogge@fgan.de>
 
 #include "tc_set.h"
 #include "link_set.h"
-#include "lq_route.h"
+#include "olsr_spf.h"
 #include "lq_packet.h"
 #include "packet.h"
 #include "olsr.h"
 #include "two_hop_neighbor_table.h"
+#include "common/avl.h"
+
+#include "lq_plugin_default_float.h"
+#include "lq_plugin_default_fpm.h"
+
+struct avl_tree lq_handler_tree;
+struct lq_handler *active_lq_handler = NULL;
 
-#include "lq_plugin_default.h"
-#include "lq_plugin.h"
-
-/* Default lq plugin settings */
-struct lq_handler default_lq_handler = {
-    &default_calc_cost,
-    &default_calc_cost,
-               
-    &default_olsr_is_relevant_costchange,
-               
-    &default_packet_loss_worker,
-    &default_olsr_memorize_foreign_hello_lq,
-    &default_olsr_copy_link_lq_into_tc,
-    &default_olsr_clear_lq,
-    &default_olsr_clear_lq,
-               
-    &default_olsr_serialize_hello_lq_pair,
-    &default_olsr_serialize_tc_lq_pair,
-    &default_olsr_deserialize_hello_lq_pair,
-    &default_olsr_deserialize_tc_lq_pair,
-               
-    &default_olsr_print_lq,
-    &default_olsr_print_lq,
-    &default_olsr_print_cost, 
-               
-    sizeof(struct default_lq),
-    sizeof(struct default_lq)
-};
-
-struct lq_handler *active_lq_handler = &default_lq_handler;
+int
+avl_strcasecmp(const void *str1, const void *str2)
+{
+  return strcasecmp(str1, str2);
+}
+
+
+void
+init_lq_handler_tree(void)
+{
+  avl_init(&lq_handler_tree, &avl_strcasecmp);
+  register_lq_handler(&lq_etx_float_handler, LQ_ALGORITHM_ETX_FLOAT_NAME);
+  register_lq_handler(&lq_etx_fpm_handler, LQ_ALGORITHM_ETX_FPM_NAME);
+  
+  if (activate_lq_handler(olsr_cnf->lq_algorithm)) {
+    activate_lq_handler(LQ_ALGORITHM_ETX_FPM_NAME);
+  }
+}
 
 /*
  * set_lq_handler
@@ -83,19 +79,42 @@ struct lq_handler *active_lq_handler = &default_lq_handler;
  * this function is used by routing metric plugins to activate their link
  * quality handler
  * 
+ * The name parameter is marked as "unused" to squelch a compiler warning if debug
+ * output is not active
+ * 
  * @param pointer to lq_handler structure
  * @param name of the link quality handler for debug output
  */
-void set_lq_handler(struct lq_handler *handler, const char *name) {
-  if (handler) {
-    OLSR_PRINTF(1, "Activated lq_handler: %s\n", name);
-    active_lq_handler = handler;
-  } else {
-    OLSR_PRINTF(1, "Activated lq_handler: default\n");
-    active_lq_handler = &default_lq_handler;
-  }
+void
+register_lq_handler(struct lq_handler *handler, const char *name)
+{
+  struct lq_handler_node *node;
+  
+  node = olsr_malloc(sizeof(struct lq_handler) + strlen(name) + 1, "olsr lq handler");
+  
+  strcpy(node->name, name);
+  node->node.key = node->name;
+  node->handler = handler;
+  
+  avl_insert(&lq_handler_tree, &node->node, OLSR_FALSE); 
+}
 
-  name = NULL; /* squelch compiler warning */
+int
+activate_lq_handler(const char *name)
+{
+  struct lq_handler_node *node;
+  
+  node = (struct lq_handler_node *) avl_find(&lq_handler_tree, name);
+  if (node == NULL) {
+    OLSR_PRINTF(1, "Error, unknown lq_handler '%s'\n", name);
+    return 1;
+  }
+  
+  OLSR_PRINTF(1, "Using '%s' algorithm for lq calculation.\n", name);
+  active_lq_handler = node->handler;
+  active_lq_handler->initialize();
+  
+  return 0;
 }
 
 /*
@@ -106,7 +125,8 @@ void set_lq_handler(struct lq_handler *handler, const char *name) {
  * @param pointer to the tc_edge_entry
  * @return linkcost
  */
-olsr_linkcost olsr_calc_tc_cost(const struct tc_edge_entry *tc_edge)
+olsr_linkcost
+olsr_calc_tc_cost(const struct tc_edge_entry *tc_edge)
 {
   return active_lq_handler->calc_tc_cost(tc_edge->linkquality);
 }
@@ -121,7 +141,9 @@ olsr_linkcost olsr_calc_tc_cost(const struct tc_edge_entry *tc_edge)
  * @param second linkcost value
  * @return boolean
  */
-olsr_bool olsr_is_relevant_costchange(olsr_linkcost c1, olsr_linkcost c2) {
+olsr_bool
+olsr_is_relevant_costchange(olsr_linkcost c1, olsr_linkcost c2)
+{
   return active_lq_handler->is_relevant_costchange(c1, c2);
 }
 
@@ -135,8 +157,11 @@ olsr_bool olsr_is_relevant_costchange(olsr_linkcost c1, olsr_linkcost c2) {
  * @param pointer to lq_hello_neighbor
  * @return number of bytes that have been written
  */
-int olsr_serialize_hello_lq_pair(unsigned char *buff, struct lq_hello_neighbor *neigh) {
-       return active_lq_handler->serialize_hello_lq(buff, neigh->linkquality);
+int
+olsr_serialize_hello_lq_pair(unsigned char *buff,
+                            struct lq_hello_neighbor *neigh)
+{
+  return active_lq_handler->serialize_hello_lq(buff, neigh->linkquality);
 }
 
 /*
@@ -148,9 +173,12 @@ int olsr_serialize_hello_lq_pair(unsigned char *buff, struct lq_hello_neighbor *
  * @param pointer to the current buffer pointer
  * @param pointer to hello_neighbor
  */
-void olsr_deserialize_hello_lq_pair(const olsr_u8_t **curr, struct hello_neighbor *neigh) {
-       active_lq_handler->deserialize_hello_lq(curr, neigh->linkquality);
-       neigh->cost = active_lq_handler->calc_hello_cost(neigh->linkquality);
+void
+olsr_deserialize_hello_lq_pair(const olsr_u8_t ** curr,
+                              struct hello_neighbor *neigh)
+{
+  active_lq_handler->deserialize_hello_lq(curr, neigh->linkquality);
+  neigh->cost = active_lq_handler->calc_hello_cost(neigh->linkquality);
 }
 
 /*
@@ -163,8 +191,10 @@ void olsr_deserialize_hello_lq_pair(const olsr_u8_t **curr, struct hello_neighbo
  * @param pointer to olsr_serialize_tc_lq_pair
  * @return number of bytes that have been written
  */
-int olsr_serialize_tc_lq_pair(unsigned char *buff, struct tc_mpr_addr *neigh) {
-       return active_lq_handler->serialize_tc_lq(buff, neigh->linkquality);
+int
+olsr_serialize_tc_lq_pair(unsigned char *buff, struct tc_mpr_addr *neigh)
+{
+  return active_lq_handler->serialize_tc_lq(buff, neigh->linkquality);
 }
 
 /*
@@ -175,8 +205,10 @@ int olsr_serialize_tc_lq_pair(unsigned char *buff, struct tc_mpr_addr *neigh) {
  * @param pointer to the current buffer pointer
  * @param pointer to tc_edge_entry
  */
-void olsr_deserialize_tc_lq_pair(const olsr_u8_t **curr, struct tc_edge_entry *edge) {
-       active_lq_handler->deserialize_tc_lq(curr, edge->linkquality);
+void
+olsr_deserialize_tc_lq_pair(const olsr_u8_t ** curr, struct tc_edge_entry *edge)
+{
+  active_lq_handler->deserialize_tc_lq(curr, edge->linkquality);
 }
 
 /*
@@ -189,14 +221,15 @@ void olsr_deserialize_tc_lq_pair(const olsr_u8_t **curr, struct tc_edge_entry *e
  * @param pointer to link_entry
  * @param OLSR_TRUE if hello package was lost
  */
-void olsr_update_packet_loss_worker(struct link_entry *entry, olsr_bool lost)
+void
+olsr_update_packet_loss_worker(struct link_entry *entry, olsr_bool lost)
 {
-       olsr_linkcost lq;
-       lq = active_lq_handler->packet_loss_handler(entry->linkquality, lost);
-  
-       if (olsr_is_relevant_costchange(lq, entry->linkcost)) {
+  olsr_linkcost lq;
+  lq = active_lq_handler->packet_loss_handler(entry, entry->linkquality, lost);
+
+  if (olsr_is_relevant_costchange(lq, entry->linkcost)) {
     entry->linkcost = lq;
-    
+
     if (olsr_cnf->lq_dlimit > 0) {
       changes_neighborhood = OLSR_TRUE;
       changes_topology = OLSR_TRUE;
@@ -204,9 +237,8 @@ void olsr_update_packet_loss_worker(struct link_entry *entry, olsr_bool lost)
 
     else
       OLSR_PRINTF(3, "Skipping Dijkstra (1)\n");
-    
-    // XXX - we should check whether we actually
-    // announce this neighbour
+
+    /* XXX - we should check whether we actually announce this neighbour */
     signal_link_changes(OLSR_TRUE);
   }
 }
@@ -221,11 +253,14 @@ void olsr_update_packet_loss_worker(struct link_entry *entry, olsr_bool lost)
  * @param pointer to hello_neighbor, if NULL the neighbor link quality information
  * of the link entry has to be reset to "zero"
  */
-void olsr_memorize_foreign_hello_lq(struct link_entry *local, struct hello_neighbor *foreign) {
+void
+olsr_memorize_foreign_hello_lq(struct link_entry *local,
+                              struct hello_neighbor *foreign)
+{
   if (foreign) {
-    active_lq_handler->memorize_foreign_hello(local->linkquality, foreign->linkquality);
-  }
-  else {
+    active_lq_handler->memorize_foreign_hello(local->linkquality,
+                                             foreign->linkquality);
+  else {
     active_lq_handler->memorize_foreign_hello(local->linkquality, NULL);
   }
 }
@@ -241,7 +276,9 @@ void olsr_memorize_foreign_hello_lq(struct link_entry *local, struct hello_neigh
  * @param buffer for output
  * @return pointer to a buffer with the text representation
  */
-const char *get_link_entry_text(struct link_entry *entry, struct lqtextbuffer *buffer) {
+const char *
+get_link_entry_text(struct link_entry *entry, struct lqtextbuffer *buffer)
+{
   return active_lq_handler->print_hello_lq(entry->linkquality, buffer);
 }
 
@@ -256,7 +293,9 @@ const char *get_link_entry_text(struct link_entry *entry, struct lqtextbuffer *b
  * @param pointer to buffer
  * @return pointer to the buffer with the text representation
  */
-const char *get_tc_edge_entry_text(struct tc_edge_entry *entry, struct lqtextbuffer *buffer) {
+const char *
+get_tc_edge_entry_text(struct tc_edge_entry *entry, struct lqtextbuffer *buffer)
+{
   return active_lq_handler->print_tc_lq(entry->linkquality, buffer);
 }
 
@@ -271,15 +310,17 @@ const char *get_tc_edge_entry_text(struct tc_edge_entry *entry, struct lqtextbuf
  * @param pointer to buffer
  * @return pointer to buffer filled with text
  */
-const char *get_linkcost_text(olsr_linkcost cost, olsr_bool route, struct lqtextbuffer *buffer) {
+const char *
+get_linkcost_text(olsr_linkcost cost, olsr_bool route,
+                 struct lqtextbuffer *buffer)
+{
   static const char *infinite = "INFINITE";
-  
+
   if (route) {
     if (cost == ROUTE_COST_BROKEN) {
       return infinite;
     }
-  }
-  else {
+  } else {
     if (cost >= LINK_COST_BROKEN) {
       return infinite;
     }
@@ -296,8 +337,11 @@ const char *get_linkcost_text(olsr_linkcost cost, olsr_bool route, struct lqtext
  * @param pointer to target lq_hello_neighbor
  * @param pointer to source link_entry
  */
-void olsr_copy_hello_lq(struct lq_hello_neighbor *target, struct link_entry *source) {
-  memcpy(target->linkquality, source->linkquality, active_lq_handler->hello_lq_size);
+void
+olsr_copy_hello_lq(struct lq_hello_neighbor *target, struct link_entry *source)
+{
+  memcpy(target->linkquality, source->linkquality,
+        active_lq_handler->hello_lq_size);
 }
 
 /*
@@ -309,8 +353,12 @@ void olsr_copy_hello_lq(struct lq_hello_neighbor *target, struct link_entry *sou
  * @param pointer to tc_mpr_addr
  * @param pointer to link_entry
  */
-void olsr_copylq_link_entry_2_tc_mpr_addr(struct tc_mpr_addr *target, struct link_entry *source) {
-  active_lq_handler->copy_link_lq_into_tc(target->linkquality, source->linkquality);
+void
+olsr_copylq_link_entry_2_tc_mpr_addr(struct tc_mpr_addr *target,
+                                    struct link_entry *source)
+{
+  active_lq_handler->copy_link_lq_into_tc(target->linkquality,
+                                         source->linkquality);
 }
 
 /*
@@ -322,8 +370,12 @@ void olsr_copylq_link_entry_2_tc_mpr_addr(struct tc_mpr_addr *target, struct lin
  * @param pointer to tc_edge_entry
  * @param pointer to link_entry
  */
-void olsr_copylq_link_entry_2_tc_edge_entry(struct tc_edge_entry *target, struct link_entry *source) {
-  active_lq_handler->copy_link_lq_into_tc(target->linkquality, source->linkquality);
+void
+olsr_copylq_link_entry_2_tc_edge_entry(struct tc_edge_entry *target,
+                                      struct link_entry *source)
+{
+  active_lq_handler->copy_link_lq_into_tc(target->linkquality,
+                                         source->linkquality);
 }
 
 /*
@@ -333,7 +385,9 @@ void olsr_copylq_link_entry_2_tc_edge_entry(struct tc_edge_entry *target, struct
  * 
  * @param pointer to tc_mpr_addr
  */
-void olsr_clear_tc_lq(struct tc_mpr_addr *target) {
+void
+olsr_clear_tc_lq(struct tc_mpr_addr *target)
+{
   active_lq_handler->clear_tc(target->linkquality);
 }
 
@@ -347,13 +401,17 @@ void olsr_clear_tc_lq(struct tc_mpr_addr *target) {
  * 
  * @return pointer to hello_neighbor
  */
-struct hello_neighbor *olsr_malloc_hello_neighbor(const char *id) {
-       struct hello_neighbor *h;
-       
-       h = olsr_malloc(sizeof(struct hello_neighbor) + active_lq_handler->hello_lq_size, id);
-       
-       active_lq_handler->clear_hello(h->linkquality);
-       return h;
+struct hello_neighbor *
+olsr_malloc_hello_neighbor(const char *id)
+{
+  struct hello_neighbor *h;
+
+  h =
+    olsr_malloc(sizeof(struct hello_neighbor) +
+               active_lq_handler->hello_lq_size, id);
+
+  active_lq_handler->clear_hello(h->linkquality);
+  return h;
 }
 
 /*
@@ -366,11 +424,14 @@ struct hello_neighbor *olsr_malloc_hello_neighbor(const char *id) {
  * 
  * @return pointer to tc_mpr_addr
  */
-struct tc_mpr_addr *olsr_malloc_tc_mpr_addr(const char *id) {
+struct tc_mpr_addr *
+olsr_malloc_tc_mpr_addr(const char *id)
+{
   struct tc_mpr_addr *t;
-  
-   t = olsr_malloc(sizeof(struct tc_mpr_addr) + active_lq_handler->tc_lq_size, id);
-  
+
+  t =
+    olsr_malloc(sizeof(struct tc_mpr_addr) + active_lq_handler->tc_lq_size, id);
+
   active_lq_handler->clear_tc(t->linkquality);
   return t;
 }
@@ -385,11 +446,15 @@ struct tc_mpr_addr *olsr_malloc_tc_mpr_addr(const char *id) {
  * 
  * @return pointer to lq_hello_neighbor
  */
-struct lq_hello_neighbor *olsr_malloc_lq_hello_neighbor(const char *id) {
+struct lq_hello_neighbor *
+olsr_malloc_lq_hello_neighbor(const char *id)
+{
   struct lq_hello_neighbor *h;
-  
-  h = olsr_malloc(sizeof(struct lq_hello_neighbor) + active_lq_handler->hello_lq_size, id);
-  
+
+  h =
+    olsr_malloc(sizeof(struct lq_hello_neighbor) +
+               active_lq_handler->hello_lq_size, id);
+
   active_lq_handler->clear_hello(h->linkquality);
   return h;
 }
@@ -404,11 +469,15 @@ struct lq_hello_neighbor *olsr_malloc_lq_hello_neighbor(const char *id) {
  * 
  * @return pointer to link_entry
  */
-struct link_entry *olsr_malloc_link_entry(const char *id) {
+struct link_entry *
+olsr_malloc_link_entry(const char *id)
+{
   struct link_entry *h;
-  
-  h =  olsr_malloc(sizeof(struct link_entry) + active_lq_handler->hello_lq_size, id);
-  
+
+  h =
+    olsr_malloc(sizeof(struct link_entry) + active_lq_handler->hello_lq_size,
+               id);
+
   active_lq_handler->clear_hello(h->linkquality);
   return h;
 }
@@ -423,11 +492,15 @@ struct link_entry *olsr_malloc_link_entry(const char *id) {
  * 
  * @return pointer to tc_edge_entry
  */
-struct tc_edge_entry *olsr_malloc_tc_edge_entry(const char *id) {
+struct tc_edge_entry *
+olsr_malloc_tc_edge_entry(const char *id)
+{
   struct tc_edge_entry *t;
-  
-  t = olsr_malloc(sizeof(struct tc_edge_entry) + active_lq_handler->tc_lq_size, id);
-  
+
+  t =
+    olsr_malloc(sizeof(struct tc_edge_entry) + active_lq_handler->tc_lq_size,
+               id);
+
   active_lq_handler->clear_tc(t);
   return t;
 }
index a7b8cfa..af91cf6 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
  * The olsr.org Optimized Link-State Routing daemon(olsrd)
  * Copyright (c) 2008 Henning Rogge <rogge@fgan.de>
 
 #include "tc_set.h"
 #include "link_set.h"
-#include "lq_route.h"
+#include "olsr_spf.h"
 #include "lq_packet.h"
 #include "packet.h"
+#include "common/avl.h"
 
 #define LINK_COST_BROKEN (1<<22)
 #define ROUTE_COST_BROKEN (0xffffffff)
 #define ZERO_ROUTE_COST 0
 
+#define MINIMAL_USEFUL_LQ 0.1
+
+#define LQ_QUICKSTART_STEPS 12
+#define LQ_QUICKSTART_AGING 0.25
+
 struct lqtextbuffer {
   char buf[16];
 };
 
 struct lq_handler {
-  olsr_linkcost (*calc_hello_cost)(const void *lq);
-  olsr_linkcost (*calc_tc_cost)(const void *lq);
-  
-  olsr_bool (*is_relevant_costchange)(olsr_linkcost c1, olsr_linkcost c2);
-  
-  olsr_linkcost (*packet_loss_handler)(void *lq, olsr_bool lost);
-  
-  void (*memorize_foreign_hello)(void *local, void *foreign);
-  void (*copy_link_lq_into_tc)(void *target, void *source);
-  void (*clear_hello)(void *target);
-  void (*clear_tc)(void *target);
-  
-  int (*serialize_hello_lq)(unsigned char *buff, void *lq);
-  int (*serialize_tc_lq)(unsigned char *buff, void *lq);
-  void (*deserialize_hello_lq)(const olsr_u8_t **curr, void *lq);
-  void (*deserialize_tc_lq)(const olsr_u8_t **curr, void *lq);
-  
-  const char *(*print_hello_lq)(void *ptr, struct lqtextbuffer *buffer);
-  const char *(*print_tc_lq)(void *ptr, struct lqtextbuffer *buffer);
-  const char *(*print_cost)(olsr_linkcost cost, struct lqtextbuffer *buffer);
+  void (*initialize)(void);
   
+  olsr_linkcost(*calc_hello_cost) (const void *lq);
+  olsr_linkcost(*calc_tc_cost) (const void *lq);
+
+  olsr_bool(*is_relevant_costchange) (olsr_linkcost c1, olsr_linkcost c2);
+
+  olsr_linkcost(*packet_loss_handler) (struct link_entry * entry, void *lq,
+                                      olsr_bool lost);
+
+  void (*memorize_foreign_hello) (void *local, void *foreign);
+  void (*copy_link_lq_into_tc) (void *target, void *source);
+  void (*clear_hello) (void *target);
+  void (*clear_tc) (void *target);
+
+  int (*serialize_hello_lq) (unsigned char *buff, void *lq);
+  int (*serialize_tc_lq) (unsigned char *buff, void *lq);
+  void (*deserialize_hello_lq) (const olsr_u8_t ** curr, void *lq);
+  void (*deserialize_tc_lq) (const olsr_u8_t ** curr, void *lq);
+
+  const char *(*print_hello_lq) (void *ptr, struct lqtextbuffer * buffer);
+  const char *(*print_tc_lq) (void *ptr, struct lqtextbuffer * buffer);
+  const char *(*print_cost) (olsr_linkcost cost, struct lqtextbuffer * buffer);
+
   size_t hello_lq_size;
   size_t tc_lq_size;
 };
 
-void set_lq_handler(struct lq_handler *handler, const char *name);
+struct lq_handler_node {
+  struct avl_node node;
+  struct lq_handler *handler; 
+  char name[0];
+};
+
+AVLNODE2STRUCT(lq_handler_tree2lq_handler_node, struct lq_handler_node, node);
+
+#define OLSR_FOR_ALL_LQ_HANDLERS(lq) \
+{ \
+  struct avl_node *lq_tree_node, *next_lq_tree_node; \
+  for (lq_tree_node = avl_walk_first(&lq_handler_tree); \
+    lq_tree_node; lq_tree_node = next_lq_tree_node) { \
+    next_lq_tree_node = avl_walk_next(lq_tree_node); \
+    lq = lq_handler_tree2lq_handler_node(lq_tree_node);
+#define OLSR_FOR_ALL_LQ_HANDLERS_END(tc) }}
+
+int avl_strcasecmp(const void *str1, const void *str2);
+void init_lq_handler_tree(void);
+
+void register_lq_handler(struct lq_handler *handler, const char *name);
+int activate_lq_handler(const char *name);
 
 olsr_linkcost olsr_calc_tc_cost(const struct tc_edge_entry *);
 olsr_bool olsr_is_relevant_costchange(olsr_linkcost c1, olsr_linkcost c2);
 
-int olsr_serialize_hello_lq_pair(unsigned char *buff, struct lq_hello_neighbor *neigh);
-void olsr_deserialize_hello_lq_pair(const olsr_u8_t **curr, struct hello_neighbor *neigh);
+int olsr_serialize_hello_lq_pair(unsigned char *buff,
+                                struct lq_hello_neighbor *neigh);
+void olsr_deserialize_hello_lq_pair(const olsr_u8_t ** curr,
+                                   struct hello_neighbor *neigh);
 int olsr_serialize_tc_lq_pair(unsigned char *buff, struct tc_mpr_addr *neigh);
-void olsr_deserialize_tc_lq_pair(const olsr_u8_t **curr, struct tc_edge_entry *edge);
+void olsr_deserialize_tc_lq_pair(const olsr_u8_t ** curr,
+                                struct tc_edge_entry *edge);
 
 void olsr_update_packet_loss_worker(struct link_entry *entry, olsr_bool lost);
-void olsr_memorize_foreign_hello_lq(struct link_entry *local, struct hello_neighbor *foreign);
+void olsr_memorize_foreign_hello_lq(struct link_entry *local,
+                                   struct hello_neighbor *foreign);
 
-const char *get_link_entry_text(struct link_entry *entry, struct lqtextbuffer *buffer);
-const char *get_tc_edge_entry_text(struct tc_edge_entry *entry, struct lqtextbuffer *buffer);
-const char *get_linkcost_text(olsr_linkcost cost, olsr_bool route, struct lqtextbuffer *buffer);
+const char *get_link_entry_text(struct link_entry *entry,
+                               struct lqtextbuffer *buffer);
+const char *get_tc_edge_entry_text(struct tc_edge_entry *entry,
+                                  struct lqtextbuffer *buffer);
+const char *get_linkcost_text(olsr_linkcost cost, olsr_bool route,
+                             struct lqtextbuffer *buffer);
 
-void olsr_copy_hello_lq(struct lq_hello_neighbor *target, struct link_entry *source);
-void olsr_copylq_link_entry_2_tc_mpr_addr(struct tc_mpr_addr *target, struct link_entry *source);
-void olsr_copylq_link_entry_2_tc_edge_entry(struct tc_edge_entry *target, struct link_entry *source);
+void olsr_copy_hello_lq(struct lq_hello_neighbor *target,
+                       struct link_entry *source);
+void olsr_copylq_link_entry_2_tc_mpr_addr(struct tc_mpr_addr *target,
+                                         struct link_entry *source);
+void olsr_copylq_link_entry_2_tc_edge_entry(struct tc_edge_entry *target,
+                                           struct link_entry *source);
 void olsr_clear_tc_lq(struct tc_mpr_addr *target);
 
 struct hello_neighbor *olsr_malloc_hello_neighbor(const char *id);
@@ -112,7 +153,7 @@ struct tc_edge_entry *olsr_malloc_tc_edge_entry(const char *id);
 /* Externals. */
 extern struct lq_handler *active_lq_handler;
 
-#endif /*LQPLUGIN_H_*/
+#endif /*LQPLUGIN_H_ */
 
 /*
  * Local Variables:
diff --git a/src/lq_plugin_default.c b/src/lq_plugin_default.c
deleted file mode 100644 (file)
index b1445cd..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * The olsr.org Optimized Link-State Routing daemon(olsrd)
- * Copyright (c) 2008 Henning Rogge <rogge@fgan.de>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions 
- * are met:
- *
- * * Redistributions of source code must retain the above copyright 
- *   notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright 
- *   notice, this list of conditions and the following disclaimer in 
- *   the documentation and/or other materials provided with the 
- *   distribution.
- * * Neither the name of olsr.org, olsrd nor the names of its 
- *   contributors may be used to endorse or promote products derived 
- *   from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * Visit http://www.olsr.org for more information.
- *
- * If you find this software useful feel free to make a donation
- * to the project. For more information see the website or contact
- * the copyright holders.
- *
- */
-
-#include "tc_set.h"
-#include "link_set.h"
-#include "lq_route.h"
-#include "lq_packet.h"
-#include "packet.h"
-#include "olsr.h"
-#include "lq_plugin_default.h"
-
-olsr_linkcost default_calc_cost(const void *ptr) {
-  const struct default_lq *lq = ptr;
-  
-  float etx = (lq->lq < 0.1 || lq->nlq < 0.1 ? LINK_COST_BROKEN : 1.0/(lq->lq * lq->nlq));
-  olsr_linkcost cost = (olsr_linkcost)(etx  * LQ_PLUGIN_LC_MULTIPLIER);
-  
-  if (cost > LINK_COST_BROKEN)
-    return LINK_COST_BROKEN;
-  if (cost == 0)
-    return 1;
-  return cost;
-}
-
-int default_olsr_serialize_hello_lq_pair(unsigned char *buff, void *ptr) {
-  struct default_lq *lq = ptr;
-  
-  buff[0] = (unsigned char)(lq->lq * 255);
-  buff[1] = (unsigned char)(lq->nlq * 255);
-  buff[2] = (unsigned char)(0);
-  buff[3] = (unsigned char)(0);
-  
-  return 4;
-}
-
-void default_olsr_deserialize_hello_lq_pair(const olsr_u8_t **curr, void *ptr) {
-  struct default_lq *lq = ptr;
-  
-  pkt_get_lq(curr, &lq->lq);
-  pkt_get_lq(curr, &lq->nlq);
-  pkt_ignore_u16(curr);
-}
-
-olsr_bool default_olsr_is_relevant_costchange(olsr_linkcost c1, olsr_linkcost c2) {
-  if (c1 > c2) {
-    return c2 - c1 > LQ_PLUGIN_RELEVANT_COSTCHANGE;
-  }
-  return c1 - c2 > LQ_PLUGIN_RELEVANT_COSTCHANGE;
-}
-
-int default_olsr_serialize_tc_lq_pair(unsigned char *buff, void *ptr) {
-  struct default_lq *lq = ptr;
-  
-  buff[0] = (unsigned char)(lq->lq * 255);
-  buff[1] = (unsigned char)(lq->nlq * 255);
-  buff[2] = (unsigned char)(0);
-  buff[3] = (unsigned char)(0);
-  
-  return 4;
-}
-
-void default_olsr_deserialize_tc_lq_pair(const olsr_u8_t **curr, void *ptr) {
-  struct default_lq *lq = ptr;
-  
-  pkt_get_lq(curr, &lq->lq);
-  pkt_get_lq(curr, &lq->nlq);
-  pkt_ignore_u16(curr);
-}
-
-olsr_linkcost default_packet_loss_worker(void *ptr, olsr_bool lost) {
-  struct default_lq *tlq = ptr;
-  float alpha;
-  
-  // calculate exponental factor for the new link quality, could be directly done in configuration !
-  alpha = 1 / (float)(olsr_cnf->lq_wsize);
-  
-  // exponential moving average
-  tlq->lq *= (1 - alpha);
-  if (lost == 0) {
-    tlq->lq += alpha;
-  }
-  return default_calc_cost(ptr);
-}
-
-void default_olsr_memorize_foreign_hello_lq(void *ptrLocal, void *ptrForeign) {
-  struct default_lq *local = ptrLocal;
-  struct default_lq *foreign = ptrForeign;
-  
-  if (foreign) {
-    local->nlq = foreign->lq;
-  }
-  else {
-    local->nlq = 0;
-  }
-}
-
-void default_olsr_copy_link_lq_into_tc(void *target, void *source) {
-  memcpy(target, source, sizeof(struct default_lq));
-}
-
-void default_olsr_clear_lq(void *target) {
-  memset(target, 0, sizeof(struct default_lq));
-}
-
-const char *default_olsr_print_lq(void *ptr, struct lqtextbuffer *buffer) {
-  struct default_lq *lq = ptr;
-  
-  sprintf(buffer->buf, "%2.3f/%2.3f", lq->lq, lq->nlq);
-  return buffer->buf;
-}
-
-const char *default_olsr_print_cost(olsr_linkcost cost, struct lqtextbuffer *buffer) {
-  sprintf(buffer->buf, "%2.3f", ((float)cost)/LQ_PLUGIN_LC_MULTIPLIER);
-  return buffer->buf;
-}
diff --git a/src/lq_plugin_default_float.c b/src/lq_plugin_default_float.c
new file mode 100644 (file)
index 0000000..5a574ff
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * The olsr.org Optimized Link-State Routing daemon(olsrd)
+ * Copyright (c) 2008 Henning Rogge <rogge@fgan.de>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright 
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright 
+ *   notice, this list of conditions and the following disclaimer in 
+ *   the documentation and/or other materials provided with the 
+ *   distribution.
+ * * Neither the name of olsr.org, olsrd nor the names of its 
+ *   contributors may be used to endorse or promote products derived 
+ *   from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Visit http://www.olsr.org for more information.
+ *
+ * If you find this software useful feel free to make a donation
+ * to the project. For more information see the website or contact
+ * the copyright holders.
+ *
+ */
+
+#include "tc_set.h"
+#include "link_set.h"
+#include "olsr_spf.h"
+#include "lq_packet.h"
+#include "packet.h"
+#include "olsr.h"
+#include "lq_plugin_default_float.h"
+
+/* Default lq plugin settings */
+struct lq_handler lq_etx_float_handler = {
+  &default_lq_initialize_float,
+  
+  &default_lq_calc_cost_float,
+  &default_lq_calc_cost_float,
+
+  &default_lq_is_relevant_costchange_float,
+
+  &default_lq_packet_loss_worker_float,
+  &default_lq_memorize_foreign_hello_float,
+  &default_lq_copy_link2tc_float,
+  &default_lq_clear_float,
+  &default_lq_clear_float,
+
+  &default_lq_serialize_hello_lq_pair_float,
+  &default_lq_serialize_tc_lq_pair_float,
+  &default_lq_deserialize_hello_lq_pair_float,
+  &default_lq_deserialize_tc_lq_pair_float,
+
+  &default_lq_print_float,
+  &default_lq_print_float,
+  &default_lq_print_cost_float,
+
+  sizeof(struct default_lq_float),
+  sizeof(struct default_lq_float)
+};
+
+void default_lq_initialize_float(void) {
+  return;
+}
+
+olsr_linkcost default_lq_calc_cost_float(const void *ptr) {
+  const struct default_lq_float *lq = ptr;
+  olsr_linkcost cost;
+  
+  if (lq->lq < MINIMAL_USEFUL_LQ || lq->nlq < MINIMAL_USEFUL_LQ) {
+    return LINK_COST_BROKEN;
+  }
+  
+  cost = (olsr_linkcost)(1.0/(lq->lq * lq->nlq) * LQ_PLUGIN_LC_MULTIPLIER);
+  
+  if (cost > LINK_COST_BROKEN)
+    return LINK_COST_BROKEN;
+  if (cost == 0) {
+    return 1;
+  }
+  return cost;
+}
+
+int default_lq_serialize_hello_lq_pair_float(unsigned char *buff, void *ptr) {
+  struct default_lq_float *lq = ptr;
+  
+  olsr_u16_t lq_value = (olsr_u16_t)(lq->lq * 65535);
+  olsr_u16_t nlq_value = (olsr_u16_t)(lq->nlq * 65535);
+  
+  buff[0] = (unsigned char)(lq_value / 256);
+  buff[1] = (unsigned char)(nlq_value / 256);
+  buff[2] = (unsigned char)(lq_value & 255);
+  buff[3] = (unsigned char)(nlq_value & 255);
+  
+  return 4;
+}
+
+void default_lq_deserialize_hello_lq_pair_float(const olsr_u8_t **curr, void *ptr) {
+  struct default_lq_float *lq = ptr;
+  
+  olsr_u8_t lq_high, lq_low, nlq_high, nlq_low;
+  olsr_u16_t lq_value, nlq_value;
+  
+  pkt_get_u8(curr, &lq_high);
+  pkt_get_u8(curr, &nlq_high);
+  pkt_get_u8(curr, &lq_low);
+  pkt_get_u8(curr, &nlq_low);
+  
+  lq_value = 256 * (olsr_u16_t)lq_high + (olsr_u16_t)lq_low;
+  nlq_value = 256 * (olsr_u16_t)nlq_high + (olsr_u16_t)nlq_low;
+  
+  lq->lq = (float)lq_value / 65535.0;
+  lq->nlq = (float)nlq_value / 65535.0;
+}
+
+olsr_bool default_lq_is_relevant_costchange_float(olsr_linkcost c1, olsr_linkcost c2) {
+  if (c1 > c2) {
+    return c2 - c1 > LQ_PLUGIN_RELEVANT_COSTCHANGE;
+  }
+  return c1 - c2 > LQ_PLUGIN_RELEVANT_COSTCHANGE;
+}
+
+int default_lq_serialize_tc_lq_pair_float(unsigned char *buff, void *ptr) {
+  struct default_lq_float *lq = ptr;
+  
+  olsr_u16_t lq_value = (olsr_u16_t)(lq->lq * 65535);
+  olsr_u16_t nlq_value = (olsr_u16_t)(lq->nlq * 65535);
+  
+  buff[0] = (unsigned char)(lq_value / 256);
+  buff[1] = (unsigned char)(nlq_value / 256);
+  buff[2] = (unsigned char)(lq_value & 255);
+  buff[3] = (unsigned char)(nlq_value & 255);
+  
+  return 4;
+}
+
+void default_lq_deserialize_tc_lq_pair_float(const olsr_u8_t **curr, void *ptr) {
+  struct default_lq_float *lq = ptr;
+  
+  olsr_u8_t lq_high, lq_low, nlq_high, nlq_low;
+  olsr_u16_t lq_value, nlq_value;
+  
+  pkt_get_u8(curr, &lq_high);
+  pkt_get_u8(curr, &nlq_high);
+  pkt_get_u8(curr, &lq_low);
+  pkt_get_u8(curr, &nlq_low);
+  
+  lq_value = 256 * (olsr_u16_t)lq_high + (olsr_u16_t)lq_low;
+  nlq_value = 256 * (olsr_u16_t)nlq_high + (olsr_u16_t)nlq_low;
+  
+  lq->lq = (float)lq_value / 65535.0;
+  lq->nlq = (float)nlq_value / 65535.0;
+}
+
+olsr_linkcost default_lq_packet_loss_worker_float(struct link_entry *link, void *ptr, olsr_bool lost) {
+  struct default_lq_float *tlq = ptr;
+  float alpha = olsr_cnf->lq_aging;
+  
+  if (tlq->quickstart < LQ_QUICKSTART_STEPS) {
+    alpha = LQ_QUICKSTART_AGING; /* fast enough to get the LQ value within 6 Hellos up to 0.9 */
+    tlq->quickstart++;
+  }
+  // exponential moving average
+  tlq->lq *= (1 - alpha);
+  if (lost == 0) {
+    tlq->lq += (alpha * link->loss_link_multiplier / 65536);
+  }
+  return default_lq_calc_cost_float(ptr);
+}
+
+void default_lq_memorize_foreign_hello_float(void *ptrLocal, void *ptrForeign) {
+  struct default_lq_float *local = ptrLocal;
+  struct default_lq_float *foreign = ptrForeign;
+  
+  if (foreign) {
+    local->nlq = foreign->lq;
+  }
+  else {
+    local->nlq = 0;
+  }
+}
+
+void default_lq_copy_link2tc_float(void *target, void *source) {
+  memcpy(target, source, sizeof(struct default_lq_float));
+}
+
+void default_lq_clear_float(void *target) {
+  memset(target, 0, sizeof(struct default_lq_float));
+}
+
+const char *default_lq_print_float(void *ptr, struct lqtextbuffer *buffer) {
+  struct default_lq_float *lq = ptr;
+  
+  sprintf(buffer->buf, "%2.3f/%2.3f", lq->lq, lq->nlq);
+  return buffer->buf;
+}
+
+const char *default_lq_print_cost_float(olsr_linkcost cost, struct lqtextbuffer *buffer) {
+  sprintf(buffer->buf, "%2.3f", ((float)cost)/LQ_PLUGIN_LC_MULTIPLIER);
+  return buffer->buf;
+}
similarity index 65%
rename from src/lq_plugin_default.h
rename to src/lq_plugin_default_float.h
index aec7def..09b8aaa 100644 (file)
 #include "olsr_types.h"
 #include "lq_plugin.h"
 
+#define LQ_ALGORITHM_ETX_FLOAT_NAME "etx_float"
+
 #define LQ_PLUGIN_LC_MULTIPLIER 1024
 #define LQ_PLUGIN_RELEVANT_COSTCHANGE 8
 
-struct default_lq {
-       float lq, nlq;
+struct default_lq_float {
+  float lq, nlq;
+  olsr_u16_t quickstart;
 };
 
-olsr_linkcost default_calc_cost(const void *lq);
+void default_lq_initialize_float(void);
+
+olsr_linkcost default_lq_calc_cost_float(const void *lq);
+
+olsr_bool default_lq_is_relevant_costchange_float(olsr_linkcost c1, olsr_linkcost c2);
 
-olsr_bool default_olsr_is_relevant_costchange(olsr_linkcost c1, olsr_linkcost c2);
+olsr_linkcost default_lq_packet_loss_worker_float(struct link_entry *link, void *lq, olsr_bool lost);
+void default_lq_memorize_foreign_hello_float(void *local, void *foreign);
 
-olsr_linkcost default_packet_loss_worker(void *lq, olsr_bool lost);
-void default_olsr_memorize_foreign_hello_lq(void *local, void *foreign);
+int default_lq_serialize_hello_lq_pair_float(unsigned char *buff, void *lq);
+void default_lq_deserialize_hello_lq_pair_float(const olsr_u8_t **curr, void *lq);
+int default_lq_serialize_tc_lq_pair_float(unsigned char *buff, void *lq);
+void default_lq_deserialize_tc_lq_pair_float(const olsr_u8_t **curr, void *lq);
 
-int default_olsr_serialize_hello_lq_pair(unsigned char *buff, void *lq);
-void default_olsr_deserialize_hello_lq_pair(const olsr_u8_t **curr, void *lq);
-int default_olsr_serialize_tc_lq_pair(unsigned char *buff, void *lq);
-void default_olsr_deserialize_tc_lq_pair(const olsr_u8_t **curr, void *lq);
+void default_lq_copy_link2tc_float(void *target, void *source);
+void default_lq_clear_float(void *target);
 
-void default_olsr_copy_link_lq_into_tc(void *target, void *source);
-void default_olsr_clear_lq(void *target);
+const char *default_lq_print_float(void *ptr, struct lqtextbuffer *buffer);
+const char *default_lq_print_cost_float(olsr_linkcost cost, struct lqtextbuffer *buffer);
 
-const char *default_olsr_print_lq(void *ptr, struct lqtextbuffer *buffer);
-const char *default_olsr_print_cost(olsr_linkcost cost, struct lqtextbuffer *buffer);
+extern struct lq_handler lq_etx_float_handler;
 
 #endif /*LQ_PLUGIN_DEFAULT_H_*/
similarity index 53%
rename from lib/lq_etx_fpm/src/lq_etx_fpm.c
rename to src/lq_plugin_default_fpm.c
index 48248a7..bb901a5 100644 (file)
 #include "tc_set.h"
 #include "link_set.h"
 #include "lq_plugin.h"
-#include "lq_route.h"
+#include "olsr_spf.h"
 #include "lq_packet.h"
 #include "packet.h"
 #include "olsr.h"
-#include "lq_etx_fpm.h"
+#include "lq_plugin_default_fpm.h"
 #include "fpm.h"
 
 /* etx lq plugin (fpm version) settings */
 struct lq_handler lq_etx_fpm_handler = {
-    &lq_etx_fpm_calc_cost,
-    &lq_etx_fpm_calc_cost,
+    &default_lq_initialize_fpm,
     
-    &lq_etx_fpm_olsr_is_relevant_costchange,
+    &default_lq_calc_cost_fpm,
+    &default_lq_calc_cost_fpm,
     
-    &lq_etx_fpm_packet_loss_worker,
-    &lq_etx_fpm_olsr_memorize_foreign_hello_lq,
-    &lq_etx_fpm_olsr_copy_link_lq_into_tc,
-    &lq_etx_fpm_olsr_clear_lq,
-    &lq_etx_fpm_olsr_clear_lq,
+    &default_lq_is_relevant_costchange_fpm,
     
-    &lq_etx_fpm_olsr_serialize_hello_lq_pair,
-    &lq_etx_fpm_olsr_serialize_tc_lq_pair,
-    &lq_etx_fpm_olsr_deserialize_hello_lq_pair,
-    &lq_etx_fpm_olsr_deserialize_tc_lq_pair,
+    &default_lq_packet_loss_worker_fpm,
+    &default_lq_memorize_foreign_hello_fpm,
+    &default_lq_copy_link2tc_fpm,
+    &default_lq_clear_fpm,
+    &default_lq_clear_fpm,
     
-    &lq_etx_fpm_olsr_print_lq,
-    &lq_etx_fpm_olsr_print_lq,
-    &lq_etx_fpm_olsr_print_cost, 
+    &default_lq_serialize_hello_lq_pair_fpm,
+    &default_lq_serialize_tc_lq_pair_fpm,
+    &default_lq_deserialize_hello_lq_pair_fpm,
+    &default_lq_deserialize_tc_lq_pair_fpm,
     
-    sizeof(struct lq_etx_fpm),
-    sizeof(struct lq_etx_fpm)
+    &default_lq_print_fpm,
+    &default_lq_print_fpm,
+    &default_lq_print_cost_fpm, 
+    
+    sizeof(struct default_lq_fpm),
+    sizeof(struct default_lq_fpm)
 };
 
-fpm MINIMAL_LQ;
-fpm aging_factor1, aging_factor2;
-
-void set_lq_etx_fpm_alpha(fpm alpha) {
-  OLSR_PRINTF(3, "lq_etx_fpm: Set alpha to %s\n", fpmtoa(alpha));
-  aging_factor1 = alpha;
-  aging_factor2 = fpmsub(itofpm(1), alpha);
-}
+fpm minimal_lq;
+fpm aging_factor_new, aging_factor_old;
+fpm aging_quickstart_new, aging_quickstart_old;
 
-int init_lq_etx_fpm(void) {
-  if (aging_factor1 == 0 && aging_factor2 == 0) {
-    OLSR_PRINTF(1, "Alpha factor for lq_etx_fgm not set !\n");
-    return 0; // error
-  }
+void default_lq_initialize_fpm(void) {
+  aging_factor_new = ftofpm(olsr_cnf->lq_aging);
+  aging_factor_old = fpmsub(itofpm(1), aging_factor_new);
   
-  MINIMAL_LQ = ftofpm(0.1);
+  aging_quickstart_new = ftofpm(LQ_QUICKSTART_AGING);
+  aging_quickstart_old = fpmsub(itofpm(1), aging_quickstart_new);
   
-  // activate plugin
-  set_lq_handler(&lq_etx_fpm_handler, LQ_ETX_FPM_HANDLER_NAME);
-  return 1;
+  minimal_lq = ftofpm(MINIMAL_USEFUL_LQ);
 }
 
-olsr_linkcost lq_etx_fpm_calc_cost(const void *ptr) {
-  const struct lq_etx_fpm *lq = ptr;
+olsr_linkcost default_lq_calc_cost_fpm(const void *ptr) {
+  const struct default_lq_fpm *lq = ptr;
   olsr_linkcost cost;
   
-  if (lq->lq < MINIMAL_LQ || lq->nlq < MINIMAL_LQ) {
+  if (lq->lq < minimal_lq || lq->nlq < minimal_lq) {
     return LINK_COST_BROKEN;
   }
   
@@ -113,8 +107,8 @@ olsr_linkcost lq_etx_fpm_calc_cost(const void *ptr) {
   return cost;
 }
 
-int lq_etx_fpm_olsr_serialize_hello_lq_pair(unsigned char *buff, void *ptr) {
-  struct lq_etx_fpm *lq = ptr;
+int default_lq_serialize_hello_lq_pair_fpm(unsigned char *buff, void *ptr) {
+  struct default_lq_fpm *lq = ptr;
   
   buff[0] = (unsigned char)fpmtoi(fpmmuli(lq->lq, 255));
   buff[1] = (unsigned char)fpmtoi(fpmmuli(lq->nlq, 255));
@@ -124,8 +118,8 @@ int lq_etx_fpm_olsr_serialize_hello_lq_pair(unsigned char *buff, void *ptr) {
   return 4;
 }
 
-void lq_etx_fpm_olsr_deserialize_hello_lq_pair(const olsr_u8_t **curr, void *ptr) {
-  struct lq_etx_fpm *lq = ptr;
+void default_lq_deserialize_hello_lq_pair_fpm(const olsr_u8_t **curr, void *ptr) {
+  struct default_lq_fpm *lq = ptr;
   olsr_u8_t valueLq, valueNlq;
   
   pkt_get_u8(curr, &valueLq);
@@ -136,15 +130,15 @@ void lq_etx_fpm_olsr_deserialize_hello_lq_pair(const olsr_u8_t **curr, void *ptr
   lq->nlq = fpmidiv(itofpm((int)valueNlq), 255);
 }
 
-olsr_bool lq_etx_fpm_olsr_is_relevant_costchange(olsr_linkcost c1, olsr_linkcost c2) {
+olsr_bool default_lq_is_relevant_costchange_fpm(olsr_linkcost c1, olsr_linkcost c2) {
   if (c1 > c2) {
-    return c2 - c1 > LQ_PLUGIN_RELEVANT_COSTCHANGE;
+    return c2 - c1 > LQ_PLUGIN_RELEVANT_COSTCHANGE_FPM;
   }
-  return c1 - c2 > LQ_PLUGIN_RELEVANT_COSTCHANGE;
+  return c1 - c2 > LQ_PLUGIN_RELEVANT_COSTCHANGE_FPM;
 }
 
-int lq_etx_fpm_olsr_serialize_tc_lq_pair(unsigned char *buff, void *ptr) {
-  struct lq_etx_fpm *lq = ptr;
+int default_lq_serialize_tc_lq_pair_fpm(unsigned char *buff, void *ptr) {
+  struct default_lq_fpm *lq = ptr;
   
   buff[0] = (unsigned char)fpmtoi(fpmmuli(lq->lq, 255));
   buff[1] = (unsigned char)fpmtoi(fpmmuli(lq->nlq, 255));
@@ -154,8 +148,8 @@ int lq_etx_fpm_olsr_serialize_tc_lq_pair(unsigned char *buff, void *ptr) {
   return 4;
 }
 
-void lq_etx_fpm_olsr_deserialize_tc_lq_pair(const olsr_u8_t **curr, void *ptr) {
-  struct lq_etx_fpm *lq = ptr;
+void default_lq_deserialize_tc_lq_pair_fpm(const olsr_u8_t **curr, void *ptr) {
+  struct default_lq_fpm *lq = ptr;
   olsr_u8_t valueLq, valueNlq;
   
   pkt_get_u8(curr, &valueLq);
@@ -166,20 +160,30 @@ void lq_etx_fpm_olsr_deserialize_tc_lq_pair(const olsr_u8_t **curr, void *ptr) {
   lq->nlq = fpmidiv(itofpm(valueNlq), 255);
 }
 
-olsr_linkcost lq_etx_fpm_packet_loss_worker(void *ptr, olsr_bool lost) {
-  struct lq_etx_fpm *tlq = ptr;
+olsr_linkcost default_lq_packet_loss_worker_fpm(struct link_entry *link, void *ptr, olsr_bool lost) {
+  struct default_lq_fpm *tlq = ptr;
+  fpm alpha_old = aging_factor_old;
+  fpm alpha_new = aging_factor_new;
+  
+  fpm link_loss_factor = fpmidiv(itofpm(link->loss_link_multiplier), 65536);
+  
+  if (tlq->quickstart < LQ_QUICKSTART_STEPS) {
+    alpha_new = aging_quickstart_new;
+    alpha_old = aging_quickstart_old;
+    tlq->quickstart++;
+  }
   
   // exponential moving average
-  tlq->lq = fpmmul(tlq->lq, aging_factor2);
+  tlq->lq = fpmmul(tlq->lq, alpha_old);
   if (lost == 0) {
-    tlq->lq = fpmadd(tlq->lq, aging_factor1);
+    tlq->lq = fpmadd(tlq->lq, fpmmul(alpha_new, link_loss_factor));
   }
-  return lq_etx_fpm_calc_cost(ptr);
+  return default_lq_calc_cost_fpm(ptr);
 }
 
-void lq_etx_fpm_olsr_memorize_foreign_hello_lq(void *ptrLocal, void *ptrForeign) {
-  struct lq_etx_fpm *local = ptrLocal;
-  struct lq_etx_fpm *foreign = ptrForeign;
+void default_lq_memorize_foreign_hello_fpm(void *ptrLocal, void *ptrForeign) {
+  struct default_lq_fpm *local = ptrLocal;
+  struct default_lq_fpm *foreign = ptrForeign;
   
   if (foreign) {
     local->nlq = foreign->lq;
@@ -189,22 +193,22 @@ void lq_etx_fpm_olsr_memorize_foreign_hello_lq(void *ptrLocal, void *ptrForeign)
   }
 }
 
-void lq_etx_fpm_olsr_copy_link_lq_into_tc(void *target, void *source) {
-  memcpy(target, source, sizeof(struct lq_etx_fpm));
+void default_lq_copy_link2tc_fpm(void *target, void *source) {
+  memcpy(target, source, sizeof(struct default_lq_fpm));
 }
 
-void lq_etx_fpm_olsr_clear_lq(void *target) {
-  memset(target, 0, sizeof(struct lq_etx_fpm));
+void default_lq_clear_fpm(void *target) {
+  memset(target, 0, sizeof(struct default_lq_fpm));
 }
 
-const char *lq_etx_fpm_olsr_print_lq(void *ptr, struct lqtextbuffer *buffer) {
-  struct lq_etx_fpm *lq = ptr;
+const char *default_lq_print_fpm(void *ptr, struct lqtextbuffer *buffer) {
+  struct default_lq_fpm *lq = ptr;
   
   sprintf(buffer->buf, "%s/%s", fpmtoa(lq->lq), fpmtoa(lq->nlq));
   return buffer->buf;
 }
 
-const char *lq_etx_fpm_olsr_print_cost(olsr_linkcost cost, struct lqtextbuffer *buffer) {
+const char *default_lq_print_cost_fpm(olsr_linkcost cost, struct lqtextbuffer *buffer) {
   sprintf(buffer->buf, "%s", fpmtoa(cost));
   return buffer->buf;
 }
similarity index 65%
rename from lib/lq_etx_fpm/src/lq_etx_fpm.h
rename to src/lq_plugin_default_fpm.h
index 97b049c..30ccebe 100644 (file)
 #include "lq_plugin.h"
 
 #define LQ_PLUGIN_LC_MULTIPLIER 1024
-#define LQ_PLUGIN_RELEVANT_COSTCHANGE 16
+#define LQ_PLUGIN_RELEVANT_COSTCHANGE_FPM 16
 
-#define LQ_ETX_FPM_HANDLER_NAME "ETX metric with FPM"
-struct lq_etx_fpm {
+#define LQ_ALGORITHM_ETX_FPM_NAME "etx_fpm"
+struct default_lq_fpm {
        fpm lq, nlq;
+       olsr_u16_t quickstart;
 };
 
-void set_lq_etx_fpm_alpha(fpm alpha);
-int init_lq_etx_fpm(void);
+void default_lq_initialize_fpm(void);
 
-olsr_linkcost lq_etx_fpm_calc_cost(const void *lq);
+olsr_linkcost default_lq_calc_cost_fpm(const void *lq);
 
-olsr_bool lq_etx_fpm_olsr_is_relevant_costchange(olsr_linkcost c1, olsr_linkcost c2);
+olsr_bool default_lq_is_relevant_costchange_fpm(olsr_linkcost c1, olsr_linkcost c2);
 
-olsr_linkcost lq_etx_fpm_packet_loss_worker(void *lq, olsr_bool lost);
-void lq_etx_fpm_olsr_memorize_foreign_hello_lq(void *local, void *foreign);
+olsr_linkcost default_lq_packet_loss_worker_fpm(struct link_entry *link, void *lq, olsr_bool lost);
+void default_lq_memorize_foreign_hello_fpm(void *local, void *foreign);
 
-int lq_etx_fpm_olsr_serialize_hello_lq_pair(unsigned char *buff, void *lq);
-void lq_etx_fpm_olsr_deserialize_hello_lq_pair(const olsr_u8_t **curr, void *lq);
-int lq_etx_fpm_olsr_serialize_tc_lq_pair(unsigned char *buff, void *lq);
-void lq_etx_fpm_olsr_deserialize_tc_lq_pair(const olsr_u8_t **curr, void *lq);
+int default_lq_serialize_hello_lq_pair_fpm(unsigned char *buff, void *lq);
+void default_lq_deserialize_hello_lq_pair_fpm(const olsr_u8_t **curr, void *lq);
+int default_lq_serialize_tc_lq_pair_fpm(unsigned char *buff, void *lq);
+void default_lq_deserialize_tc_lq_pair_fpm(const olsr_u8_t **curr, void *lq);
 
-void lq_etx_fpm_olsr_copy_link_lq_into_tc(void *target, void *source);
-void lq_etx_fpm_olsr_clear_lq(void *target);
+void default_lq_copy_link2tc_fpm(void *target, void *source);
+void default_lq_clear_fpm(void *target);
 
-const char *lq_etx_fpm_olsr_print_lq(void *ptr, struct lqtextbuffer *buffer);
-const char *lq_etx_fpm_olsr_print_cost(olsr_linkcost cost, struct lqtextbuffer *buffer);
+const char *default_lq_print_fpm(void *ptr, struct lqtextbuffer *buffer);
+const char *default_lq_print_cost_fpm(olsr_linkcost cost, struct lqtextbuffer *buffer);
+
+extern struct lq_handler lq_etx_fpm_handler;
 
 #endif /*LQ_ETX_FPM_*/
index cc3f56f..9c3776b 100644 (file)
@@ -404,7 +404,7 @@ main(int argc, char *argv[])
   signal(SIGQUIT, olsr_shutdown);
   signal(SIGILL,  olsr_shutdown);
   signal(SIGABRT, olsr_shutdown);
-  signal(SIGSEGV, olsr_shutdown);
+//  signal(SIGSEGV, olsr_shutdown);
   signal(SIGTERM, olsr_shutdown);
   signal(SIGPIPE, SIG_IGN);
 #endif
@@ -502,6 +502,9 @@ olsr_shutdown(int signal __attribute__((unused)))
   close(olsr_cnf->rts);
 #endif
 
+  /* Free cookies and memory pools attached. */
+  olsr_delete_all_cookies();
+
   olsr_syslog(OLSR_LOG_INFO, "%s stopped", olsrd_version);
 
   OLSR_PRINTF(1, "\n <<<< %s - terminating >>>>\n           http://www.olsr.org\n", olsrd_version);
@@ -525,7 +528,7 @@ print_usage(void)
           "  [-hint <hello interval (secs)>] [-tcint <tc interval (secs)>]\n"
           "  [-midint <mid interval (secs)>] [-hnaint <hna interval (secs)>]\n"
           "  [-T <Polling Rate (secs)>] [-nofork] [-hemu <ip_address>]\n"
-          "  [-lql <LQ level>] [-lqw <LQ winsize>]\n");
+          "  [-lql <LQ level>] [-lqa <LQ aging factor>]\n");
 }
 
 
@@ -643,21 +646,21 @@ olsr_process_arguments(int argc, char *argv[],
       /*
        * Set LQ winsize
        */
-      if (strcmp(*argv, "-lqw") == 0) 
+      if (strcmp(*argv, "-lqa") == 0) 
        {
-         int tmp_lq_wsize;
+         float tmp_lq_aging;
          NEXT_ARG;
           CHECK_ARGC;
          
-         sscanf(*argv, "%d", &tmp_lq_wsize);
+         sscanf(*argv, "%f", &tmp_lq_aging);
 
-         if(tmp_lq_wsize < MIN_LQ_WSIZE || tmp_lq_wsize > MAX_LQ_WSIZE)
+         if(tmp_lq_aging < MIN_LQ_AGING || tmp_lq_aging > MAX_LQ_AGING)
            {
-             printf("LQ winsize %d not allowed. Range [%d-%d]\n", 
-                    tmp_lq_wsize, MIN_LQ_WSIZE, MAX_LQ_WSIZE);
+             printf("LQ aging factor %f not allowed. Range [%f-%f]\n", 
+                    tmp_lq_aging, MIN_LQ_AGING, MAX_LQ_AGING);
              olsr_exit(__func__, EXIT_FAILURE);
            }
-         olsr_cnf->lq_wsize = tmp_lq_wsize;
+         olsr_cnf->lq_aging = tmp_lq_aging;
          continue;
        }
       
index f62c0ee..7b58fe9 100644 (file)
@@ -154,11 +154,9 @@ olsr_add_mpr_selector(const union olsr_ip_addr *addr, float vtime)
   OLSR_PRINTF(1, "MPRS: adding %s\n", olsr_ip_to_string(&buf, addr));
 
   new_entry = olsr_malloc(sizeof(struct mpr_selector), "Add MPR selector");
-
   /* Fill struct */
   new_entry->MS_main_addr = *addr;
   olsr_set_mpr_sel_timer(new_entry, vtime * MSEC_PER_SEC);
-
   /* Queue */
   QUEUE_ELEM(mprs_list, new_entry);
   /*
index 65ac6b3..aae15f7 100644 (file)
@@ -52,7 +52,7 @@
 #include "mid_set.h"
 #include "mpr.h"
 #include "lq_mpr.h"
-#include "lq_route.h"
+#include "olsr_spf.h"
 #include "scheduler.h"
 #include "apm.h"
 #include "misc.h"
@@ -61,6 +61,7 @@
 #include "lq_packet.h"
 #include "common/avl.h"
 #include "net_olsr.h"
+#include "lq_plugin.h"
 
 #include <stdarg.h>
 #include <signal.h>
@@ -218,7 +219,6 @@ void
 olsr_trigger_forced_update(void *unused __attribute__((unused))) {
 
   changes_force = OLSR_TRUE;
-
   changes_neighborhood = OLSR_TRUE;
   changes_topology = OLSR_TRUE;
   changes_hna = OLSR_TRUE;
@@ -240,13 +240,16 @@ olsr_init_tables(void)
 
   /* Set avl tree comparator */
   if (olsr_cnf->ipsize == 4) {
-    avl_comp_default = NULL;
+    avl_comp_default = avl_comp_ipv4;
     avl_comp_prefix_default = avl_comp_ipv4_prefix;
   } else {
     avl_comp_default = avl_comp_ipv6;
     avl_comp_prefix_default = avl_comp_ipv6_prefix;
   }
 
+  /* Initialize lq plugin set */
+  init_lq_handler_tree();
+  
   /* Initialize link set */
   olsr_init_link_set();
 
@@ -274,6 +277,11 @@ olsr_init_tables(void)
   /* Initialize HNA set */
   olsr_init_hna_set();  
 
+#if 0
+  /* Initialize Layer 1/2 database */
+  olsr_initialize_layer12();
+#endif
+  
   /* Start periodic SPF and RIB recalculation */
   if (olsr_cnf->lq_dinter > 0.0) {
     olsr_start_timer((unsigned int)(olsr_cnf->lq_dinter * MSEC_PER_SEC), 5,
index 54036b8..3166fbc 100644 (file)
@@ -67,7 +67,7 @@
 #define DEF_LQ_DIJK_LIMIT   255
 #define DEF_LQ_DIJK_INTER   0.0
 #define DEF_LQ_NAT_THRESH   1.0
-#define DEF_LQ_WSIZE        12
+#define DEF_LQ_AGING        0.1
 #define DEF_CLEAR_SCREEN    OLSR_FALSE
 
 /* Bounds */
@@ -92,8 +92,8 @@
 #define MIN_HYST_PARAM      0.0
 #define MAX_LQ_LEVEL        2
 #define MIN_LQ_LEVEL        0
-#define MAX_LQ_WSIZE        128
-#define MIN_LQ_WSIZE        3
+#define MAX_LQ_AGING        1.0
+#define MIN_LQ_AGING        0.01
 
 /* Option values */
 #define CFG_FIBM_FLAT          "flat"
@@ -220,7 +220,8 @@ struct olsrd_config
   olsr_u8_t                lq_level;
   olsr_u8_t                lq_fish;
   float                    lq_dinter;
-  olsr_u32_t               lq_wsize;
+  float                    lq_aging;
+  char                     *lq_algorithm;
   olsr_u8_t                lq_dlimit;
 
   /* Stuff set by olsrd */
index 48bf2d7..628f54f 100644 (file)
@@ -88,6 +88,11 @@ olsr_alloc_cookie(const char *cookie_name, olsr_cookie_type cookie_type)
     ci->ci_name = strdup(cookie_name);
   }
 
+  /* Init the free list */
+  if (cookie_type == OLSR_COOKIE_TYPE_MEMORY) {
+    list_head_init(&ci->ci_free_list);
+  }
+
   return ci;
 }
 
@@ -97,6 +102,7 @@ olsr_alloc_cookie(const char *cookie_name, olsr_cookie_type cookie_type)
 void
 olsr_free_cookie(struct olsr_cookie_info *ci)
 {
+  struct list_node *memory_list;
 
   /* Mark the cookie as unused */
   cookies[ci->ci_id] = NULL;
@@ -105,9 +111,38 @@ olsr_free_cookie(struct olsr_cookie_info *ci)
   if (ci->ci_name) {
     free(ci->ci_name);
   }
+
+  /* Flush all the memory on the free list */
+  if (ci->ci_type == OLSR_COOKIE_TYPE_MEMORY) {
+    while (!list_is_empty(&ci->ci_free_list)) {
+      memory_list = ci->ci_free_list.next;
+      list_remove(memory_list);
+      free(memory_list);
+    }
+  }
+
   free(ci);
 }
 
+/*
+ * Flush all cookies. This is really only called upon shutdown.
+ */
+void
+olsr_delete_all_cookies(void)
+{
+  int ci_index;
+
+  /*
+   * Walk the full index range and kill 'em all.
+   */
+  for (ci_index = 1; ci_index < COOKIE_ID_MAX; ci_index++) {
+    if (!cookies[ci_index]) {
+      continue;
+    }
+    olsr_free_cookie(cookies[ci_index]);
+  }
+}
+
 /*
  * Set the size for fixed block allocations.
  * This is only allowed for memory cookies.
@@ -183,18 +218,37 @@ olsr_cookie_malloc(struct olsr_cookie_info *ci)
 {
   void *ptr;
   struct olsr_cookie_mem_brand *branding;
+  struct list_node *free_list_node;
+  olsr_bool reuse = OLSR_FALSE;
 
   /*
-   * Not all the callers do a proper cleaning of memory.
-   * Clean it on behalf of those.
+   * Check first if we have reusable memory.
    */
-  ptr = calloc(1, ci->ci_size + sizeof(struct olsr_cookie_mem_brand));
-
-  if (!ptr) {
-    const char *const err_msg = strerror(errno);
-    OLSR_PRINTF(1, "OUT OF MEMORY: %s\n", err_msg);
-    olsr_syslog(OLSR_LOG_ERR, "olsrd: out of memory!: %s\n", err_msg);
-    olsr_exit(ci->ci_name, EXIT_FAILURE);
+  if (!ci->ci_free_list_usage) {
+
+    /*
+     * No reusable memory block on the free_list.
+     */
+    ptr = calloc(1, ci->ci_size + sizeof(struct olsr_cookie_mem_brand));
+
+    if (!ptr) {
+      const char *const err_msg = strerror(errno);
+      OLSR_PRINTF(1, "OUT OF MEMORY: %s\n", err_msg);
+      olsr_syslog(OLSR_LOG_ERR, "olsrd: out of memory!: %s\n", err_msg);
+      olsr_exit(ci->ci_name, EXIT_FAILURE);
+    }
+  } else {
+
+    /*
+     * There is a memory block on the free list.
+     * Carve it out of the list, and clean.
+     */
+    free_list_node = ci->ci_free_list.next;
+    list_remove(free_list_node);
+    ptr = (void *)free_list_node;
+    memset(ptr, 0, ci->ci_size);
+    ci->ci_free_list_usage--;
+    reuse = OLSR_TRUE;
   }
 
   /*
@@ -211,8 +265,8 @@ olsr_cookie_malloc(struct olsr_cookie_info *ci)
   olsr_cookie_usage_incr(ci->ci_id);
 
 #if 0
-  OLSR_PRINTF(1, "MEMORY: alloc %s, %p, %u bytes\n",
-             ci->ci_name, ptr, ci->ci_size);
+  OLSR_PRINTF(1, "MEMORY: alloc %s, %p, %u bytes%s\n",
+             ci->ci_name, ptr, ci->ci_size, reuse ? ", reuse" : "");
 #endif
 
   return ptr;
@@ -226,6 +280,8 @@ void
 olsr_cookie_free(struct olsr_cookie_info *ci, void *ptr)
 {
   struct olsr_cookie_mem_brand *branding;
+  struct list_node *free_list_node;
+  olsr_bool reuse = OLSR_FALSE;
 
   branding = (struct olsr_cookie_mem_brand *)
     ((unsigned char *)ptr + ci->ci_size);
@@ -240,15 +296,36 @@ olsr_cookie_free(struct olsr_cookie_info *ci, void *ptr)
   /* Kill the brand */
   memset(branding, 0, sizeof(*branding));
 
+  /*
+   * Rather than freeing the memory right away, try to reuse at a later
+   * point. Keep at least ten percent of the active used blocks or at least
+   * ten blocks on the free list.
+   */
+  if ((ci->ci_free_list_usage < COOKIE_FREE_LIST_THRESHOLD) ||
+      (ci->ci_free_list_usage < ci->ci_usage / COOKIE_FREE_LIST_THRESHOLD)) {
+
+    free_list_node = (struct list_node *)ptr;
+    list_node_init(free_list_node);
+    list_add_before(&ci->ci_free_list, free_list_node);
+    ci->ci_free_list_usage++;
+    reuse = OLSR_TRUE;
+
+  } else {
+
+    /*
+     * No interest in reusing memory.
+     */
+    free(ptr);
+  }
+
   /* Stats keeping */
   olsr_cookie_usage_decr(ci->ci_id);
 
 #if 0
-  OLSR_PRINTF(1, "MEMORY: free %s, %p, %u bytes\n",
-             ci->ci_name, ptr, ci->ci_size);
+  OLSR_PRINTF(1, "MEMORY: free %s, %p, %u bytes%s\n",
+             ci->ci_name, ptr, ci->ci_size, reuse ? ", reuse" : "");
 #endif
 
-  free(ptr);
 }
 
 /*
index 06014fc..24a38d1 100644 (file)
@@ -39,6 +39,7 @@
  */
 
 #include "olsr_types.h"
+#include "common/list.h"
 
 #ifndef _OLSR_COOKIE_H
 #define _OLSR_COOKIE_H
@@ -63,9 +64,13 @@ struct olsr_cookie_info {
   olsr_cookie_type ci_type;           /* Type of cookie */
   size_t ci_size;                     /* Fixed size for block allocations */
   unsigned int ci_usage;              /* Stats, resource usage */
-  unsigned int ci_changes;             /* Stats, resource churn */
+  unsigned int ci_changes;            /* Stats, resource churn */
+  struct list_node ci_free_list;       /* List head for recyclable blocks */
+  unsigned int ci_free_list_usage;     /* Length of free list */
 };
 
+#define COOKIE_FREE_LIST_THRESHOLD 10  /* Blocks / Percent  */
+
 /*
  * Small brand which gets appended on the end of every block allocation.
  * Helps to detect memory corruption, like overruns, double frees.
@@ -79,6 +84,7 @@ struct olsr_cookie_mem_brand {
 extern struct olsr_cookie_info *olsr_alloc_cookie(const char *,
                                                  olsr_cookie_type);
 extern void olsr_free_cookie(struct olsr_cookie_info *);
+extern void olsr_delete_all_cookies(void);
 extern char *olsr_cookie_name(olsr_cookie_t);
 extern void olsr_cookie_set_memory_size(struct olsr_cookie_info *, size_t);
 extern void olsr_cookie_usage_incr(olsr_cookie_t);
similarity index 99%
rename from src/lq_route.c
rename to src/olsr_spf.c
index fd4c487..1418ea4 100644 (file)
@@ -62,7 +62,7 @@
 #include "hna_set.h"
 #include "common/list.h"
 #include "common/avl.h"
-#include "lq_route.h"
+ #include "olsr_spf.h"
 #include "net_olsr.h"
 #include "lq_plugin.h"
 
similarity index 97%
rename from src/lq_route.h
rename to src/olsr_spf.h
index 1ce225b..a496ac6 100644 (file)
@@ -38,8 +38,8 @@
  *
  */
 
-#ifndef _LQ_ROUTE_H
-#define _LQ_ROUTE_H
+#ifndef _OLSR_SPF_H
+#define _OLSR_SPF_H
 
 void olsr_calculate_routing_table(void);
 
index ff9f7d8..24bb1cb 100644 (file)
@@ -220,7 +220,7 @@ olsr_build_hello_packet(struct hello_message *message, struct interface *outif)
       continue;
     }
            
-    message_neighbor = olsr_malloc_hello_neighbor("Build HELLO 2");
+         message_neighbor = olsr_malloc_hello_neighbor("Build HELLO 2");
            
     message_neighbor->link = UNSPEC_LINK;
            
@@ -340,9 +340,9 @@ olsr_build_tc_packet(struct tc_message *message)
     switch (olsr_cnf->tc_redundancy) {
     case(2):
     {
-      /* 2 = Add all neighbors */
-      //printf("\t%s\n", olsr_ip_to_string(&mprs->mpr_selector_addr));
-      message_mpr = olsr_malloc_tc_mpr_addr("Build TC");
+               /* 2 = Add all neighbors */
+               //printf("\t%s\n", olsr_ip_to_string(&mprs->mpr_selector_addr));
+                 message_mpr = olsr_malloc_tc_mpr_addr("Build TC");
                
       message_mpr->address = entry->neighbor_main_addr;
       message_mpr->next = message->multipoint_relay_selector_address;
index e5af19e..4983a7a 100644 (file)
@@ -50,6 +50,7 @@
 #include "common/avl.h"
 #include "net_olsr.h"
 #include "tc_set.h"
+#include "olsr_cookie.h"
 
 #ifdef WIN32
 #undef strerror
@@ -108,13 +109,12 @@ olsr_init_export_route(void)
 }
 
 /**
- *Deletes all OLSR routes
+ * Delete all OLSR routes.
  *
  * This is extremely simple - Just increment the version of the
  * tree and then olsr_update_rib_routes() will see all routes in the tree
  * as outdated and olsr_update_kernel_routes() will finally flush it.
  *
- *@return 1
  */
 void
 olsr_delete_all_kernel_routes(void)
@@ -281,7 +281,7 @@ olsr_del_kernel_routes(struct list_node *head_node)
     olsr_delete_kernel_route(rt);
 
     list_remove(&rt->rt_change_node);
-    free(rt);
+    olsr_cookie_free(rt_mem_cookie, rt);
   }
 }
 
index 589be22..a111216 100644 (file)
 #include "olsr.h"
 #include "link_set.h"
 #include "common/avl.h"
-#include "lq_route.h"
+#include "olsr_spf.h"
 #include "net_olsr.h"
 
 #include <assert.h>
 
+/* Cookies */
+struct olsr_cookie_info *rt_mem_cookie = NULL;
+struct olsr_cookie_info *rtp_mem_cookie = NULL;
+
 /*
  * Sven-Ola: if the current internet gateway is switched, the
  * NAT connection info is lost for any active TCP/UDP session.
@@ -162,9 +166,20 @@ avl_comp_ipv6_prefix (const void *prefix1, const void *prefix2)
 void
 olsr_init_routing_table(void)
 {
+  OLSR_PRINTF(5, "RIB: init routing tree\n");
+
   /* the routing tree */
   avl_init(&routingtree, avl_comp_prefix_default);
   routingtree_version = 0;
+
+  /*
+   * Get some cookies for memory stats and memory recycling.
+   */
+  rt_mem_cookie = olsr_alloc_cookie("rt_entry", OLSR_COOKIE_TYPE_MEMORY);
+  olsr_cookie_set_memory_size(rt_mem_cookie, sizeof(struct rt_entry));
+
+  rtp_mem_cookie = olsr_alloc_cookie("rt_path", OLSR_COOKIE_TYPE_MEMORY);
+  olsr_cookie_set_memory_size(rtp_mem_cookie, sizeof(struct rt_path));
 }
 
 /**
@@ -216,7 +231,7 @@ olsr_update_rt_path(struct rt_path *rtp, struct tc_entry *tc,
 static struct rt_entry *
 olsr_alloc_rt_entry(struct olsr_ip_prefix *prefix)
 {
-  struct rt_entry *rt = olsr_malloc(sizeof(struct rt_entry), __FUNCTION__);
+  struct rt_entry *rt = olsr_cookie_malloc(rt_mem_cookie);
   if (!rt) {
     return NULL;
   }
@@ -245,7 +260,7 @@ static struct rt_path *
 olsr_alloc_rt_path(struct tc_entry *tc,
                    struct olsr_ip_prefix *prefix, olsr_u8_t origin)
 {
-  struct rt_path *rtp = olsr_malloc(sizeof(struct rt_path), __FUNCTION__);
+  struct rt_path *rtp = olsr_cookie_malloc(rtp_mem_cookie);
 
   if (!rtp) {
     return NULL;
@@ -356,7 +371,7 @@ olsr_delete_rt_path(struct rt_path *rtp)
     current_inetgw = NULL;
   }
 
-  free(rtp);
+  olsr_cookie_free(rtp_mem_cookie, rtp);
 }
 
 
index 8440149..01d532e 100644 (file)
@@ -49,6 +49,7 @@
 #include <net/route.h>
 #include "hna_set.h"
 #include "link_set.h"
+#include "olsr_cookie.h"
 #include "common/avl.h"
 #include "common/list.h"
 
@@ -202,6 +203,7 @@ union olsr_kernel_route
 
 extern struct avl_tree routingtree;
 extern unsigned int routingtree_version;
+extern struct olsr_cookie_info *rt_mem_cookie;
 
 void
 olsr_init_routing_table(void);
index e0a070d..5d83bfd 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
  * The olsr.org Optimized Link-State Routing daemon(olsrd)
  * Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
@@ -39,7 +40,6 @@
  *
  */
 
-
 #include "defs.h"
 #include "scheduler.h"
 #include "log.h"
 #include "build_msg.h"
 #include "net_olsr.h"
 #include "socket_parser.h"
-#include "lq_route.h"
+#include "olsr_spf.h"
 #include "link_set.h"
 #include "olsr_cookie.h"
 
 /* Timer data, global. Externed in defs.h */
-clock_t now_times;  /* current idea of times(2) reported uptime */
+clock_t now_times;                    /* current idea of times(2) reported uptime */
 
 /* Hashed root of all timers */
 struct list_node timer_wheel[TIMER_WHEEL_SLOTS];
-clock_t timer_last_run; /* remember the last timeslot walk */
-struct list_node *timer_walk_list_node = NULL; /* used for timeslot walk */
+clock_t timer_last_run;                       /* remember the last timeslot walk */
+struct list_node *timer_walk_list_node = NULL; /* used for timeslot walk */
 
 /* Pool of timers to avoid malloc() churn */
 struct list_node free_timer_list;
@@ -98,10 +98,10 @@ olsr_scheduler_sleep(clock_t scheduler_runtime)
 
   if (timercmp(&time_used, &next_interval, <)) {
     timersub(&next_interval, &time_used, &sleeptime_val);
-         
+
     sleeptime_spec.tv_sec = sleeptime_val.tv_sec;
     sleeptime_spec.tv_nsec = sleeptime_val.tv_usec * NSEC_PER_USEC;
-         
+
     while (nanosleep(&sleeptime_spec, &remainder_spec) < 0)
       sleeptime_spec = remainder_spec;
   }
@@ -119,15 +119,16 @@ olsr_scheduler_sleep(clock_t scheduler_runtime)
 void
 olsr_scheduler(void)
 {
-  struct tms tms_buf;   /* Buffer for times(2) calls. */
+  struct tms tms_buf;                 /* Buffer for times(2) calls. */
   struct interface *ifn;
 
-  OLSR_PRINTF(1, "Scheduler started - polling every %0.2f seconds\n", olsr_cnf->pollrate);
+  OLSR_PRINTF(1, "Scheduler started - polling every %0.2f seconds\n",
+             olsr_cnf->pollrate);
   OLSR_PRINTF(3, "Max jitter is %f\n\n", olsr_cnf->max_jitter);
 
   /* Main scheduler loop */
   for (;;) {
+
     /*
      * Update the global timestamp. We are using a non-wallclock timer here
      * to avoid any undesired side effects if the system clock changes.
@@ -137,10 +138,10 @@ olsr_scheduler(void)
     /* Read incoming data */
     olsr_poll_sockets();
 
-    /* Process timers (before packet generation) */      
+    /* Process timers (before packet generation) */
     olsr_walk_timers(&timer_last_run);
 
-    /* Update */      
+    /* Update */
     olsr_process_changes();
 
     /* Check for changes in topology */
@@ -151,9 +152,9 @@ olsr_scheduler(void)
     }
 
     /* looping trough interfaces and emmitting pending data */
-    for (ifn = ifnet; ifn ; ifn = ifn->int_next) { 
+    for (ifn = ifnet; ifn; ifn = ifn->int_next) {
       if (net_output_pending(ifn) && TIMED_OUT(ifn->fwdtimer)) {
-        net_output(ifn);
+       net_output(ifn);
       }
     }
 
@@ -165,7 +166,7 @@ olsr_scheduler(void)
     if (olsr_win32_end_request) {
       break;
     }
-#endif      
+#endif
   }
 
 #if defined WIN32
@@ -177,7 +178,7 @@ olsr_scheduler(void)
    * and hence also kill us.
    */
   while (1) {
-    Sleep(1000); /* milliseconds */
+    Sleep(1000);               /* milliseconds */
   }
 #endif
 }
@@ -191,7 +192,7 @@ olsr_scheduler(void)
  * @param cached result of random() at system init.
  * @return the absolute timer in system clock tick units
  */
-static clock_t 
+static clock_t
 olsr_jitter(unsigned int rel_time, olsr_u8_t jitter_pct, unsigned int random)
 {
   unsigned int jitter_time;
@@ -212,7 +213,7 @@ olsr_jitter(unsigned int rel_time, olsr_u8_t jitter_pct, unsigned int random)
 
 #if 0
   OLSR_PRINTF(3, "TIMER: jitter %u%% rel_time %ums to %ums\n",
-              jitter_pct, rel_time, rel_time - jitter_time);
+             jitter_pct, rel_time, rel_time - jitter_time);
 #endif
 
   return GET_TIMESTAMP(rel_time - jitter_time);
@@ -239,7 +240,7 @@ olsr_get_timer(void)
    */
   if (!list_is_empty(&free_timer_list)) {
     timer_list_node = free_timer_list.next;
-    
+
     /* carve it out of the pool, do not memset overwrite timer->timer_random */
     list_remove(timer_list_node);
     timer = list2timer(timer_list_node);
@@ -250,14 +251,14 @@ olsr_get_timer(void)
   /*
    * Nothing in the pool, allocate a new chunk.
    */
-  timer_block = olsr_malloc(sizeof(struct timer_entry) * OLSR_TIMER_MEMORY_CHUNK,
-                            "timer chunk");
-  memset(timer_block, 0, sizeof(struct timer_entry) * OLSR_TIMER_MEMORY_CHUNK); 
+  timer_block =
+    olsr_malloc(sizeof(struct timer_entry) * OLSR_TIMER_MEMORY_CHUNK,
+               "timer chunk");
 
 #if 0
   OLSR_PRINTF(3, "TIMER: alloc %u bytes chunk at %p\n",
-              sizeof(struct timer_entry) * OLSR_TIMER_MEMORY_CHUNK,
-              timer_block);
+             sizeof(struct timer_entry) * OLSR_TIMER_MEMORY_CHUNK,
+             timer_block);
 #endif
 
   /*
@@ -298,7 +299,7 @@ olsr_init_timers(void)
 
   OLSR_PRINTF(5, "TIMER: init timers\n");
 
-  memset(timer_wheel, 0 , sizeof(timer_wheel));
+  memset(timer_wheel, 0, sizeof(timer_wheel));
 
   timer_head_node = timer_wheel;
   for (index = 0; index < TIMER_WHEEL_SLOTS; index++) {
@@ -322,7 +323,7 @@ olsr_init_timers(void)
  * Callback the provided function with the context pointer.
  */
 void
-olsr_walk_timers(clock_t *last_run)
+olsr_walk_timers(clock_t * last_run)
 {
   static struct timer_entry *timer;
   struct list_node *timer_head_node;
@@ -348,9 +349,8 @@ olsr_walk_timers(clock_t *last_run)
     timer_head_node = &timer_wheel[*last_run & TIMER_WHEEL_MASK];
 
     /* Walk all entries hanging off this hash bucket */
-    for (timer_walk_list_node = timer_head_node->next;
-         timer_walk_list_node != timer_head_node; /* circular list */
-         timer_walk_list_node = timer_walk_list_node->next) {
+    for (timer_walk_list_node = timer_head_node->next; timer_walk_list_node != timer_head_node;        /* circular list */
+        timer_walk_list_node = timer_walk_list_node->next) {
 
       timer = list2timer(timer_walk_list_node);
 
@@ -359,44 +359,42 @@ olsr_walk_timers(clock_t *last_run)
       /* Ready to fire ? */
       if (TIMED_OUT(timer->timer_clock)) {
 
-        OLSR_PRINTF(3, "TIMER: fire %s timer %p, ctx %p, "
-                    "at clocktick %u\n",
-                    olsr_cookie_name(timer->timer_cookie),
-                    timer, timer->timer_cb_context,
-                    (unsigned int)(*last_run));
+       OLSR_PRINTF(3, "TIMER: fire %s timer %p, ctx %p, "
+                   "at clocktick %u\n",
+                   olsr_cookie_name(timer->timer_cookie),
+                   timer, timer->timer_cb_context, (unsigned int)(*last_run));
 
-        /* This timer is expired, call into the provided callback function */
-        timer->timer_cb(timer->timer_cb_context);
+       /* This timer is expired, call into the provided callback function */
+       timer->timer_cb(timer->timer_cb_context);
 
-        if (timer->timer_period) {
+       if (timer->timer_period) {
 
-          /*
-           * Don't restart the periodic timer if the callback function has
-           * stopped the timer.
-           */
-          if (timer->timer_flags & OLSR_TIMER_RUNNING) {
+         /*
+          * Don't restart the periodic timer if the callback function has
+          * stopped the timer.
+          */
+         if (timer->timer_flags & OLSR_TIMER_RUNNING) {
 
-            /* For periodical timers, rehash the random number and restart */
-            timer->timer_random = random();
-            olsr_change_timer(timer, timer->timer_period,
-                              timer->timer_jitter_pct,
-                              OLSR_TIMER_PERIODIC);
-          }
+           /* For periodical timers, rehash the random number and restart */
+           timer->timer_random = random();
+           olsr_change_timer(timer, timer->timer_period,
+                             timer->timer_jitter_pct, OLSR_TIMER_PERIODIC);
+         }
 
-        } else {
+       } else {
 
-          /*
-           * Don't stop the singleshot timer if the callback function has
-           * stopped the timer.
-           */
-          if (timer->timer_flags & OLSR_TIMER_RUNNING) {
+         /*
+          * Don't stop the singleshot timer if the callback function has
+          * stopped the timer.
+          */
+         if (timer->timer_flags & OLSR_TIMER_RUNNING) {
 
-            /* Singleshot timers are stopped and returned to the pool */
-            olsr_stop_timer(timer);
-          }
-        }
+           /* Singleshot timers are stopped and returned to the pool */
+           olsr_stop_timer(timer);
+         }
+       }
 
-        timers_fired++;
+       timers_fired++;
       }
     }
 
@@ -412,9 +410,9 @@ olsr_walk_timers(clock_t *last_run)
 
 #ifdef DEBUG
   OLSR_PRINTF(3, "TIMER: processed %4u/%u clockwheel slots, "
-              "timers walked %4u/%u, timers fired %u\n",
-              wheel_slot_walks, TIMER_WHEEL_SLOTS,
-              total_timers_walked, timers_running, total_timers_fired);
+             "timers walked %4u/%u, timers fired %u\n",
+             wheel_slot_walks, TIMER_WHEEL_SLOTS,
+             total_timers_walked, timers_running, total_timers_fired);
 #endif
 
   /*
@@ -475,7 +473,7 @@ olsr_get_timezone(void)
  *
  * @return buffer to a formatted system time string.
  */
-const char*
+const char *
 olsr_wallclock_string(void)
 {
   static char buf[4][sizeof("00:00:00.000000")];
@@ -485,7 +483,7 @@ olsr_wallclock_string(void)
   int sec, usec;
 
   ret = buf[idx];
-  idx = (idx+1) & 3;
+  idx = (idx + 1) & 3;
 
   gettimeofday(&now, NULL);
 
@@ -493,7 +491,7 @@ olsr_wallclock_string(void)
   usec = (int)now.tv_usec;
 
   snprintf(ret, sizeof(buf), "%02u:%02u:%02u.%06u",
-           (sec % 86400) / 3600, (sec % 3600) / 60, sec % 60, usec);
+          (sec % 86400) / 3600, (sec % 3600) / 60, sec % 60, usec);
 
   return ret;
 }
@@ -507,7 +505,7 @@ olsr_wallclock_string(void)
  * @param absolute time expressed in clockticks
  * @return buffer to a formatted system time string.
  */
-const char*
+const char *
 olsr_clock_string(clock_t clock)
 {
   static char buf[4][sizeof("00:00:00.000")];
@@ -516,14 +514,14 @@ olsr_clock_string(clock_t clock)
   unsigned int sec, msec;
 
   ret = buf[idx];
-  idx = (idx+1) & 3;
+  idx = (idx + 1) & 3;
 
   /* On most systems a clocktick is a 10ms quantity. */
   msec = olsr_cnf->system_tick_divider * (unsigned int)(clock - now_times);
   sec = msec / MSEC_PER_SEC;
 
-  snprintf(ret, sizeof(buf)/4, "%02u:%02u:%02u.%03u",
-           sec / 3600, (sec % 3600) / 60, (sec % 60), (msec % MSEC_PER_SEC));
+  snprintf(ret, sizeof(buf) / 4, "%02u:%02u:%02u.%03u",
+          sec / 3600, (sec % 3600) / 60, (sec % 60), (msec % MSEC_PER_SEC));
 
   return ret;
 }
@@ -540,8 +538,8 @@ olsr_clock_string(clock_t clock)
  */
 struct timer_entry *
 olsr_start_timer(unsigned int rel_time, olsr_u8_t jitter_pct,
-                 olsr_bool periodical, void (*timer_cb_function)(void *),
-                 void *context, olsr_cookie_t cookie)
+                olsr_bool periodical, void (*timer_cb_function) (void *),
+                void *context, olsr_cookie_t cookie)
 {
   struct timer_entry *timer;
 
@@ -569,13 +567,13 @@ olsr_start_timer(unsigned int rel_time, olsr_u8_t jitter_pct,
    * Now insert in the respective timer_wheel slot.
    */
   list_add_before(&timer_wheel[timer->timer_clock & TIMER_WHEEL_MASK],
-                  &timer->timer_list);
+                 &timer->timer_list);
   timers_running++;
 
 #ifdef DEBUG
   OLSR_PRINTF(3, "TIMER: start %s timer %p firing in %s, ctx %p\n",
-              olsr_cookie_name(timer->timer_cookie),
-              timer, olsr_clock_string(timer->timer_clock), context);
+             olsr_cookie_name(timer->timer_cookie),
+             timer, olsr_clock_string(timer->timer_clock), context);
 #endif
 
   return timer;
@@ -610,12 +608,11 @@ olsr_stop_timer(struct timer_entry *timer)
   if (!timer) {
     return;
   }
-
 #ifdef DEBUG
   OLSR_PRINTF(3, "TIMER: stop %s timer %p firing in %s, ctx %p\n",
-              olsr_cookie_name(timer->timer_cookie),
-              timer, olsr_clock_string(timer->timer_clock),
-              timer->timer_cb_context);
+             olsr_cookie_name(timer->timer_cookie),
+             timer, olsr_clock_string(timer->timer_clock),
+             timer->timer_cb_context);
 #endif
 
   olsr_update_timer_walk_ctx(timer);
@@ -642,7 +639,7 @@ olsr_stop_timer(struct timer_entry *timer)
  */
 void
 olsr_change_timer(struct timer_entry *timer, unsigned int rel_time,
-                  olsr_u8_t jitter_pct, olsr_bool periodical)
+                 olsr_u8_t jitter_pct, olsr_bool periodical)
 {
 
   /* Sanity check. */
@@ -668,13 +665,12 @@ olsr_change_timer(struct timer_entry *timer, unsigned int rel_time,
    */
   list_remove(&timer->timer_list);
   list_add_before(&timer_wheel[timer->timer_clock & TIMER_WHEEL_MASK],
-                  &timer->timer_list);
+                 &timer->timer_list);
 
 #ifdef DEBUG
   OLSR_PRINTF(3, "TIMER: change %s timer %p, firing to %s, ctx %p\n",
-              olsr_cookie_name(timer->timer_cookie), timer,
-              olsr_clock_string(timer->timer_clock),
-              timer->timer_cb_context);
+             olsr_cookie_name(timer->timer_cookie), timer,
+             olsr_clock_string(timer->timer_clock), timer->timer_cb_context);
 #endif
 }
 
@@ -687,26 +683,26 @@ olsr_change_timer(struct timer_entry *timer, unsigned int rel_time,
  */
 void
 olsr_set_timer(struct timer_entry **timer_ptr, unsigned int rel_time,
-               olsr_u8_t jitter_pct, olsr_bool periodical,
-               void (*timer_cb_function)(void *), void *context,
-               olsr_cookie_t cookie)
+              olsr_u8_t jitter_pct, olsr_bool periodical,
+              void (*timer_cb_function) (void *), void *context,
+              olsr_cookie_t cookie)
 {
 
   if (!*timer_ptr) {
 
     /* No timer running, kick it. */
     *timer_ptr = olsr_start_timer(rel_time, jitter_pct, periodical,
-                                  timer_cb_function, context, cookie);
+                                 timer_cb_function, context, cookie);
   } else {
 
     if (!rel_time) {
 
-      /* No good future time provided, kill it.*/
+      /* No good future time provided, kill it. */
       olsr_stop_timer(*timer_ptr);
       *timer_ptr = NULL;
     } else {
 
-      /* Time is ok and timer is running, change it !*/
+      /* Time is ok and timer is running, change it ! */
       olsr_change_timer(*timer_ptr, rel_time, jitter_pct, periodical);
     }
   }
index 0168f28..6a73d30 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
  * The olsr.org Optimized Link-State Routing daemon(olsrd)
  * Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
  * For a periodic timer the timer_period field is set to non zero,
  * which causes the timer to run forever until manually stopped.
  */
-struct timer_entry
-{
-  struct list_node timer_list; /* memory pooling, or wheel membership */
-  clock_t timer_clock; /* when timer shall fire (absolute time)*/
-  unsigned int timer_period; /* set for periodical timers (relative time) */
-  olsr_cookie_t timer_cookie; /* used for diag stuff */
-  olsr_u8_t timer_jitter_pct; /* the jitter expressed in percent */
-  olsr_u8_t timer_flags; /* misc flags */
-  unsigned int timer_random; /* cache random() result for performance reasons */
-  void (*timer_cb)(void *); /* callback function */
-  void *timer_cb_context; /* context pointer */
+struct timer_entry {
+  struct list_node timer_list;        /* memory pooling, or wheel membership */
+  clock_t timer_clock;                /* when timer shall fire (absolute time) */
+  unsigned int timer_period;          /* set for periodical timers (relative time) */
+  olsr_cookie_t timer_cookie;         /* used for diag stuff */
+  olsr_u8_t timer_jitter_pct;         /* the jitter expressed in percent */
+  olsr_u8_t timer_flags;              /* misc flags */
+  unsigned int timer_random;          /* cache random() result for performance reasons */
+  void (*timer_cb) (void *);          /* callback function */
+  void *timer_cb_context;             /* context pointer */
 };
 
 /* inline to recast from timer_list back to timer_entry */
 LISTNODE2STRUCT(list2timer, struct timer_entry, timer_list);
 
-#define OLSR_TIMER_ONESHOT    0 /* One shot timer */
-#define OLSR_TIMER_PERIODIC   1 /* Periodic timer */
+#define OLSR_TIMER_ONESHOT    0        /* One shot timer */
+#define OLSR_TIMER_PERIODIC   1        /* Periodic timer */
 
 /* Timer flags */
-#define OLSR_TIMER_RUNNING  ( 1 << 0) /* this timer is running */
+#define OLSR_TIMER_RUNNING  ( 1 << 0)  /* this timer is running */
 
 /* Memory pooling */
-#define OLSR_TIMER_MEMORY_CHUNK 100 /* timers per chunk */
+#define OLSR_TIMER_MEMORY_CHUNK 100    /* timers per chunk */
 
 /* Timers */
 void olsr_init_timers(void);
 void olsr_walk_timers(clock_t *);
 void olsr_set_timer(struct timer_entry **, unsigned int, olsr_u8_t, olsr_bool,
-                    void (*)(void *), void *, olsr_cookie_t);
+                   void (*)(void *), void *, olsr_cookie_t);
 struct timer_entry *olsr_start_timer(unsigned int, olsr_u8_t, olsr_bool,
-                                     void (*)(void *), void *, olsr_cookie_t);
-void olsr_change_timer(struct timer_entry *, unsigned int, olsr_u8_t, olsr_bool);
+                                    void (*)(void *), void *, olsr_cookie_t);
+void olsr_change_timer(struct timer_entry *, unsigned int, olsr_u8_t,
+                      olsr_bool);
 void olsr_stop_timer(struct timer_entry *);
 
 /* Printing timestamps */
-const charolsr_clock_string(clock_t);
-const charolsr_wallclock_string(void);
+const char *olsr_clock_string(clock_t);
+const char *olsr_wallclock_string(void);
 
 /* Main scheduler loop */
-void olsr_scheduler(void) __attribute__((noreturn));
+void olsr_scheduler(void) __attribute__ ((noreturn));
 
 #endif
 
index a745db9..841e0ab 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
  * The olsr.org Optimized Link-State Routing daemon(olsrd)
  * Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
@@ -45,7 +46,7 @@
 #include "link_set.h"
 #include "olsr.h"
 #include "scheduler.h"
-#include "lq_route.h"
+#include "olsr_spf.h"
 #include "common/avl.h"
 #include "lq_packet.h"
 #include "net_olsr.h"
@@ -56,7 +57,7 @@
 
 /* Root of the link state database */
 struct avl_tree tc_tree;
-struct tc_entry *tc_myself; /* Shortcut to ourselves */
+struct tc_entry *tc_myself;           /* Shortcut to ourselves */
 
 /* Some cookies for stats keeping */
 struct olsr_cookie_info *tc_edge_gc_timer_cookie = NULL;
@@ -78,11 +79,13 @@ struct olsr_cookie_info *tc_mem_cookie = NULL;
 
 /* Value window for ansn, identifies old messages to be ignored */
 #define TC_ANSN_WINDOW 256
+
 /* Value window for seqno, identifies old messages to be ignored */
 #define TC_SEQNO_WINDOW 1024
 
 /* Enlarges the value window for upcoming ansn/seqno to be accepted */
 #define TC_ANSN_WINDOW_MULT 4
+
 /* Enlarges the value window for upcoming ansn/seqno to be accepted */
 #define TC_SEQNO_WINDOW_MULT 8
 
@@ -90,11 +93,11 @@ static olsr_bool
 olsr_seq_inrange_low(int beg, int end, olsr_u16_t seq)
 {
   if (beg < 0) {
-    if (seq >= (olsr_u16_t)beg || seq < end) {
+    if (seq >= (olsr_u16_t) beg || seq < end) {
       return OLSR_TRUE;
     }
   } else if (end >= 0x10000) {
-    if (seq >= beg || seq < (olsr_u16_t)end) {
+    if (seq >= beg || seq < (olsr_u16_t) end) {
       return OLSR_TRUE;
     }
   } else if (seq >= beg && seq < end) {
@@ -107,11 +110,11 @@ static olsr_bool
 olsr_seq_inrange_high(int beg, int end, olsr_u16_t seq)
 {
   if (beg < 0) {
-    if (seq > (olsr_u16_t)beg || seq <= end) {
+    if (seq > (olsr_u16_t) beg || seq <= end) {
       return OLSR_TRUE;
     }
   } else if (end >= 0x10000) {
-    if (seq > beg || seq <= (olsr_u16_t)end) {
+    if (seq > beg || seq <= (olsr_u16_t) end) {
       return OLSR_TRUE;
     }
   } else if (seq > beg && seq <= end) {
@@ -162,8 +165,7 @@ olsr_add_tc_entry(union olsr_ip_addr *adr)
   /*
    * Add a rt_path for ourselves.
    */
-  olsr_insert_routing_table(adr, olsr_cnf->maxplen, adr,
-                            OLSR_RT_ORIGIN_INT);
+  olsr_insert_routing_table(adr, olsr_cnf->maxplen, adr, OLSR_RT_ORIGIN_INT);
 
   return tc;
 }
@@ -182,12 +184,16 @@ olsr_init_tc(void)
   /*
    * Get some cookies for getting stats to ease troubleshooting.
    */
-  tc_edge_gc_timer_cookie = olsr_alloc_cookie("TC edge GC", OLSR_COOKIE_TYPE_TIMER);
-  tc_validity_timer_cookie = olsr_alloc_cookie("TC validity", OLSR_COOKIE_TYPE_TIMER);
+  tc_edge_gc_timer_cookie =
+    olsr_alloc_cookie("TC edge GC", OLSR_COOKIE_TYPE_TIMER);
+  tc_validity_timer_cookie =
+    olsr_alloc_cookie("TC validity", OLSR_COOKIE_TYPE_TIMER);
 
-  tc_edge_mem_cookie = olsr_alloc_cookie("tc_edge_entry", OLSR_COOKIE_TYPE_MEMORY);
-  olsr_cookie_set_memory_size(tc_edge_mem_cookie, sizeof(struct tc_edge_entry) +
-    active_lq_handler->tc_lq_size);
+  tc_edge_mem_cookie =
+    olsr_alloc_cookie("tc_edge_entry", OLSR_COOKIE_TYPE_MEMORY);
+  olsr_cookie_set_memory_size(tc_edge_mem_cookie,
+                             sizeof(struct tc_edge_entry) +
+                             active_lq_handler->tc_lq_size);
 
   tc_mem_cookie = olsr_alloc_cookie("tc_entry", OLSR_COOKIE_TYPE_MEMORY);
   olsr_cookie_set_memory_size(tc_mem_cookie, sizeof(struct tc_entry));
@@ -336,13 +342,13 @@ olsr_tc_edge_to_string(struct tc_edge_entry *tc_edge)
   struct ipaddr_str addrbuf, dstbuf;
   struct tc_entry *tc = tc_edge->tc;
   struct lqtextbuffer lqbuffer1, lqbuffer2;
-  
+
   snprintf(buf, sizeof(buf),
-           "%s > %s, cost (%6s) %s",
-           olsr_ip_to_string(&addrbuf, &tc->addr),
-           olsr_ip_to_string(&dstbuf, &tc_edge->T_dest_addr),
-           get_tc_edge_entry_text(tc_edge, &lqbuffer1),
-           get_linkcost_text(tc_edge->cost, OLSR_FALSE, &lqbuffer2));
+          "%s > %s, cost (%6s) %s",
+          olsr_ip_to_string(&addrbuf, &tc->addr),
+          olsr_ip_to_string(&dstbuf, &tc_edge->T_dest_addr),
+          get_tc_edge_entry_text(tc_edge, &lqbuffer1),
+          get_linkcost_text(tc_edge->cost, OLSR_FALSE, &lqbuffer2));
 
   return buf;
 }
@@ -400,11 +406,11 @@ olsr_calc_tc_edge_entry_etx(struct tc_edge_entry *tc_edge)
   if (olsr_cnf->lq_level < 1) {
     return 0;
   }
-  
+
   old = tc_edge->cost;
   tc_edge->cost = olsr_calc_tc_cost(tc_edge);
-  
-  return olsr_is_relevant_costchange(old, tc_edge->cost); 
+
+  return olsr_is_relevant_costchange(old, tc_edge->cost);
 }
 
 /**
@@ -415,7 +421,7 @@ olsr_calc_tc_edge_entry_etx(struct tc_edge_entry *tc_edge)
  */
 struct tc_edge_entry *
 olsr_add_tc_edge_entry(struct tc_entry *tc, union olsr_ip_addr *addr,
-                       olsr_u16_t ansn)
+                      olsr_u16_t ansn)
 {
 #if !defined(NODEBUG) && defined(DEBUG)
   struct ipaddr_str buf;
@@ -432,7 +438,7 @@ olsr_add_tc_edge_entry(struct tc_entry *tc, union olsr_ip_addr *addr,
   tc_edge->T_dest_addr = *addr;
   tc_edge->ansn = ansn;
   tc_edge->edge_node.key = &tc_edge->T_dest_addr;
-  
+
   /*
    * Insert into the edge tree.
    */
@@ -452,14 +458,14 @@ olsr_add_tc_edge_entry(struct tc_entry *tc, union olsr_ip_addr *addr,
   if (tc_neighbor) {
 #ifdef DEBUG
     OLSR_PRINTF(1, "TC:   found neighbor tc_entry %s\n",
-                olsr_ip_to_string(&buf, &tc_neighbor->addr));
+               olsr_ip_to_string(&buf, &tc_neighbor->addr));
 #endif
 
     tc_edge_inv = olsr_lookup_tc_edge(tc_neighbor, &tc->addr);
     if (tc_edge_inv) {
 #ifdef DEBUG
       OLSR_PRINTF(1, "TC:   found inverse edge for %s\n",
-                  olsr_ip_to_string(&buf, &tc_edge_inv->T_dest_addr));
+                 olsr_ip_to_string(&buf, &tc_edge_inv->T_dest_addr));
 #endif
 
       /*
@@ -483,7 +489,6 @@ olsr_add_tc_edge_entry(struct tc_entry *tc, union olsr_ip_addr *addr,
   return tc_edge;
 }
 
-
 /**
  * Delete a TC edge entry.
  *
@@ -515,13 +520,11 @@ olsr_delete_tc_edge_entry(struct tc_edge_entry *tc_edge)
   olsr_cookie_free(tc_edge_mem_cookie, tc_edge);
 }
 
-
 /**
  * Delete all destinations that have a lower ANSN.
  *
  * @param tc the entry to delete edges from
- * @param ansn the advertised neighbor set sequence number
- * @return 1 if any destinations were deleted 0 if not
+ * @return TRUE if any destinations were deleted, FALSE if not
  */
 olsr_bool
 olsr_delete_outdated_tc_edges(struct tc_entry *tc)
@@ -543,6 +546,53 @@ olsr_delete_outdated_tc_edges(struct tc_entry *tc)
   return retval;
 }
 
+/**
+ * Delete all destinations that are inside the borders but
+ * not updated in the last tc.
+ *
+ * @param tc the entry to delete edges from
+ * @param ansn the advertised neighbor set sequence number
+ * @return 1 if any destinations were deleted 0 if not
+ */
+static int
+olsr_delete_revoked_tc_edges(struct tc_entry *tc, olsr_u16_t ansn,
+                            union olsr_ip_addr *lower_border,
+                            union olsr_ip_addr *upper_border)
+{
+  struct tc_edge_entry *tc_edge;
+  int retval = 0;
+
+#if 0
+  OLSR_PRINTF(5, "TC: deleting MPRS\n");
+#endif
+
+  olsr_bool passedLowerBorder = OLSR_FALSE;
+
+  OLSR_FOR_ALL_TC_EDGE_ENTRIES(tc, tc_edge) {
+    if (!passedLowerBorder) {
+      if (avl_comp_default(lower_border, &tc_edge->T_dest_addr) <= 0) {
+       passedLowerBorder = OLSR_TRUE;
+      } else {
+       continue;
+      }
+    }
+
+    if (passedLowerBorder) {
+      if (avl_comp_default(upper_border, &tc_edge->T_dest_addr) <= 0) {
+       break;
+      }
+    }
+
+    if (SEQNO_GREATER_THAN(ansn, tc_edge->ansn)) {
+      olsr_delete_tc_edge_entry(tc_edge);
+      retval = 1;
+    }
+  } OLSR_FOR_ALL_TC_EDGE_ENTRIES_END(tc, tc_edge);
+
+  return retval;
+}
+
+
 /**
  * Update an edge registered on an entry.
  * Creates new edge-entries if not registered.
@@ -554,10 +604,9 @@ olsr_delete_outdated_tc_edges(struct tc_entry *tc)
  */
 static int
 olsr_tc_update_edge(struct tc_entry *tc, olsr_u16_t ansn,
-                    const unsigned char **curr)
+                   const unsigned char **curr, union olsr_ip_addr *neighbor)
 {
   struct tc_edge_entry *tc_edge;
-  union olsr_ip_addr neighbor;
   int edge_change;
 
   edge_change = 0;
@@ -565,23 +614,23 @@ olsr_tc_update_edge(struct tc_entry *tc, olsr_u16_t ansn,
   /*
    * Fetch the per-edge data
    */
-  pkt_get_ipaddress(curr, &neighbor);
+  pkt_get_ipaddress(curr, neighbor);
 
   /* First check if we know this edge */
-  tc_edge = olsr_lookup_tc_edge(tc, &neighbor);
+  tc_edge = olsr_lookup_tc_edge(tc, neighbor);
+
+  if (!tc_edge) {
 
-  if(!tc_edge) {
-      
     /*
      * Yet unknown - create it.
      * Check if the address is allowed.
      */
-    if (!olsr_validate_address(&neighbor)) {
+    if (!olsr_validate_address(neighbor)) {
       return 0;
     }
 
-    tc_edge = olsr_add_tc_edge_entry(tc, &neighbor, ansn);
-    
+    tc_edge = olsr_add_tc_edge_entry(tc, neighbor, ansn);
+
     olsr_deserialize_tc_lq_pair(curr, tc_edge);
     edge_change = 1;
 
@@ -603,15 +652,14 @@ olsr_tc_update_edge(struct tc_entry *tc, olsr_u16_t ansn,
      * Update the etx.
      */
     if (olsr_calc_tc_edge_entry_etx(tc_edge)) {
-        if (tc->msg_hops <= olsr_cnf->lq_dlimit) {
-               edge_change = 1;
-        }
+      if (tc->msg_hops <= olsr_cnf->lq_dlimit) {
+       edge_change = 1;
+      }
     }
-
 #if DEBUG
-    if (edge_change) {          
+    if (edge_change) {
       OLSR_PRINTF(1, "TC:   chg edge entry %s\n",
-                  olsr_tc_edge_to_string(tc_edge));
+                 olsr_tc_edge_to_string(tc_edge));
     }
 #endif
 
@@ -631,7 +679,7 @@ struct tc_edge_entry *
 olsr_lookup_tc_edge(struct tc_entry *tc, union olsr_ip_addr *edge_addr)
 {
   struct avl_node *edge_node;
-  
+
 #if 0
   OLSR_PRINTF(1, "TC: lookup dst\n");
 #endif
@@ -652,28 +700,81 @@ olsr_print_tc_table(void)
   struct tc_entry *tc;
   const int ipwidth = olsr_cnf->ip_version == AF_INET ? 15 : 30;
 
-  OLSR_PRINTF(1, "\n--- %s ------------------------------------------------- TOPOLOGY\n\n"
-              "%-*s %-*s %-5s  %-5s  %s %s\n",
-              olsr_wallclock_string(),
-              ipwidth, "Source IP addr", ipwidth, "Dest IP addr", "LQ", "ILQ", "ETX", "UP");
+  OLSR_PRINTF(1,
+             "\n--- %s ------------------------------------------------- TOPOLOGY\n\n"
+             "%-*s %-*s %-14s  %s\n", olsr_wallclock_string(), ipwidth,
+             "Source IP addr", ipwidth, "Dest IP addr", "      LQ      ",
+             "ETX");
 
   OLSR_FOR_ALL_TC_ENTRIES(tc) {
     struct tc_edge_entry *tc_edge;
     OLSR_FOR_ALL_TC_EDGE_ENTRIES(tc, tc_edge) {
       struct ipaddr_str addrbuf, dstaddrbuf;
       struct lqtextbuffer lqbuffer1, lqbuffer2;
-      
-      OLSR_PRINTF(1, "%-*s %-*s  (%-10s) %s\n",
-                  ipwidth, olsr_ip_to_string(&addrbuf, &tc->addr),
-                  ipwidth, olsr_ip_to_string(&dstaddrbuf, &tc_edge->T_dest_addr),
-                  get_tc_edge_entry_text(tc_edge, &lqbuffer1),
-                  get_linkcost_text(tc_edge->cost, OLSR_FALSE, &lqbuffer2));
-      
+
+      OLSR_PRINTF(1, "%-*s %-*s %-14s %s\n",
+                 ipwidth, olsr_ip_to_string(&addrbuf, &tc->addr),
+                 ipwidth, olsr_ip_to_string(&dstaddrbuf,
+                                            &tc_edge->T_dest_addr),
+                 get_tc_edge_entry_text(tc_edge, &lqbuffer1),
+                 get_linkcost_text(tc_edge->cost, OLSR_FALSE, &lqbuffer2));
+
     } OLSR_FOR_ALL_TC_EDGE_ENTRIES_END(tc, tc_edge);
   } OLSR_FOR_ALL_TC_ENTRIES_END(tc);
 #endif
 }
 
+/*
+ * calculate the border IPs of a tc edge set according to the border flags
+ *
+ * @param lower border flag
+ * @param pointer to lower border ip
+ * @param upper border flag
+ * @param pointer to upper border ip
+ * @result 1 if lower/upper border ip have been set 
+ */
+static int
+olsr_calculate_tc_border(olsr_u8_t lower_border,
+                        union olsr_ip_addr *lower_border_ip,
+                        olsr_u8_t upper_border,
+                        union olsr_ip_addr *upper_border_ip)
+{
+  if (lower_border == 0 && upper_border == 0) {
+    return 0;
+  }
+  if (lower_border == 0xff) {
+    memset(&lower_border_ip, 0, sizeof(lower_border_ip));
+  } else {
+    int i;
+
+    lower_border--;
+    for (i = 0; i < lower_border / 8; i++) {
+      lower_border_ip->v6.in6_u.u6_addr8[olsr_cnf->ipsize - i - 1] = 0;
+    }
+    lower_border_ip->v6.in6_u.u6_addr8[olsr_cnf->ipsize - lower_border / 8 -
+                                      1] &= (0xff << (lower_border & 7));
+    lower_border_ip->v6.in6_u.u6_addr8[olsr_cnf->ipsize - lower_border / 8 -
+                                      1] |= (1 << (lower_border & 7));
+  }
+
+  if (upper_border == 0xff) {
+    memset(&upper_border_ip, 0xff, sizeof(upper_border_ip));
+  } else {
+    int i;
+
+    upper_border--;
+
+    for (i = 0; i < upper_border / 8; i++) {
+      upper_border_ip->v6.in6_u.u6_addr8[olsr_cnf->ipsize - i - 1] = 0;
+    }
+    upper_border_ip->v6.in6_u.u6_addr8[olsr_cnf->ipsize - upper_border / 8 -
+                                      1] &= (0xff << (upper_border & 7));
+    upper_border_ip->v6.in6_u.u6_addr8[olsr_cnf->ipsize - upper_border / 8 -
+                                      1] |= (1 << (upper_border & 7));
+  }
+  return 1;
+}
+
 /*
  * Process an incoming TC or TC_LQ message.
  *
@@ -686,20 +787,23 @@ olsr_print_tc_table(void)
  */
 void
 olsr_input_tc(union olsr_message *msg,
-              struct interface *input_if __attribute__((unused)),
-              union olsr_ip_addr *from_addr)
+             struct interface *input_if __attribute__ ((unused)),
+             union olsr_ip_addr *from_addr)
 {
-#ifndef NODEBUG 
+#ifndef NODEBUG
   struct ipaddr_str buf;
 #endif
   olsr_u16_t size, msg_seq, ansn;
-  olsr_u8_t type, ttl, msg_hops;
+  olsr_u8_t type, ttl, msg_hops, lower_border, upper_border;
   double vtime;
   unsigned int vtime_s;
   union olsr_ip_addr originator;
   const unsigned char *limit, *curr;
   struct tc_entry *tc;
 
+  union olsr_ip_addr lower_border_ip, upper_border_ip;
+  int borderSet = 0;
+
   curr = (void *)msg;
   if (!msg) {
     return;
@@ -722,52 +826,52 @@ olsr_input_tc(union olsr_message *msg,
   pkt_get_u8(&curr, &msg_hops);
   pkt_get_u16(&curr, &msg_seq);
   pkt_get_u16(&curr, &ansn);
-  pkt_ignore_u16(&curr);
+
+  /* Get borders */
+  pkt_get_u8(&curr, &lower_border);
+  pkt_get_u8(&curr, &upper_border);
 
   tc = olsr_lookup_tc_entry(&originator);
-  
+
   if (tc && 0 != tc->edge_tree.count) {
-    if (olsr_seq_inrange_high(
-          (int)tc->msg_seq - TC_SEQNO_WINDOW,
-          tc->msg_seq,
-          msg_seq) &&
-        olsr_seq_inrange_high(
-          (int)tc->ansn - TC_ANSN_WINDOW,
-          tc->ansn, ansn)) {
+    if (olsr_seq_inrange_high((int)tc->msg_seq - TC_SEQNO_WINDOW,
+                             tc->msg_seq,
+                             msg_seq) &&
+       olsr_seq_inrange_high((int)tc->ansn - TC_ANSN_WINDOW, tc->ansn, ansn)) {
 
       /*
        * Ignore already seen seq/ansn values (small window for mesh memory)
        */
       if ((tc->msg_seq == msg_seq) || (tc->ignored++ < 32)) {
-        return;
+       return;
       }
 
       OLSR_PRINTF(1, "Ignored to much LQTC's for %s, restarting\n",
-                  olsr_ip_to_string(&buf, &originator));
+                 olsr_ip_to_string(&buf, &originator));
 
-    } else if (!olsr_seq_inrange_high(
-                 tc->msg_seq,
-                 (int)tc->msg_seq + TC_SEQNO_WINDOW * TC_SEQNO_WINDOW_MULT,
-                 msg_seq) ||
-               !olsr_seq_inrange_low(
-                 tc->ansn,
-                 (int)tc->ansn + TC_ANSN_WINDOW * TC_ANSN_WINDOW_MULT,
-                 ansn)) {
+    } else
+      if (!olsr_seq_inrange_high
+         (tc->msg_seq,
+          (int)tc->msg_seq + TC_SEQNO_WINDOW * TC_SEQNO_WINDOW_MULT, msg_seq)
+         || !olsr_seq_inrange_low(tc->ansn,
+                                  (int)tc->ansn +
+                                  TC_ANSN_WINDOW * TC_ANSN_WINDOW_MULT,
+                                  ansn)) {
 
       /*
        * Only accept future seq/ansn values (large window for node reconnects).
        * Restart in all other cases. Ignore a single stray message.
        */
       if (!tc->err_seq_valid) {
-        tc->err_seq = msg_seq;
-        tc->err_seq_valid = OLSR_TRUE;
+       tc->err_seq = msg_seq;
+       tc->err_seq_valid = OLSR_TRUE;
       }
       if (tc->err_seq == msg_seq) {
-        return;
+       return;
       }
 
       OLSR_PRINTF(2, "Detected node restart for %s\n",
-                  olsr_ip_to_string(&buf, &originator));
+                 olsr_ip_to_string(&buf, &originator));
     }
   }
 
@@ -786,7 +890,7 @@ olsr_input_tc(union olsr_message *msg,
   tc->ansn = ansn;
   tc->ignored = 0;
   tc->err_seq_valid = OLSR_FALSE;
-  
+
   /*
    * If the sender interface (NB: not originator) of this message
    * is not in the symmetric 1-hop neighborhood of this node, the
@@ -794,37 +898,61 @@ olsr_input_tc(union olsr_message *msg,
    */
   if (check_neighbor_link(from_addr) != SYM_LINK) {
     OLSR_PRINTF(2, "Received TC from NON SYM neighbor %s\n",
-                olsr_ip_to_string(&buf, from_addr));
+               olsr_ip_to_string(&buf, from_addr));
     return;
   }
 
   OLSR_PRINTF(1, "Processing TC from %s, seq 0x%04x\n",
-              olsr_ip_to_string(&buf, &originator), ansn);
+             olsr_ip_to_string(&buf, &originator), ansn);
 
   /*
    * Now walk the edge advertisements contained in the packet.
    */
+
   limit = (unsigned char *)msg + size;
+  borderSet = 0;
   while (curr < limit) {
-    if (olsr_tc_update_edge(tc, ansn, &curr)) {
+    if (olsr_tc_update_edge(tc, ansn, &curr, &upper_border_ip)) {
       changes_topology = OLSR_TRUE;
     }
+
+    if (!borderSet) {
+      borderSet = 1;
+      memcpy(&lower_border_ip, &upper_border_ip, sizeof(lower_border_ip));
+    }
   }
 
   /*
-   * Set or change the expiration timer accordingly.
+   * Calculate real border IPs.
    */
-  olsr_set_timer(&tc->validity_timer, vtime_s * MSEC_PER_SEC,
-                 OLSR_TC_VTIME_JITTER, OLSR_TIMER_ONESHOT,
-                 &olsr_expire_tc_entry, tc, tc_validity_timer_cookie->ci_id);
+  if (borderSet) {
+    borderSet = olsr_calculate_tc_border(lower_border, &lower_border_ip,
+                                        upper_border, &upper_border_ip);
+  }
 
   /*
-   * Kick the the edge garbage collection timer. In the meantime hopefully
-   * all edges belonging to a multipart neighbor set will arrive.
+   * Set or change the expiration timer accordingly.
    */
-  olsr_set_timer(&tc->edge_gc_timer, OLSR_TC_EDGE_GC_TIME,
-                 OLSR_TC_EDGE_GC_JITTER, OLSR_TIMER_ONESHOT,
-                 &olsr_expire_tc_edge_gc, tc, tc_edge_gc_timer_cookie->ci_id);
+  olsr_set_timer(&tc->validity_timer, vtime_s * MSEC_PER_SEC,
+                OLSR_TC_VTIME_JITTER, OLSR_TIMER_ONESHOT,
+                &olsr_expire_tc_entry, tc, tc_validity_timer_cookie->ci_id);
+
+  if (borderSet) {
+
+    /*
+     * Delete all old tc edges within borders.
+     */
+    olsr_delete_revoked_tc_edges(tc, ansn, &lower_border_ip, &upper_border_ip);
+  } else {
+
+    /*
+     * Kick the the edge garbage collection timer. In the meantime hopefully
+     * all edges belonging to a multipart neighbor set will arrive.
+     */
+    olsr_set_timer(&tc->edge_gc_timer, OLSR_TC_EDGE_GC_TIME,
+                  OLSR_TC_EDGE_GC_JITTER, OLSR_TIMER_ONESHOT,
+                  &olsr_expire_tc_edge_gc, tc, tc_edge_gc_timer_cookie->ci_id);
+  }
 
   /*
    * Last, flood the message to our other neighbors.
index 94eb89b..8bc7a21 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
  * The olsr.org Optimized Link-State Routing daemon(olsrd)
  * Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
  * The SPF calculation operates on these datasets.
  */
 
-struct tc_edge_entry
-{
-  struct avl_node    edge_node; /* edge_tree node in tc_entry */
-  union olsr_ip_addr T_dest_addr; /* edge_node key */
-  struct tc_edge_entry *edge_inv; /* shortcut, used during SPF calculation */
-  struct tc_entry    *tc; /* backpointer to owning tc entry */
-  olsr_linkcost      cost; /* metric used for SPF calculation */
-  olsr_u16_t         ansn; /* ansn of this edge, used for multipart msgs */
-  char               linkquality[0];
+struct tc_edge_entry {
+  struct avl_node edge_node;          /* edge_tree node in tc_entry */
+  union olsr_ip_addr T_dest_addr;      /* edge_node key */
+  struct tc_edge_entry *edge_inv;      /* shortcut, used during SPF calculation */
+  struct tc_entry *tc;                /* backpointer to owning tc entry */
+  olsr_linkcost cost;                 /* metric used for SPF calculation */
+  olsr_u16_t ansn;                    /* ansn of this edge, used for multipart msgs */
+  char linkquality[0];
 };
 
 AVLNODE2STRUCT(edge_tree2tc_edge, struct tc_edge_entry, edge_node);
 
-struct tc_entry
-{
-  struct avl_node    vertex_node; /* node keyed by ip address */
-  union olsr_ip_addr addr; /* vertex_node key */
-  struct avl_node    cand_tree_node; /* SPF candidate heap, node keyed by path_etx */
-  olsr_linkcost      path_cost; /* SPF calculated distance, cand_tree_node key */
-  struct list_node   path_list_node; /* SPF result list */
-  struct avl_tree    edge_tree; /* subtree for edges */
-  struct avl_tree    prefix_tree; /* subtree for prefixes */
-  struct link_entry  *next_hop; /* SPF calculated link to the 1st hop neighbor */
-  struct timer_entry *edge_gc_timer; /* used for edge garbage collection */
-  struct timer_entry *validity_timer; /* tc validity time */
-  olsr_u32_t         refcount; /* reference counter */
-  olsr_u16_t         msg_seq; /* sequence number of the tc message */
-  olsr_u8_t          msg_hops; /* hopcount as per the tc message */
-  olsr_u8_t          hops; /* SPF calculated hopcount */
-  olsr_u16_t         ansn; /* ANSN number of the tc message */
-  olsr_u16_t         ignored; /* how many TC messages ignored in a sequence (kindof emergency brake) */
-  olsr_u16_t         err_seq; /* sequence number of an unplausible TC */
-  olsr_bool          err_seq_valid; /* do we have an error (unplauible seq/ansn) */
+struct tc_entry {
+  struct avl_node vertex_node;        /* node keyed by ip address */
+  union olsr_ip_addr addr;            /* vertex_node key */
+  struct avl_node cand_tree_node;      /* SPF candidate heap, node keyed by path_etx */
+  olsr_linkcost path_cost;            /* SPF calculated distance, cand_tree_node key */
+  struct list_node path_list_node;     /* SPF result list */
+  struct avl_tree edge_tree;          /* subtree for edges */
+  struct avl_tree prefix_tree;        /* subtree for prefixes */
+  struct link_entry *next_hop;        /* SPF calculated link to the 1st hop neighbor */
+  struct timer_entry *edge_gc_timer;   /* used for edge garbage collection */
+  struct timer_entry *validity_timer;  /* tc validity time */
+  olsr_u32_t refcount;                /* reference counter */
+  olsr_u16_t msg_seq;                 /* sequence number of the tc message */
+  olsr_u8_t msg_hops;                 /* hopcount as per the tc message */
+  olsr_u8_t hops;                     /* SPF calculated hopcount */
+  olsr_u16_t ansn;                    /* ANSN number of the tc message */
+  olsr_u16_t ignored;                 /* how many TC messages ignored in a sequence
+                                          (kindof emergency brake) */
+  olsr_u16_t err_seq;                 /* sequence number of an unplausible TC */
+  olsr_bool err_seq_valid;            /* do we have an error (unplauible seq/ansn) */
 };
 
 /*
  * Garbage collection time for edges.
  * This is used for multipart messages.
  */
-#define OLSR_TC_EDGE_GC_TIME (2*1000) /* milliseconds */
-#define OLSR_TC_EDGE_GC_JITTER 5 /* percent */
+#define OLSR_TC_EDGE_GC_TIME (2*1000)  /* milliseconds */
+#define OLSR_TC_EDGE_GC_JITTER 5       /* percent */
 
-#define OLSR_TC_VTIME_JITTER 25 /* percent */
+#define OLSR_TC_VTIME_JITTER 25        /* percent */
 
 
 AVLNODE2STRUCT(vertex_tree2tc, struct tc_entry, vertex_node);
@@ -149,7 +149,7 @@ void olsr_time_out_tc_set(void);
 
 /* tc msg input parser */
 void olsr_input_tc(union olsr_message *, struct interface *,
-                   union olsr_ip_addr *from);
+                  union olsr_ip_addr *from);
 
 /* tc_entry manipulation */
 struct tc_entry *olsr_lookup_tc_entry(union olsr_ip_addr *);
@@ -161,13 +161,14 @@ void olsr_unlock_tc_entry(struct tc_entry *);
 olsr_bool olsr_delete_outdated_tc_edges(struct tc_entry *);
 char *olsr_tc_edge_to_string(struct tc_edge_entry *);
 struct tc_edge_entry *olsr_lookup_tc_edge(struct tc_entry *,
-                                          union olsr_ip_addr *);
+                                         union olsr_ip_addr *);
 struct tc_edge_entry *olsr_add_tc_edge_entry(struct tc_entry *,
-                                             union olsr_ip_addr *, olsr_u16_t);
+                                            union olsr_ip_addr *, olsr_u16_t);
 void olsr_delete_tc_entry(struct tc_entry *);
 void olsr_delete_tc_edge_entry(struct tc_edge_entry *);
 olsr_bool olsr_calc_tc_edge_entry_etx(struct tc_edge_entry *);
 void olsr_set_tc_edge_timer(struct tc_edge_entry *, unsigned int);
+// static olsr_bool olsr_etx_significant_change(float, float);
 
 #endif
 
index 0621b6f..78311e6 100644 (file)
@@ -238,7 +238,7 @@ olsr_print_two_hop_neighbor_table(void)
   int i;
 
   OLSR_PRINTF(1, "\n--- %s ----------------------- TWO-HOP NEIGHBORS\n\n"
-              "IP addr (2-hop)  IP addr (1-hop)  TLQ\n",
+              "IP addr (2-hop)  IP addr (1-hop)  Total cost\n",
               olsr_wallclock_string());
 
   for (i = 0; i < HASHSIZE; i++) {
index c8d920f..7f3cc4e 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * The olsr.org Optimized Link-State Routing daemon(olsrd)
- * Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
+ * Copyright (c) 2004, Andreas Tnnesen(andreto@olsr.org)
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without 
index 4ac6a62..f0ca9e2 100644 (file)
@@ -622,6 +622,7 @@ add_hemu_if(struct olsr_if *iface)
   /*
    * Register functions for periodic message generation 
    */
+  
   ifp->hello_gen_timer =
     olsr_start_timer(iface->cnf->hello_params.emission_interval * MSEC_PER_SEC,
                      HELLO_JITTER, OLSR_TIMER_PERIODIC,