clean checkin
authorHenning Rogge <rogge@fgan.de>
Tue, 18 Mar 2008 14:07:12 +0000 (15:07 +0100)
committerHenning Rogge <rogge@fgan.de>
Tue, 18 Mar 2008 14:07:12 +0000 (15:07 +0100)
77 files changed:
Makefile
Makefile.inc
lib/arprefresh/src/olsrd_arprefresh.c
lib/bmf/src/Bmf.c
lib/bmf/src/NetworkInterfaces.c
lib/bmf/src/olsrd_plugin.c
lib/dot_draw/src/olsrd_dot_draw.c
lib/dyn_gw/src/olsrd_dyn_gw.c
lib/dyn_gw_plain/src/olsrd_dyn_gw_plain.c
lib/httpinfo/src/olsrd_httpinfo.c
lib/nameservice/src/mapwrite.c
lib/nameservice/src/nameservice.c
lib/nameservice/src/nameservice.h
lib/nameservice/src/olsrd_plugin.c
lib/pgraph/src/olsrd_pgraph.c
lib/quagga/src/olsrd_plugin.c
lib/secure/src/olsrd_plugin.c
lib/secure/src/olsrd_secure.c
lib/tas/src/plugin.c
lib/tas/src/plugin.h
lib/txtinfo/src/olsrd_txtinfo.c
src/defs.h
src/duplicate_set.c
src/duplicate_set.h
src/generate_msg.h
src/hashing.c
src/hashing.h
src/hna_set.c
src/hna_set.h
src/hysteresis.c
src/hysteresis.h
src/interfaces.c
src/interfaces.h
src/link_set.c
src/link_set.h
src/linux/apm.c
src/linux/link_layer.c
src/lq_list.h
src/lq_mpr.c
src/lq_packet.c
src/lq_packet.h
src/lq_plugin.c [new file with mode: 0644]
src/lq_plugin.h [new file with mode: 0644]
src/lq_plugin_default.c [new file with mode: 0644]
src/lq_plugin_default.h [new file with mode: 0644]
src/lq_route.c
src/lq_route.h
src/main.c
src/mantissa.c
src/mid_set.c
src/mid_set.h
src/mpr.c
src/mpr_selector_set.c
src/mpr_selector_set.h
src/neighbor_table.c
src/neighbor_table.h
src/net_olsr.c
src/olsr.c
src/olsr.h
src/olsr_protocol.h
src/olsr_types.h
src/packet.c
src/packet.h
src/parser.c
src/process_package.c
src/routing_table.c
src/routing_table.h
src/scheduler.c
src/scheduler.h
src/socket_parser.c
src/socket_parser.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
src/win32/ifnet.c

index ca3b276..45043fe 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -192,6 +192,10 @@ quagga:
                $(MAKECMD) -C lib/quagga 
                $(MAKECMD) -C lib/quagga DESTDIR=$(DESTDIR) install 
 
+txtinfo:
+               $(MAKECMD) -C lib/txtinfo clean
+               $(MAKECMD) -C lib/txtinfo 
+               $(MAKECMD) -C lib/txtinfo DESTDIR=$(DESTDIR) install 
 
 build_all:     all switch libs
 install_all:   install install_libs
index 4147022..9feb874 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
 
 # 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=50
+WARNINGS +=    -finline-limit=100
 # 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,
@@ -178,7 +178,7 @@ OBJS +=             $(SRCS:%.c=%.o)
 # debugging or non-debugging flags
 ifeq ($(DEBUG),1)
 CPPFLAGS +=    -DDEBUG
-CFLAGS +=      -g
+CFLAGS +=      -ggdb
 else
 CPPFLAGS +=    -DNDEBUG
 endif
index 9210ff6..d45107d 100644 (file)
@@ -188,7 +188,8 @@ int olsrd_plugin_init(void)
                    0 <= setsockopt(arprefresh_sockfd, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)))
                {
                        /* Register the ARP refresh event */
-                       olsr_register_scheduler_event(&olsr_arp_event, NULL, 2, 0, NULL);
+                        olsr_start_timer(2 * MSEC_PER_SEC, 0, OLSR_TIMER_PERIODIC,
+                                         &olsr_arp_event, NULL, 0);
                        ret = 1;
                }
                else
index a93f524..3b116fe 100644 (file)
@@ -60,7 +60,7 @@
 #include "defs.h" /* olsr_cnf, OLSR_PRINTF */
 #include "ipcalc.h"
 #include "olsr.h" /* olsr_printf */
-#include "scheduler.h" /* olsr_register_scheduler_event */
+#include "scheduler.h" /* olsr_start_timer() */
 #include "mid_set.h" /* mid_lookup_main_addr() */
 #include "mpr_selector_set.h" /* olsr_lookup_mprs_set() */
 #include "link_set.h" /* get_best_link_to_neighbor() */
index 4daf2a8..3a458b2 100644 (file)
@@ -64,6 +64,7 @@
 #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"
 
 /* Plugin includes */
 #include "Packet.h" /* IFHWADDRLEN */
@@ -389,37 +390,6 @@ void RestoreSpoofFilter(void)
   }
 } /* RestoreSpoofFilter */
 
-#ifndef USING_THALES_LINK_COST_ROUTING
-/* -------------------------------------------------------------------------
- * Function   : CalcEtx
- * Description: Calculate the Expected Transmission Count (ETX) value, based on
- *              link loss fraction and inverse link loss fraction
- * Input      : loss - link loss fraction
- *              neigh_loss - inverse link loss fraction 
- * Output     : none
- * Return     : the ETX value
- * Data Used  : none
- * ------------------------------------------------------------------------- */
-static float CalcEtx(float loss, float neigh_loss) 
-{
-#ifdef USE_FPM
-  if (loss < fpmtof(MIN_LINK_QUALITY) || neigh_loss < fpmtof(MIN_LINK_QUALITY))
-  {
-    return fpmtof(INFINITE_ETX);
-  }
-#else
-  if (loss < MIN_LINK_QUALITY || neigh_loss < MIN_LINK_QUALITY)
-  {
-    return INFINITE_ETX;
-  }
-#endif
-  else
-  {
-    return 1.0 / (loss * neigh_loss);
-  }
-} /* CalcEtx */
-#endif /* USING_THALES_LINK_COST_ROUTING */
-
 /* -------------------------------------------------------------------------
  * Function   : FindNeighbors
  * Description: Find the neighbors on a network interface to forward a BMF
@@ -461,9 +431,7 @@ void FindNeighbors(
   {
     struct link_entry* walker;
 
-    /* TODO: get_link_set() is not thread-safe! */
-    for (walker = get_link_set(); walker != NULL; walker = walker->next) 
-    {
+    OLSR_FOR_ALL_LINK_ENTRIES(walker) {
 #ifndef NODEBUG
       struct ipaddr_str buf;
 #endif
@@ -550,7 +518,7 @@ void FindNeighbors(
       }
 
       *nPossibleNeighbors += 1;
-    } /* for */
+    } OLSR_FOR_ALL_LINK_ENTRIES_END(walker);
 
   }
   /* handle the LQ case */
@@ -762,13 +730,8 @@ void FindNeighbors(
 #else /* USING_THALES_LINK_COST_ROUTING */
         
     struct link_entry* walker;
-#ifdef USE_FPM
-    float previousLinkEtx = 2 * fpmtof(INFINITE_ETX);
-    float bestEtx = 2 * fpmtof(INFINITE_ETX);
-#else
-    float previousLinkEtx = 2 * INFINITE_ETX;
-    float bestEtx = 2 * INFINITE_ETX;
-#endif
+    olsr_linkcost previousLinkEtx = LINK_COST_BROKEN;
+    olsr_linkcost bestEtx = LINK_COST_BROKEN;
 
     if (forwardedBy != NULL)
     {
@@ -776,21 +739,11 @@ void FindNeighbors(
       struct link_entry* bestLinkFromForwarder = get_best_link_to_neighbor(forwardedBy);
       if (bestLinkFromForwarder != NULL)
       {
-        previousLinkEtx =
-          CalcEtx(
-#ifdef USE_FPM
-            fpmtof(bestLinkFromForwarder->loss_link_quality),
-            fpmtof(bestLinkFromForwarder->neigh_link_quality));
-#else
-            bestLinkFromForwarder->loss_link_quality,
-            bestLinkFromForwarder->neigh_link_quality);
-#endif
+        previousLinkEtx = bestLinkFromForwarder->linkcost;
       }
     }
 
-    /* TODO: get_link_set() is not thread-safe! */
-    for (walker = get_link_set(); walker != NULL; walker = walker->next) 
-    {
+    OLSR_FOR_ALL_LINK_ENTRIES(walker) {
 #ifndef NODEBUG
       struct ipaddr_str buf;
 #endif
@@ -854,20 +807,9 @@ void FindNeighbors(
       /* Found a candidate neighbor to direct our packet to */
 
       /* Calculate the link quality (ETX) of the link to the found neighbor */
-      currEtx = CalcEtx(
-#ifdef USE_FPM
-        fpmtof(walker->loss_link_quality),
-        fpmtof(walker->neigh_link_quality));
-#else
-        walker->loss_link_quality,
-        walker->neigh_link_quality);
-#endif
+      currEtx = walker->linkcost;
  
-#ifdef USE_FPM
-      if (currEtx >= fpmtof(INFINITE_ETX))
-#else
-      if (currEtx >= INFINITE_ETX)
-#endif
+      if (currEtx < LINK_COST_BROKEN)
       {
         OLSR_PRINTF(
           9,
@@ -913,18 +855,11 @@ void FindNeighbors(
 #endif
           OLSR_PRINTF(
             9,
-            "%s: ----> Not forwarding to %s: \"%s\" gives a better link to this neighbor, costing %5.2f\n",
+            "%s: ----> Not forwarding to %s: \"%s\" gives a better link to this neighbor, costing %s\n",
             PLUGIN_NAME_SHORT,
             olsr_ip_to_string(&buf, &walker->neighbor_iface_addr),
             bestIntf->int_name,
-            CalcEtx(
-#ifdef USE_FPM
-              fpmtof(bestLinkToNeighbor->loss_link_quality),
-              fpmtof(bestLinkToNeighbor->neigh_link_quality)));
-#else
-              bestLinkToNeighbor->loss_link_quality,
-              bestLinkToNeighbor->neigh_link_quality));
-#endif
+            get_linkcost_text(bestLinkToNeighbor->linkcost, OLSR_FALSE));
         }
 
         continue; /* for */
@@ -937,11 +872,11 @@ void FindNeighbors(
 #endif
         OLSR_PRINTF(
           9,
-          "%s: ----> 2-hop path from %s via me to %s will cost ETX %5.2f\n",
+          "%s: ----> 2-hop path from %s via me to %s will cost ETX %s\n",
           PLUGIN_NAME_SHORT,
           olsr_ip_to_string(&forwardedByBuf, forwardedBy),
           olsr_ip_to_string(&niaBuf, &walker->neighbor_iface_addr),
-          previousLinkEtx + currEtx);
+          get_linkcost_text(previousLinkEtx + currEtx, OLSR_TRUE));
       }
 
       /* Check the topology table whether the 'forwardedBy' node is itself a direct
@@ -962,14 +897,7 @@ void FindNeighbors(
           /* We are not interested in dead-end or dying edges. */
           if (tc_edge != NULL && (tc_edge->flags & OLSR_TC_EDGE_DOWN) == 0)
           {
-            float tcEtx = CalcEtx(
-#ifdef USE_FPM
-              fpmtof(tc_edge->link_quality),
-              fpmtof(tc_edge->inverse_link_quality));
-#else
-              tc_edge->link_quality,
-              tc_edge->inverse_link_quality);
-#endif
+            olsr_linkcost tcEtx = tc_edge->cost;
 
             if (previousLinkEtx + currEtx > tcEtx)
             {
@@ -979,12 +907,12 @@ void FindNeighbors(
 #endif
               OLSR_PRINTF(
                 9,
-                "%s: ----> Not forwarding to %s: I am not an MPR between %s and %s, direct link costs %5.2f\n",
+                "%s: ----> Not forwarding to %s: I am not an MPR between %s and %s, direct link costs %s\n",
                 PLUGIN_NAME_SHORT,
                 neighbor_iface_buf.buf,
                 olsr_ip_to_string(&forw_buf, forwardedBy),
                 neighbor_iface_buf.buf,
-                tcEtx);
+                get_linkcost_text(tcEtx, OLSR_FALSE));
 
               continue; /* for */
             } /* if */
@@ -1008,7 +936,7 @@ void FindNeighbors(
       }
 
       *nPossibleNeighbors += 1;
-    } /* for */
+    } OLSR_FOR_ALL_LINK_ENTRIES_END(walker);
 
 #endif /* USING_THALES_LINK_COST_ROUTING */
 
index 3625965..bc08401 100644 (file)
@@ -45,7 +45,7 @@
 #include "olsrd_plugin.h"
 #include "plugin_util.h"
 #include "defs.h" /* olsr_u8_t, olsr_cnf */
-#include "scheduler.h" /* olsr_register_scheduler_event */
+#include "scheduler.h" /* olsr_start_timer() */
 
 /* BMF includes */
 #include "Bmf.h" /* InitBmf(), CloseBmf() */
@@ -98,7 +98,9 @@ int olsrd_plugin_init(void)
   add_ifchgf(&InterfaceChange);
 
   /* Register the duplicate registration pruning process */
-  olsr_register_scheduler_event(&PrunePacketHistory, NULL, 3.0, 2.0, NULL);
+  olsr_start_timer(3 * MSEC_PER_SEC, 0, OLSR_TIMER_PERIODIC,
+                   &PrunePacketHistory, NULL, 0);
+
 
   return InitBmf(NULL);
 }
index 739c0bc..4811be8 100644 (file)
@@ -69,6 +69,7 @@
 #include "link_set.h"
 #include "socket_parser.h"
 #include "net_olsr.h"
+#include "lq_plugin.h"
 
 #include "olsrd_dot_draw.h"
 #include "olsrd_plugin.h"
@@ -154,11 +155,7 @@ static void
 ipc_print_neigh_link(const struct neighbor_entry *neighbor)
 {
   struct ipaddr_str mainaddrstrbuf, strbuf;
-#ifdef USE_FPM
-  fpm etx = itofpm(0);
-#else
-  double etx = 0.0;
-#endif
+  olsr_linkcost etx = 0.0;
   const char *style;
   const char *adr = olsr_ip_to_string(&mainaddrstrbuf, &olsr_cnf->main_addr);
   struct link_entry* link;
@@ -168,7 +165,7 @@ ipc_print_neigh_link(const struct neighbor_entry *neighbor)
   } else {   
     link = get_best_link_to_neighbor(&neighbor->neighbor_main_addr);
     if (link) {
-      etx = olsr_calc_link_etx(link);
+      etx = link->linkcost;
     }
     style = "solid";
   }
@@ -176,7 +173,7 @@ ipc_print_neigh_link(const struct neighbor_entry *neighbor)
   ipc_send_fmt("\"%s\" -> \"%s\"[label=\"%s\", style=%s];\n",
                adr,
                olsr_ip_to_string(&strbuf, &neighbor->neighbor_main_addr),
-               olsr_etx_to_string(etx),
+               get_linkcost_text(etx, OLSR_FALSE),
                style);
   
   if (neighbor->is_mpr) {
@@ -269,6 +266,7 @@ ipc_action(int fd __attribute__((unused)))
   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
 }
 
 
@@ -280,25 +278,21 @@ pcf_event(int changes_neighborhood,
          int changes_topology,
          int changes_hna)
 {
-  int res = 0;
-  if(changes_neighborhood || changes_topology || changes_hna) {
-    struct neighbor_entry *neighbor_table_tmp;
-    struct tc_entry *tc;
-    struct tc_edge_entry *tc_edge;
-    struct ip_prefix_list *hna;
-    int idx;
+  struct neighbor_entry *neighbor_table_tmp;
+  struct tc_entry *tc;
+  struct tc_edge_entry *tc_edge;
+  struct ip_prefix_list *hna;
+  int idx, res = 0;
+
+  if (changes_neighborhood || changes_topology || changes_hna) {
     
     /* Print tables to IPC socket */
     ipc_send_str("digraph topology\n{\n");
 
     /* Neighbors */
-    for (idx = 0; idx < HASHSIZE; idx++) {       
-      for(neighbor_table_tmp = neighbortable[idx].next;
-          neighbor_table_tmp != &neighbortable[idx];
-          neighbor_table_tmp = neighbor_table_tmp->next){
-        ipc_print_neigh_link( neighbor_table_tmp );
-      }
-    }
+    OLSR_FOR_ALL_NBR_ENTRIES(neighbor_table_tmp) {
+      ipc_print_neigh_link( neighbor_table_tmp );
+    } OLSR_FOR_ALL_NBR_ENTRIES_END(neighbor_table_tmp);
 
     /* Topology */  
     OLSR_FOR_ALL_TC_ENTRIES(tc) {
@@ -347,7 +341,7 @@ ipc_print_tc_link(const struct tc_entry *entry, const struct tc_edge_entry *dst_
   ipc_send_fmt("\"%s\" -> \"%s\"[label=\"%s\"];\n",
                olsr_ip_to_string(&strbuf1, &entry->addr),
                olsr_ip_to_string(&strbuf2, &dst_entry->T_dest_addr),
-               olsr_etx_to_string(olsr_calc_tc_etx(dst_entry)));
+               get_linkcost_text(dst_entry->cost, OLSR_FALSE));
 }
 
 
@@ -395,3 +389,9 @@ ipc_send_fmt(const char *format, ...)
     ipc_send(buf, len);
   }
 }
+
+/*
+ * Local Variables:
+ * c-basic-offset: 2
+ * End:
+ */
index 621ce48..3c2e53f 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
  * The olsr.org Optimized Link-State Routing daemon(olsrd)
  * Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
 
 #include "olsr_types.h"
 #include "olsrd_dyn_gw.h"
-#include "scheduler.h"
 #include "olsr.h"
 #include "defs.h"
 #include "ipcalc.h"
+#include "scheduler.h"
 
 #include <stdio.h>
 #include <string.h>
@@ -251,7 +250,8 @@ olsrd_plugin_init(void)
   pthread_create(&ping_thread, NULL, (void *(*)(void *))looped_checks, NULL);
   
   /* Register the GW check */
-  olsr_register_scheduler_event(&olsr_event_doing_hna, NULL, 3, 4, NULL);
+  olsr_start_timer(3 * MSEC_PER_SEC, 0, OLSR_TIMER_PERIODIC,
+                   &olsr_event_doing_hna, NULL, 0);
 
   return 1;
 }
index 8ea7989..fd1149c 100644 (file)
@@ -95,7 +95,8 @@ olsrd_plugin_init(void)
   }
 
   /* Register the GW check */
-  olsr_register_scheduler_event(&olsr_event, NULL, 3, 4, NULL);
+  olsr_start_timer(3 * MSEC_PER_SEC, 0, OLSR_TIMER_PERIODIC,
+                   &olsr_event, NULL, 0);
 
   return 1;
 }
index ba9001a..87cf489 100644 (file)
@@ -62,6 +62,7 @@
 #include "link_set.h"
 #include "socket_parser.h"
 #include "ipcalc.h"
+#include "lq_plugin.h"
 
 #include "olsrd_httpinfo.h"
 #include "admin_interface.h"
@@ -86,7 +87,7 @@
 #define OS "Undefined"
 #endif
 
-static char copyright_string[] __attribute__((unused)) = "olsr.org HTTPINFO plugin Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org) All rights reserved.";
+static char copyright_string[] __attribute__((unused)) = "olsr.org HTTPINFO plugin Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org) All rights reserved.";
 
 #define MAX_CLIENTS 3
 
@@ -764,7 +765,7 @@ static int build_route(char *buf, olsr_u32_t bufsize, const struct rt_entry * rt
                    rt->rt_best->rtp_metric.hops);
   size += snprintf(&buf[size], bufsize-size,
                    "<td align=\"right\">%s</td>",
-                   olsr_etx_to_string(rt->rt_best->rtp_metric.etx));
+                   get_linkcost_text(rt->rt_best->rtp_metric.cost, OLSR_TRUE));
   size += snprintf(&buf[size], bufsize-size,
                    "<td align=\"center\">%s</td></tr>\n",
                    if_ifwithindex_name(rt->rt_best->rtp_nexthop.iif_index));
@@ -966,7 +967,7 @@ static int build_neigh_body(char *buf, olsr_u32_t bufsize)
 {
   struct neighbor_entry *neigh;
   struct link_entry *link = NULL;
-  int size = 0, idx;
+  int size = 0;
   const char *colspan = resolve_ip_addresses ? " colspan=\"2\"" : "";
 
   size += section_title(&buf[size], bufsize-size, "Links");
@@ -975,31 +976,24 @@ static int build_neigh_body(char *buf, olsr_u32_t bufsize)
                    "<tr><th align=\"center\"%s>Local IP</th><th align=\"center\"%s>Remote IP</th><th align=\"right\">Hysteresis</th>", colspan, colspan);
   if (olsr_cnf->lq_level > 0) {
     size += snprintf(&buf[size], bufsize-size,
-                     "<th align=\"right\">LinkQuality</th><th>lost</th><th>total</th><th align=\"right\">NLQ</th><th align=\"right\">ETX</th>");
+                     "<th align=\"right\">LinkCost</th>");
   }
   size += snprintf(&buf[size], bufsize-size, "</tr>\n");
 
   /* Link set */
-  for (link = link_set; link != NULL; link = link->next) {
+  OLSR_FOR_ALL_LINK_ENTRIES(link) {
     size += snprintf(&buf[size], bufsize-size, "<tr>");
     size += build_ipaddr_with_link(&buf[size], bufsize, &link->local_iface_addr, -1);
     size += build_ipaddr_with_link(&buf[size], bufsize, &link->neighbor_iface_addr, -1);
-    size += snprintf(&buf[size], bufsize-size, "<td align=\"right\">%s</td>", olsr_etx_to_string(link->L_link_quality));
+    size += snprintf(&buf[size], bufsize-size, "<td align=\"right\">%0.2f</td>", link->L_link_quality);
     if (olsr_cnf->lq_level > 0) {
       size += snprintf(&buf[size], bufsize-size,
-                       "<td align=\"right\">%s</td>"
-                       "<td>%d</td>"
-                       "<td>%d</td>"
-                       "<td align=\"right\">%s</td>"
-                       "<td align=\"right\">%s</td>\n",
-                       olsr_etx_to_string(link->loss_link_quality),
-                       link->lost_packets,
-                       link->total_packets,
-                       olsr_etx_to_string(link->neigh_link_quality),
-                       olsr_etx_to_string(olsr_calc_link_etx(link)));
+                       "<td align=\"right\">(%s) %s</td>",
+                       get_link_entry_text(link),
+                       get_linkcost_text(link->linkcost, OLSR_FALSE));
     }
     size += snprintf(&buf[size], bufsize-size, "</tr>\n");
-  }
+  } OLSR_FOR_ALL_LINK_ENTRIES_END(link);
 
   size += snprintf(&buf[size], bufsize-size, "</table>\n");
 
@@ -1007,33 +1001,36 @@ static int build_neigh_body(char *buf, olsr_u32_t bufsize)
   size += snprintf(&buf[size], bufsize-size,
                    "<tr><th align=\"center\"%s>IP Address</th><th align=\"center\">SYM</th><th align=\"center\">MPR</th><th align=\"center\">MPRS</th><th align=\"center\">Willingness</th><th>2 Hop Neighbors</th></tr>\n", colspan);
   /* Neighbors */
-  for (idx = 0; idx < HASHSIZE; idx++) {
-    for (neigh = neighbortable[idx].next; neigh != &neighbortable[idx]; neigh = neigh->next) {
-      struct neighbor_2_list_entry *list_2;
-      int thop_cnt;
-      size += snprintf(&buf[size], bufsize-size, "<tr>");
-      size += build_ipaddr_with_link(&buf[size], bufsize, &neigh->neighbor_main_addr, -1);
-      size += snprintf(&buf[size], bufsize-size,
-                       "<td align=\"center\">%s</td>"
-                       "<td align=\"center\">%s</td>"
-                       "<td align=\"center\">%s</td>"
-                       "<td align=\"center\">%d</td>",
-                       (neigh->status == SYM) ? "YES" : "NO",
-                       neigh->is_mpr ? "YES" : "NO",
-                       olsr_lookup_mprs_set(&neigh->neighbor_main_addr) ? "YES" : "NO",
-                       neigh->willingness);
-
-      size += snprintf(&buf[size], bufsize-size, "<td><select>\n"
-                       "<option>IP ADDRESS</option>\n");
+  OLSR_FOR_ALL_NBR_ENTRIES(neigh) {
 
-
-      for (list_2 = neigh->neighbor_2_list.next, thop_cnt = 0; list_2 != &neigh->neighbor_2_list; list_2 = list_2->next, thop_cnt++) {
-        struct ipaddr_str strbuf;
-        size += snprintf(&buf[size], bufsize-size, "<option>%s</option>\n", olsr_ip_to_string(&strbuf, &list_2->neighbor_2->neighbor_2_addr));
-      }
-      size += snprintf(&buf[size], bufsize-size, "</select> (%d)</td></tr>\n", thop_cnt);
+    struct neighbor_2_list_entry *list_2;
+    int thop_cnt;
+    size += snprintf(&buf[size], bufsize-size, "<tr>");
+    size += build_ipaddr_with_link(&buf[size], bufsize, &neigh->neighbor_main_addr, -1);
+    size += snprintf(&buf[size], bufsize-size,
+                     "<td align=\"center\">%s</td>"
+                     "<td align=\"center\">%s</td>"
+                     "<td align=\"center\">%s</td>"
+                     "<td align=\"center\">%d</td>",
+                     (neigh->status == SYM) ? "YES" : "NO",
+                     neigh->is_mpr ? "YES" : "NO",
+                     olsr_lookup_mprs_set(&neigh->neighbor_main_addr) ? "YES" : "NO",
+                     neigh->willingness);
+
+    size += snprintf(&buf[size], bufsize-size, "<td><select>\n"
+                     "<option>IP ADDRESS</option>\n");
+
+
+    for (list_2 = neigh->neighbor_2_list.next, thop_cnt = 0;
+         list_2 != &neigh->neighbor_2_list;
+         list_2 = list_2->next, thop_cnt++) {
+      struct ipaddr_str strbuf;
+      size += snprintf(&buf[size], bufsize-size, "<option>%s</option>\n",
+                       olsr_ip_to_string(&strbuf, &list_2->neighbor_2->neighbor_2_addr));
     }
-  }
+    size += snprintf(&buf[size], bufsize-size, "</select> (%d)</td></tr>\n", thop_cnt);
+  } OLSR_FOR_ALL_NBR_ENTRIES_END(neigh);
+
   size += snprintf(&buf[size], bufsize-size, "</table>\n");
   return size;
 }
@@ -1047,7 +1044,7 @@ static int build_topo_body(char *buf, olsr_u32_t bufsize)
   size += section_title(&buf[size], bufsize-size, "Topology Entries");
   size += snprintf(&buf[size], bufsize-size, "<tr><th align=\"center\"%s>Destination IP</th><th align=\"center\"%s>Last Hop IP</th>", colspan, colspan);
   if (olsr_cnf->lq_level > 0) {
-    size += snprintf(&buf[size], bufsize-size, "<th align=\"right\">LQ</th><th align=\"right\">ILQ</th><th align=\"right\">ETX</th>");
+    size += snprintf(&buf[size], bufsize-size, "<th align=\"right\">Linkcost</th>");
   }
   size += snprintf(&buf[size], bufsize-size, "</tr>\n");
 
@@ -1059,12 +1056,9 @@ static int build_topo_body(char *buf, olsr_u32_t bufsize)
           size += build_ipaddr_with_link(&buf[size], bufsize, &tc->addr, -1);
           if (olsr_cnf->lq_level > 0) {
               size += snprintf(&buf[size], bufsize-size,
-                               "<td align=\"right\">%s</td>"
-                               "<td align=\"right\">%s</td>"
-                               "<td align=\"right\">%s</td>\n",
-                               olsr_etx_to_string(tc_edge->link_quality),
-                               olsr_etx_to_string(tc_edge->inverse_link_quality),
-                               olsr_etx_to_string(olsr_calc_tc_etx(tc_edge)));
+                               "<td align=\"right\">(%s) %s</td>\n",
+                               get_tc_edge_entry_text(tc_edge),
+                               get_linkcost_text(tc_edge->cost, OLSR_FALSE));
           }
           size += snprintf(&buf[size], bufsize-size, "</tr>\n");
 
@@ -1274,3 +1268,9 @@ static ssize_t writen(int fd, const void *buf, size_t count)
     }
     return count;
 }
+
+/*
+ * Local Variables:
+ * c-basic-offset: 2
+ * End:
+ */
index 1545616..1c15ed1 100644 (file)
@@ -43,6 +43,8 @@
 #include "mid_set.h"
 #include "tc_set.h"
 #include "ipcalc.h"
+#include "lq_plugin.h"
+
 #include "mapwrite.h"
 
 static char my_latlon_str[48];
@@ -54,16 +56,20 @@ static char* lookup_position_latlon(union olsr_ip_addr *ip)
 {
   int hash;
   struct db_entry *entry;
-  if (ipequal(ip, &olsr_cnf->main_addr))
-  {
+  struct list_node *list_head, *list_node;
+
+  if (ipequal(ip, &olsr_cnf->main_addr)) {
     return my_latlon_str;
   }
-  for (hash = 0; hash < HASHSIZE; hash++) 
-  {
-    for(entry = latlon_list[hash]; entry != NULL; entry = entry->next)
-    {
-      if (NULL != entry->names && ipequal(&entry->originator, ip))
-      {
+
+  for (hash = 0; hash < HASHSIZE; hash++) {
+      list_head = &latlon_list[hash];
+      for (list_node = list_head->next; list_node != list_head;
+           list_node = list_node->next) {
+
+          entry = list2db(list_node);
+
+      if (entry->names && ipequal(&entry->originator, ip)) {
         return entry->names->name;
       }
     }
@@ -143,8 +149,14 @@ void mapwrite_work(FILE* fmap)
   for (hash = 0; hash < HASHSIZE; hash++) 
   {
     struct db_entry *entry;
-    for(entry = latlon_list[hash]; entry != NULL; entry = entry->next)
-    {
+       struct list_node *list_head, *list_node;
+
+    list_head = &latlon_list[hash];
+    for (list_node = list_head->next; list_node != list_head;
+         list_node = list_node->next) {
+        
+      entry = list2db(list_node);
+
       if (NULL != entry->names)
       {
         if (0 > fprintf(fmap, "Node('%s',%s,'%s','%s');\n",
@@ -167,12 +179,10 @@ void mapwrite_work(FILE* fmap)
       /*
        * To speed up processing, Links with both positions are named PLink()
        */
-      if (0 > fprintf(fmap, "PLink('%s','%s',%s,%s,%s,%s,%s);\n", 
+      if (0 > fprintf(fmap, "PLink('%s','%s',%s,%s,%s);\n", 
             olsr_ip_to_string(&strbuf1, &tc_edge->T_dest_addr),
             olsr_ip_to_string(&strbuf2, &tc->addr), 
-            olsr_etx_to_string(tc_edge->link_quality),
-            olsr_etx_to_string(tc_edge->inverse_link_quality),
-            olsr_etx_to_string(olsr_calc_tc_etx(tc_edge)),
+            get_linkcost_text(tc_edge->cost, OLSR_FALSE),
             lla, llb))
       {
         return;
@@ -183,12 +193,10 @@ void mapwrite_work(FILE* fmap)
       /*
        * If one link end pos is unkown, only send Link()
        */
-      if (0 > fprintf(fmap, "Link('%s','%s',%s,%s,%s);\n", 
+      if (0 > fprintf(fmap, "Link('%s','%s',%s);\n", 
             olsr_ip_to_string(&strbuf1, &tc_edge->T_dest_addr),
             olsr_ip_to_string(&strbuf2, &tc->addr), 
-            olsr_etx_to_string(tc_edge->link_quality),
-            olsr_etx_to_string(tc_edge->inverse_link_quality),
-            olsr_etx_to_string(olsr_calc_tc_etx(tc_edge))))
+            get_linkcost_text(tc_edge->cost, OLSR_FALSE)))
       {
         return;
       }
@@ -207,7 +215,7 @@ void mapwrite_work(FILE* fmap)
 static const char* the_fifoname = 0;
 static int fifopolltime = 0;
 
-static void mapwrite_poll(void)
+static void mapwrite_poll(void *context __attribute__((unused)))
 {
   fifopolltime++;
   if (0 == (fifopolltime & 7) && 0 != the_fifoname)
@@ -251,7 +259,7 @@ int mapwrite_init(const char* fifoname)
     else
     {
       the_fifoname = fifoname;
-      olsr_register_timeout_function(&mapwrite_poll, OLSR_FALSE);
+      olsr_start_timer(100, 5, OLSR_TIMER_PERIODIC, &mapwrite_poll, NULL, 0);
     }
   }
   return OLSR_TRUE;
index 329067d..2ded8f3 100644 (file)
@@ -60,7 +60,6 @@
 #include "plugin_util.h"
 #include "nameservice.h"
 #include "mapwrite.h"
-#include "olsrd_copy.h"
 #include "compat.h"
 
 
@@ -82,21 +81,28 @@ float my_lat = 0.0, my_lon = 0.0;
  * my own hostnames, service_lines and dns-servers
  * are store in a linked list (without hashing)
  * */
-static struct db_entry* list[HASHSIZE];
+static struct list_node list[HASHSIZE];
 struct name_entry *my_names = NULL;
+struct timer_entry *name_table_write = NULL;
 static olsr_bool name_table_changed = OLSR_TRUE;
 
-static struct db_entry* service_list[HASHSIZE];
+static struct list_node service_list[HASHSIZE];
 static struct name_entry *my_services = NULL;
 static olsr_bool service_table_changed = OLSR_TRUE;
 
-static struct db_entry* forwarder_list[HASHSIZE];
+static struct list_node forwarder_list[HASHSIZE];
 static struct name_entry *my_forwarders = NULL;
 static olsr_bool forwarder_table_changed = OLSR_TRUE;
 
-struct db_entry* latlon_list[HASHSIZE];
+struct list_node latlon_list[HASHSIZE];
 static olsr_bool latlon_table_changed = OLSR_TRUE;
 
+/* backoff timer for writing changes into a file */
+struct timer_entry *write_file_timer = NULL;
+
+/* periodic message generation */
+struct timer_entry *msg_gen_timer = NULL;
+
 /* regular expression to be matched by valid hostnames, compiled in name_init() */
 static regex_t regex_t_name;
 static regmatch_t regmatch_t_name;
@@ -146,12 +152,12 @@ name_constructor(void)
        my_latlon_file[0] = '\0';
        latlon_in_file[0] = '\0';
        
-       /* init lists */
+       /* init the lists heads */
        for(i = 0; i < HASHSIZE; i++) {
-               list[i] = NULL;
-               forwarder_list[i] = NULL;
-               service_list[i] = NULL;
-               latlon_list[i] = NULL;
+               list_head_init(&list[i]);
+               list_head_init(&forwarder_list[i]);
+               list_head_init(&service_list[i]);
+               list_head_init(&latlon_list[i]);
        }
        
 
@@ -372,8 +378,12 @@ name_init(void)
 
        /* register functions with olsrd */
        olsr_parser_add_function(&olsr_parser, PARSER_TYPE, 1);
-       olsr_register_timeout_function(&olsr_timeout, OLSR_TRUE);
-       olsr_register_scheduler_event(&olsr_event, NULL, my_interval, 0, NULL);
+
+       /* periodic message generation */
+       msg_gen_timer = olsr_start_timer(my_interval * MSEC_PER_SEC, EMISSION_JITTER,
+                                                                        OLSR_TIMER_PERIODIC, &olsr_namesvc_gen,
+                                                                        NULL, 0);
+
        mapwrite_init(my_latlon_file);
 
        return 1;
@@ -446,6 +456,9 @@ name_destructor(void)
        free_all_list_entries(forwarder_list);
        free_all_list_entries(latlon_list);
 
+       olsr_stop_timer(write_file_timer);
+       olsr_stop_timer(msg_gen_timer);
+
        regfree(&regex_t_name);
        regfree(&regex_t_service);
        mapwrite_exit();
@@ -453,108 +466,103 @@ name_destructor(void)
 
 /* free all list entries */
 void 
-free_all_list_entries(struct db_entry **this_db_list) 
+free_all_list_entries(struct list_node *this_db_list) 
 {
+       struct db_entry *db;
+       struct list_node *list_head, *list_node, *list_node_next;
+
        int i;
        
-       for(i = 0; i < HASHSIZE; i++)
-       {
-               struct db_entry **tmp = &this_db_list[i];
-               while(*tmp != NULL)
-               {
-                       struct db_entry *to_delete = *tmp;
-                       *tmp = (*tmp)->next;
-                       free_name_entry_list(&to_delete->names);
-                       free(to_delete);
-                       to_delete = NULL;
+       for (i = 0; i < HASHSIZE; i++) {
+
+               list_head = &this_db_list[i];
+
+               for (list_node = list_head->next;
+                        list_node != list_head;
+                        list_node = list_node_next) {
+
+                       /* prefetch next node before loosing context */
+                       list_node_next = list_node->next;
+
+                       db = list2db(list_node);
+                       olsr_namesvc_delete_db_entry(db);
                }
        }
 }
 
 
 /**
- * A timeout function called every time
- *
- * XXX:the scheduler is polled (by default 10 times a sec,
- * which is far too often):
- *
- * time out old list entries
- * and write changes to file
+ * The write file timer has fired.
  */
-
-static int timeout_roundrobin = 0;
-
 void
-olsr_timeout(void)
+olsr_expire_write_file_timer(void *context __attribute__((unused)))
 {
-       switch(timeout_roundrobin++)
-       {
-               case 0:
-                       timeout_old_names(list, &name_table_changed);
-                       timeout_old_names(forwarder_list, &forwarder_table_changed);
-                       timeout_old_names(service_list, &service_table_changed);
-                       timeout_old_names(latlon_list, &latlon_table_changed);
-                       break;
-               case 1:
-                       write_resolv_file(); // if forwarder_table_changed
-                       break;
-               case 2:
-                       write_hosts_file(); // if name_table_changed
-                       break;
-               case 3:
-                       write_services_file(); // if service_table_changed
-                       break;
+       write_file_timer = NULL;
+
+       write_resolv_file();   /* if forwarder_table_changed */
+       write_hosts_file();    /* if name_table_changed */
+       write_services_file(); /* if service_table_changed */
 #ifdef WIN32
-               case 4:
-                       write_latlon_file(); // latlon_table_changed
-                       break;
+       write_latlon_file();   /* if latlon_table_changed */
 #endif
-               default:
-                       timeout_roundrobin = 0;
-       } // switch
 }
 
-void
-timeout_old_names(struct db_entry **this_list, olsr_bool *this_table_changed)
+
+/*
+ * Kick a timer to write everything into a file.
+ * This also paces things a bit.
+ */
+static void
+olsr_start_write_file_timer(void)
 {
-       struct db_entry **tmp;
-       struct db_entry *to_delete;
-       int index;
+       if (write_file_timer) {
+               return;
+       }
 
-       for(index=0;index<HASHSIZE;index++)
-       {
-               for (tmp = &this_list[index]; *tmp != NULL; )
-               {
-                       /* check if the entry for this ip is timed out */
-                       if (olsr_timed_out(&(*tmp)->timer))
-                       {
+       write_file_timer = olsr_start_timer(5 * MSEC_PER_SEC, 5, OLSR_TIMER_ONESHOT,
+                                                                               olsr_expire_write_file_timer, NULL, 0);
+}
+
+/*
+ * Delete and unlink db_entry.
+ */
+void
+olsr_namesvc_delete_db_entry(struct db_entry *db)
+{
 #ifndef NODEBUG
-                               struct ipaddr_str strbuf;
+       struct ipaddr_str strbuf;
 #endif
-                               to_delete = *tmp;
-                               /* update the pointer in the linked list */
-                               *tmp = (*tmp)->next;
-                               
-                               OLSR_PRINTF(2, "NAME PLUGIN: %s timed out... deleting\n", 
-                                       olsr_ip_to_string(&strbuf, &to_delete->originator));
+       OLSR_PRINTF(2, "NAME PLUGIN: %s timed out... deleting\n", 
+                               olsr_ip_to_string(&strbuf, &db->originator));
+
+       olsr_start_write_file_timer();
+       olsr_stop_timer(db->db_timer); /* stop timer if running */
        
-                               /* Delete */
-                               free_name_entry_list(&to_delete->names);
-                               free(to_delete);
-                               *this_table_changed = OLSR_TRUE;
-                       } else {
-                               tmp = &(*tmp)->next;
-                       }
-               }
-       }
+       /* Delete */
+       free_name_entry_list(&db->names);
+       list_remove(&db->db_list);
+       free(db);
 }
 
+/**
+ * Callback for the db validity timer.
+ */
+static void
+olsr_nameservice_expire_db_timer(void *context)
+{
+  struct db_entry *db;
+
+  db = (struct db_entry *)context;
+  db->db_timer = NULL; /* be pedandic */
+
+  olsr_namesvc_delete_db_entry(db);
+}
 
 /**
  * Scheduled event: generate and send NAME packet
  */
 void
-olsr_event(void *foo __attribute__((unused)))
+olsr_namesvc_gen(void *foo __attribute__((unused)))
 {
        /* send buffer: huge */
        char buffer[10240];
@@ -658,18 +666,11 @@ olsr_parser(union olsr_message *m, struct interface *in_if, union olsr_ip_addr *
                return;
        }
 
-       /* Check if this message has been processed before
-       * Remeber that this also registeres the message as
-       * processed if nessecary
-       */
-       if(olsr_check_dup_table_proc(&originator, seqno)) {
-               /* If not so - process */
-               update_name_entry(&originator, namemessage, size, vtime);
-       }
+       update_name_entry(&originator, namemessage, size, vtime);
 
        /* Forward the message if nessecary
        * default_fwd does all the work for us! */
-       olsr_forward_message(m, &originator, seqno, in_if, ipaddr);
+       olsr_forward_message(m, ipaddr);
 }
 
 /**
@@ -824,7 +825,9 @@ decap_namemsg(struct name *from_packet, struct name_entry **to, olsr_bool *this_
                                free(already_saved_name_entries->name);
                                already_saved_name_entries->name = olsr_malloc(len_of_name + 1, "upd name_entry name");
                                strncpy(already_saved_name_entries->name, name, len_of_name);
+
                                *this_table_changed = OLSR_TRUE;
+                               olsr_start_write_file_timer();
                        }
                        if (!ipequal(&already_saved_name_entries->ip, &from_packet->ip))
                        {
@@ -836,7 +839,9 @@ decap_namemsg(struct name *from_packet, struct name_entry **to, olsr_bool *this_
                                        olsr_ip_to_string(&strbuf2, &from_packet->ip),
                                        olsr_ip_to_string(&strbuf3, &already_saved_name_entries->ip));
                                already_saved_name_entries->ip = from_packet->ip;
+
                                *this_table_changed = OLSR_TRUE;
+                               olsr_start_write_file_timer();
                        }
                        if (!*this_table_changed)
                        {
@@ -860,6 +865,7 @@ decap_namemsg(struct name *from_packet, struct name_entry **to, olsr_bool *this_
                tmp->name, olsr_ip_to_string(&strbuf, &tmp->ip), tmp->len, tmp->type);
 
        *this_table_changed = OLSR_TRUE;
+       olsr_start_write_file_timer();
 
        // queue to front
        tmp->next = *to;
@@ -899,19 +905,24 @@ update_name_entry(union olsr_ip_addr *originator, struct namemsg *msg, int msg_s
                
                switch (ntohs(from_packet->type)) {
                        case NAME_HOST: 
-                               insert_new_name_in_list(originator, list, from_packet, &name_table_changed, vtime); 
+                               insert_new_name_in_list(originator, list, from_packet,
+                                                                               &name_table_changed, vtime); 
                                break;
                        case NAME_FORWARDER:
-                               insert_new_name_in_list(originator, forwarder_list, from_packet, &forwarder_table_changed, vtime); 
+                               insert_new_name_in_list(originator, forwarder_list, from_packet,
+                                                                               &forwarder_table_changed, vtime); 
                                break;
                        case NAME_SERVICE:
-                               insert_new_name_in_list(originator, service_list, from_packet, &service_table_changed, vtime); 
+                               insert_new_name_in_list(originator, service_list, from_packet,
+                                                                               &service_table_changed, vtime); 
                                break;
                        case NAME_LATLON:
-                               insert_new_name_in_list(originator, latlon_list, from_packet, &latlon_table_changed, vtime);
+                               insert_new_name_in_list(originator, latlon_list, from_packet,
+                                                                               &latlon_table_changed, vtime);
                                break;
                        default:
-                               OLSR_PRINTF(3, "NAME PLUGIN: Received Message of unknown type [%d] from (%s)\n", from_packet->type, olsr_ip_to_string(&strbuf, originator));
+                               OLSR_PRINTF(3, "NAME PLUGIN: Received Message of unknown type [%d] from (%s)\n",
+                                                       from_packet->type, olsr_ip_to_string(&strbuf, originator));
                                break;
                }
 
@@ -928,51 +939,68 @@ update_name_entry(union olsr_ip_addr *originator, struct namemsg *msg, int msg_s
  * corresponding entry for this ip in the corresponding hash table
  */
 void
-insert_new_name_in_list(union olsr_ip_addr *originator, struct db_entry **this_list, struct name *from_packet, olsr_bool *this_table_changed, double vtime)
+insert_new_name_in_list(union olsr_ip_addr *originator,
+                                               struct list_node *this_list,
+                                               struct name *from_packet, olsr_bool *this_table_changed,
+                                               double vtime)
 {
        int hash;
        struct db_entry *entry;
+       struct list_node *list_head, *list_node;
 
        olsr_bool entry_found = OLSR_FALSE;
 
-       hash = olsr_hashing(originator);
+       hash = olsr_ip_hashing(originator);
 
        /* find the entry for originator, if there is already one */
-       for (entry = this_list[hash]; entry != NULL; entry = entry->next)
-       {
+       list_head = &this_list[hash];
+       for (list_node = list_head->next; list_node != list_head;
+                list_node = list_node->next) {
+
+               entry = list2db(list_node);
+
                if (ipequal(originator, &entry->originator)) {
 #ifndef NODEBUG
                        struct ipaddr_str strbuf;
 #endif
                        // found
-                       OLSR_PRINTF(4, "NAME PLUGIN: found entry for (%s) in its hash table\n", olsr_ip_to_string(&strbuf, originator));
+                       OLSR_PRINTF(4, "NAME PLUGIN: found entry for (%s) in its hash table\n",
+                                               olsr_ip_to_string(&strbuf, originator));
 
                        //delegate to function for parsing the packet and linking it to entry->names
                        decap_namemsg(from_packet, &entry->names, this_table_changed);
 
-                       olsr_get_timestamp(vtime * 1000, &entry->timer);
+                       olsr_set_timer(&entry->db_timer, vtime * MSEC_PER_SEC,
+                                                  OLSR_NAMESVC_DB_JITTER, OLSR_TIMER_ONESHOT,
+                                                  &olsr_nameservice_expire_db_timer, entry, 0);
 
                        entry_found = OLSR_TRUE;
                }
        }
+
        if (! entry_found)
        {
 #ifndef NODEBUG
                struct ipaddr_str strbuf;
 #endif
-               OLSR_PRINTF(3, "NAME PLUGIN: create new db entry for ip (%s) in hash table\n", olsr_ip_to_string(&strbuf, originator));
+               OLSR_PRINTF(3, "NAME PLUGIN: create new db entry for ip (%s) in hash table\n",
+                                       olsr_ip_to_string(&strbuf, originator));
 
                /* insert a new entry */
                entry = olsr_malloc(sizeof(struct db_entry), "new db_entry");
+               memset(entry, 0, sizeof(struct db_entry));
 
                entry->originator = *originator;
-               olsr_get_timestamp(vtime * 1000, &entry->timer);
-               entry->names = NULL;
 
-               // queue to front
-               entry->next = this_list[hash];
-               this_list[hash] = entry;
+               olsr_set_timer(&entry->db_timer, vtime * MSEC_PER_SEC,
+                                          OLSR_LINK_LOSS_JITTER, OLSR_TIMER_ONESHOT,
+                                          &olsr_nameservice_expire_db_timer, entry, 0);
 
+               entry->names = NULL;
+
+               /* insert to the list */
+               list_add_before(&this_list[hash], &entry->db_list);
+               
                //delegate to function for parsing the packet and linking it to entry->names
                decap_namemsg(from_packet, &entry->names, this_table_changed);
        }
@@ -987,6 +1015,7 @@ write_hosts_file(void)
        int hash;
        struct name_entry *name;
        struct db_entry *entry;
+       struct list_node *list_head, *list_node;
        FILE* hosts;
        FILE* add_hosts;
        int c=0;
@@ -1035,25 +1064,26 @@ write_hosts_file(void)
        }
        
        // write received names
-       for (hash = 0; hash < HASHSIZE; hash++) 
-       {
-               for(entry = list[hash]; entry != NULL; entry = entry->next)
-               {
-                       for (name = entry->names; name != NULL; name = name->next) 
-                       {
-                               struct ipaddr_str strbuf;
+       for (hash = 0; hash < HASHSIZE; hash++) {
+               list_head = &list[hash];
+               for (list_node = list_head->next; list_node != list_head;
+                        list_node = list_node->next) {
 
+                       entry = list2db(list_node);
+
+                       for (name = entry->names; name != NULL; name = name->next) {
+                               struct ipaddr_str strbuf;
                                OLSR_PRINTF(
                                        6, "%s\t%s%s\t#%s\n",
-                                               olsr_ip_to_string( &strbuf, &name->ip ), name->name, my_suffix,
-                                               olsr_ip_to_string( &strbuf, &entry->originator )
-                               );
+                                       olsr_ip_to_string( &strbuf, &name->ip ), name->name, my_suffix,
+                                       olsr_ip_to_string( &strbuf, &entry->originator )
+                                       );
 
                                fprintf(
                                        hosts, "%s\t%s%s\t# %s\n",
-                                               olsr_ip_to_string( &strbuf, &name->ip ), name->name, my_suffix,
-                                               olsr_ip_to_string( &strbuf, &entry->originator )
-                               );
+                                       olsr_ip_to_string( &strbuf, &name->ip ), name->name, my_suffix,
+                                       olsr_ip_to_string( &strbuf, &entry->originator )
+                                       );
 
 #ifdef MID_ENTRIES
                                // write mid entries
@@ -1071,19 +1101,19 @@ write_hosts_file(void)
 
                                                OLSR_PRINTF(
                                                        6, "%s\t%s%s%s\t# %s (mid #%i)\n",
-                                                               olsr_ip_to_string( &midbuf, &alias->alias ),
-                                                               mid_prefix, name->name, my_suffix,
-                                                               olsr_ip_to_string( &strbuf, &entry->originator ),
-                                                               mid_num
-                                               );
+                                                       olsr_ip_to_string( &midbuf, &alias->alias ),
+                                                       mid_prefix, name->name, my_suffix,
+                                                       olsr_ip_to_string( &strbuf, &entry->originator ),
+                                                       mid_num
+                                                       );
 
                                                fprintf(
                                                        hosts, "%s\t%s%s%s\t# %s (mid #%i)\n",
-                                                               olsr_ip_to_string( &midbuf, &alias->alias ),
-                                                               mid_prefix, name->name, my_suffix,
-                                                               olsr_ip_to_string( &strbuf, &entry->originator ),
-                                                               mid_num
-                                               );
+                                                       olsr_ip_to_string( &midbuf, &alias->alias ),
+                                                       mid_prefix, name->name, my_suffix,
+                                                       olsr_ip_to_string( &strbuf, &entry->originator ),
+                                                       mid_num
+                                                       );
 
                                                alias = alias->next_alias;
                                                mid_num++;
@@ -1117,6 +1147,7 @@ write_services_file(void)
        int hash;
        struct name_entry *name;
        struct db_entry *entry;
+       struct list_node *list_head, *list_node;
        FILE* services_file;
        time_t currtime;
 
@@ -1142,18 +1173,22 @@ write_services_file(void)
        }
        
        // write received services
-       for (hash = 0; hash < HASHSIZE; hash++) 
-       {
-               for(entry = service_list[hash]; entry != NULL; entry = entry->next)
-               {
-                       for (name = entry->names; name != NULL; name = name->next) 
-                       {
+       for (hash = 0; hash < HASHSIZE; hash++) {
+               list_head = &list[hash];
+               for (list_node = list_head->next; list_node != list_head;
+                        list_node = list_node->next) {
+
+                       entry = list2db(list_node);
+
+                       for (name = entry->names; name != NULL; name = name->next) {
                                struct ipaddr_str strbuf;
                                OLSR_PRINTF(6, "%s\t",  name->name);
-                               OLSR_PRINTF(6, "\t#%s\n", olsr_ip_to_string(&strbuf, &entry->originator));
+                               OLSR_PRINTF(6, "\t#%s\n",
+                                                       olsr_ip_to_string(&strbuf, &entry->originator));
 
                                fprintf(services_file, "%s\t", name->name );
-                               fprintf(services_file, "\t#%s\n", olsr_ip_to_string(&strbuf, &entry->originator));
+                               fprintf(services_file, "\t#%s\n",
+                                               olsr_ip_to_string(&strbuf, &entry->originator));
                        }
                }
        }
@@ -1196,9 +1231,9 @@ select_best_nameserver(struct rt_entry **rt)
                        /*
                         * first is better, swap the pointers.
                         */
-                       OLSR_PRINTF(6, "NAME PLUGIN: nameserver %s, etx %s\n",
+                       OLSR_PRINTF(6, "NAME PLUGIN: nameserver %s, cost %s\n",
                                                olsr_ip_to_string(&strbuf, &rt1->rt_dst.prefix),
-                                               olsr_etx_to_string(rt1->rt_best->rtp_metric.etx));
+                                               get_linkcost_text(rt1->rt_best->rtp_metric.cost, OLSR_TRUE));
 
                        rt[nameserver_idx] = rt2;
                        rt[nameserver_idx+1] = rt1;
@@ -1216,6 +1251,7 @@ write_resolv_file(void)
        int hash;
        struct name_entry *name;
        struct db_entry *entry;
+       struct list_node *list_head, *list_node;
        struct rt_entry *route;
        static struct rt_entry *nameserver_routes[NAMESERVER_COUNT+1];
        FILE* resolv;
@@ -1228,12 +1264,14 @@ write_resolv_file(void)
        /* clear the array of 3+1 nameserver routes */
        memset(nameserver_routes, 0, sizeof(nameserver_routes));
 
-       for (hash = 0; hash < HASHSIZE; hash++) 
-       {
-               for(entry = forwarder_list[hash]; entry != NULL; entry = entry->next)
-               {
-                       for (name = entry->names; name != NULL; name = name->next) 
-                       {
+       for (hash = 0; hash < HASHSIZE; hash++) {
+               list_head = &list[hash];
+               for (list_node = list_head->next; list_node != list_head;
+                        list_node = list_node->next) {
+
+                       entry = list2db(list_node);
+
+                       for (name = entry->names; name != NULL; name = name->next) {
 #ifndef NODEBUG
                                struct ipaddr_str strbuf;
 #endif
@@ -1248,9 +1286,9 @@ write_resolv_file(void)
 
                                /* enqueue it on the head of list */
                                *nameserver_routes = route;
-                               OLSR_PRINTF(6, "NAME PLUGIN: found nameserver %s, etx %s",
+                               OLSR_PRINTF(6, "NAME PLUGIN: found nameserver %s, cost %s",
                                                        olsr_ip_to_string(&strbuf, &name->ip),
-                                                       olsr_etx_to_string(route->rt_best->rtp_metric.etx));
+                                                       get_linkcost_text(route->rt_best->rtp_metric.cost, OLSR_TRUE));
 
                                /* find the closet one */
                                select_best_nameserver(nameserver_routes);
@@ -1307,6 +1345,25 @@ free_name_entry_list(struct name_entry **list)
        while (*tmp != NULL) {
                to_delete = *tmp;
                *tmp = (*tmp)->next;
+
+               /* flag changes */
+               switch (to_delete->type) {
+               case NAME_HOST:
+                       name_table_changed = OLSR_TRUE;
+                       break;
+               case NAME_FORWARDER:
+                       forwarder_table_changed = OLSR_TRUE;
+                       break;
+               case NAME_SERVICE:
+                       service_table_changed = OLSR_TRUE;
+                       break;
+               case NAME_LATLON:
+                       latlon_table_changed = OLSR_TRUE;
+                       break;
+               default:
+                       break;
+               }
+
                free( to_delete->name );
                to_delete->name = NULL;
                free( to_delete );
@@ -1511,13 +1568,17 @@ lookup_name_latlon(union olsr_ip_addr *ip)
 {
        int hash;
        struct db_entry *entry;
+       struct list_node *list_head, *list_node;
        struct name_entry *name;
-       for (hash = 0; hash < HASHSIZE; hash++) 
-       {
-               for(entry = list[hash]; entry != NULL; entry = entry->next)
-               {
-                       for (name = entry->names; name != NULL; name = name->next) 
-                       {
+
+       for (hash = 0; hash < HASHSIZE; hash++) {
+               list_head = &list[hash];
+               for (list_node = list_head->next; list_node != list_head;
+                        list_node = list_node->next) {
+
+                       entry = list2db(list_node);
+
+                       for (name = entry->names; name != NULL; name = name->next) {
                                if (ipequal(&name->ip, ip)) return name->name;
                        }
                }
index 53679cd..dd895d0 100644 (file)
@@ -43,6 +43,7 @@
 #include "olsr_types.h"
 #include "interfaces.h"
 #include "olsr_protocol.h"
+#include "lq_list.h"
 
 #include "olsrd_plugin.h"
 #include "nameservice_msg.h"
@@ -51,7 +52,7 @@
 
 #define PLUGIN_NAME    "OLSRD nameservice plugin"
 #define PLUGIN_VERSION "0.3"
-#define PLUGIN_AUTHOR   "Bruno Randolf, Jens Nachtigall, Sven-Ola"
+#define PLUGIN_AUTHOR   "Bruno Randolf, Jens Nachtigall, Sven-Ola Tuecke"
 
 // useful to set for the freifunkfirmware to remove all
 // calls to olsr_printf by the empty statement ";"
@@ -59,8 +60,9 @@
 
 #define MESSAGE_TYPE           130
 #define PARSER_TYPE            MESSAGE_TYPE
-#define EMISSION_INTERVAL      120 /* two minutes */
-#define NAME_VALID_TIME                1800 /* half one hour */
+#define EMISSION_INTERVAL      120 /* seconds */
+#define EMISSION_JITTER         25 /* percent */
+#define NAME_VALID_TIME                1800 /* seconds */
 #define NAMESERVER_COUNT        3
 
 #define NAME_PROTOCOL_VERSION  1
@@ -103,26 +105,29 @@ struct name_entry
 struct db_entry
 {
        union olsr_ip_addr      originator;     /* IP address of the node this entry describes */
-       struct timeval          timer;          /* Validity time */
+        struct timer_entry      *db_timer;      /* Validity time */
        struct name_entry       *names;         /* list of names this originator declares */
-       struct db_entry         *next;          /* linked list */
+        struct list_node        db_list;        /* linked list of db entries per hash container */
 };
 
+/* inline to recast from db_list back to db_entry */
+LISTNODE2STRUCT(list2db, struct db_entry, db_list);
+
+#define OLSR_NAMESVC_DB_JITTER 5 /* percent */
+
 extern struct name_entry *my_names;
-extern struct db_entry* latlon_list[HASHSIZE];
+extern struct list_node latlon_list[HASHSIZE];
 extern float my_lat, my_lon;
 
-/* Timeout function to register with the sceduler */
-void
-olsr_timeout(void);
+void olsr_expire_write_file_timer(void *);
+void olsr_namesvc_delete_db_entry(struct db_entry *);
 
 /* Parser function to register with the sceduler */
 void
 olsr_parser(union olsr_message *, struct interface *, union olsr_ip_addr *);
 
-/* Event function to register with the sceduler */
-void
-olsr_event(void *);
+/* callback for periodic timer */
+void olsr_namesvc_gen(void *);
 
 int
 encap_namemsg(struct namemsg *);
@@ -134,16 +139,14 @@ struct name_entry*
 remove_nonvalid_names_from_list(struct name_entry *my_list, int type);
 
 void 
-free_all_list_entries(struct db_entry **this_db_list) ;
-
-void
-timeout_old_names(struct db_entry **this_list, olsr_bool *this_table_changed);
+free_all_list_entries(struct list_node *) ;
 
 void
 decap_namemsg(struct name *from_packet, struct name_entry **to, olsr_bool *this_table_changed );
 
 void
-insert_new_name_in_list(union olsr_ip_addr *originator, struct db_entry **this_list, struct name *from_packet, olsr_bool *this_table_changed, double vtime);
+insert_new_name_in_list(union olsr_ip_addr *, struct list_node *,
+                        struct name *, olsr_bool *, double);
 
 olsr_bool
 allowed_hostname_or_ip_in_service(const char *service_line, const regmatch_t *hostname_or_ip);
@@ -209,3 +212,4 @@ int
 name_init(void);
 
 #endif
+
index 5535431..a63c318 100644 (file)
@@ -42,7 +42,7 @@
 
 #define PLUGIN_NAME    "OLSRD nameservice plugin"
 #define PLUGIN_VERSION "0.3"
-#define PLUGIN_AUTHOR   "Bruno Randolf, Jens Nachtigall, Sven-Ola"
+#define PLUGIN_AUTHOR   "Bruno Randolf, Jens Nachtigall, Sven-Ola Tuecke"
 #define MOD_DESC PLUGIN_NAME " " PLUGIN_VERSION
 #define PLUGIN_INTERFACE_VERSION 5
 
index dde246c..64e9f05 100644 (file)
@@ -313,42 +313,32 @@ static int pcf_event(int changes_neighborhood,
                      int changes_hna __attribute__((unused)))
 {
   int res;
-  olsr_u8_t index;
   struct neighbor_entry *neighbor_table_tmp;
   struct tc_entry *tc;
   struct tc_edge_entry *tc_edge;
 
   res = 0;
 
-  //if(changes_neighborhood || changes_topology || changes_hna)
-  if(changes_neighborhood || changes_topology)
-    {
-      /* Print tables to IPC socket */
+  if (changes_neighborhood || changes_topology) {
+    /* Print tables to IPC socket */
 
-      //ipc_send("start ", strlen("start "));
+    //ipc_send("start ", strlen("start "));
 
-      /* Neighbors */
-      for(index=0;index<HASHSIZE;index++)
-       {
-         
-         for(neighbor_table_tmp = neighbortable[index].next;
-             neighbor_table_tmp != &neighbortable[index];
-             neighbor_table_tmp = neighbor_table_tmp->next)
-           {
-             ipc_print_neigh_link( neighbor_table_tmp );
-           }
-       }
+    /* Neighbors */
+    OLSR_FOR_ALL_NBR_ENTRIES(neighbor_table_tmp) {
+      ipc_print_neigh_link( neighbor_table_tmp );
+    } OLSR_FOR_ALL_NBR_ENTRIES_END(neighbor_table_tmp);
 
-      /* Topology */  
-      OLSR_FOR_ALL_TC_ENTRIES(tc) {
-          OLSR_FOR_ALL_TC_EDGE_ENTRIES(tc, tc_edge) {
-              ipc_print_tc_link(tc, tc_edge);
-          } OLSR_FOR_ALL_TC_EDGE_ENTRIES_END(tc, tc_edge);
-      } OLSR_FOR_ALL_TC_ENTRIES_END(tc);
+    /* Topology */  
+    OLSR_FOR_ALL_TC_ENTRIES(tc) {
+      OLSR_FOR_ALL_TC_EDGE_ENTRIES(tc, tc_edge) {
+        ipc_print_tc_link(tc, tc_edge);
+      } OLSR_FOR_ALL_TC_EDGE_ENTRIES_END(tc, tc_edge);
+    } OLSR_FOR_ALL_TC_ENTRIES_END(tc);
 
-      ipc_send(" end ", strlen(" end "));
+    ipc_send(" end ", strlen(" end "));
 
-      /* HNA entries */
+    /* HNA entries */
 //      for(index=0;index<HASHSIZE;index++)
 //     {
 //       tmp_hna = hna_set[index].next;
@@ -372,12 +362,12 @@ static int pcf_event(int changes_neighborhood,
 
 //      ipc_send("}\n\n", strlen("}\n\n"));
 
-      res = 1;
-    }
-
+    res = 1;
+  }
 
-  if(ipc_socket == -1)
+  if (ipc_socket == -1) {
     plugin_ipc_init();
+  }
 
   return res;
 }
@@ -415,3 +405,9 @@ static int ipc_send(const char *data, int size)
 
   return 1;
 }
+
+/*
+ * Local Variables:
+ * c-basic-offset: 2
+ * End:
+ */
index 5b8a126..9360721 100644 (file)
@@ -125,7 +125,9 @@ int olsrd_plugin_init(void) {
     return 1;
   }
 
-  olsr_register_scheduler_event(&zebra_check, NULL, 1, 0, NULL);
+  olsr_start_timer(1 * MSEC_PER_SEC, 0, OLSR_TIMER_PERIODIC,
+                   &zebra_check, NULL, 0);
+
   return 0;
 }
 
index fc00422..342744f 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
  * Secure OLSR plugin
  * http://www.olsr.org
index 126ccd8..ffa9643 100644 (file)
@@ -107,6 +107,7 @@ MD5_checksum(const olsr_u8_t *data, const olsr_u16_t data_len, olsr_u8_t *hashbu
 #define OS "Undefined"
 #endif
 
+static struct timeval now;
 
 /* Timestamp node */
 struct stamp
@@ -198,7 +199,9 @@ secure_plugin_init(void)
   olsr_preprocessor_add_function(&secure_preprocessor);
   
   /* Register timeout - poll every 2 seconds */
-  olsr_register_scheduler_event(&timeout_timestamps, NULL, 2, 0 , NULL);
+  olsr_start_timer(2 * MSEC_PER_SEC, 0, OLSR_TIMER_PERIODIC,
+                   &timeout_timestamps, NULL, 0);
+
 
   return 1;
 }
@@ -641,7 +644,7 @@ send_challenge(struct interface *olsr_if, const union olsr_ip_addr *new_host)
   /* update validtime - not validated */
   entry->conftime = GET_TIMESTAMP(EXCHANGE_HOLD_TIME * 1000);
 
-  hash = olsr_hashing(new_host);
+  hash = olsr_ip_hashing(new_host);
   
   /* Queue */
   timestamps[hash].next->prev = entry;
@@ -883,7 +886,7 @@ parse_challenge(struct interface *olsr_if, char *in_msg)
       entry = malloc(sizeof(struct stamp));
       memcpy(&entry->addr, &msg->originator, olsr_cnf->ipsize);
 
-      hash = olsr_hashing((union olsr_ip_addr *)&msg->originator);
+      hash = olsr_ip_hashing((union olsr_ip_addr *)&msg->originator);
   
       /* Queue */
       timestamps[hash].next->prev = entry;
@@ -1122,7 +1125,7 @@ lookup_timestamp_entry(const union olsr_ip_addr *adr)
   struct stamp *entry;
   struct ipaddr_str buf;
 
-  hash = olsr_hashing(adr);
+  hash = olsr_ip_hashing(adr);
 
   for(entry = timestamps[hash].next;
       entry != &timestamps[hash];
@@ -1154,6 +1157,8 @@ timeout_timestamps(void* foo __attribute__((unused)))
   struct stamp *entry_to_delete;
   int index;
 
+  /* Update our local timestamp */
+  gettimeofday(&now, NULL);
 
   for(index=0;index<HASHSIZE;index++)
     {
index a679773..a16c98e 100644 (file)
@@ -67,6 +67,7 @@
 #include <lq_route.h>
 #include <mpr_selector_set.h>
 #include <duplicate_set.h>
+#include <lq_plugin.h>
 
 #define PLUGIN_INTERFACE_VERSION 5
 
@@ -105,34 +106,39 @@ static void __attribute__((constructor)) banner(void)
 
 int iterLinkTabNext(char *buff, int len)
 {
-#ifdef USE_FPM
-  fpm etx;
-#else
-  double etx;
-#endif
+  struct list_node *link_node;
 
   if (iterLinkTab == NULL)
     return -1;
 
-  etx = olsr_calc_link_etx(iterLinkTab);
-
-  snprintf(buff, len, "local~%s~remote~%s~main~%s~hysteresis~%s~lq~%s~nlq~%s~etx~%s~",
+  snprintf(buff, len, "local~%s~remote~%s~main~%s~hysteresis~%f~cost~%s~",
            rawIpAddrToString(&iterLinkTab->local_iface_addr, ipAddrLen),
            rawIpAddrToString(&iterLinkTab->neighbor_iface_addr, ipAddrLen),
            rawIpAddrToString(&iterLinkTab->neighbor->neighbor_main_addr, ipAddrLen),
-           olsr_etx_to_string(iterLinkTab->L_link_quality),
-           olsr_etx_to_string(iterLinkTab->loss_link_quality),
-           olsr_etx_to_string(iterLinkTab->neigh_link_quality),
-           olsr_etx_to_string(etx));
+           iterLinkTab->L_link_quality,
+           get_linkcost_text(iterLinkTab->linkcost, OLSR_FALSE));
+
 
-  iterLinkTab = iterLinkTab->next;
+  link_node = iterLinkTab->link_list.next;
+  if (link_node != &link_entry_head) {
+    iterLinkTab = list2link(link_node);
+  } else {
+    iterLinkTab = NULL;
+  }
 
   return 0;
 }
 
 void iterLinkTabInit(void)
 {
-  iterLinkTab = get_link_set();
+  struct list_node *link_node;
+
+  link_node = link_entry_head.next;
+  if (link_node != &link_entry_head) {
+    iterLinkTab = list2link(link_node);
+  } else {
+    iterLinkTab = NULL;
+  }
 }
 
 int iterNeighTabNext(char *buff, int len)
@@ -287,9 +293,9 @@ int iterTcTabNext(char *buff, int len)
 
   OLSR_FOR_ALL_TC_EDGE_ENTRIES(iterTcTab, tc_edge) {
 
-    res = snprintf(buff, len, "[~%d~address~%s~etx~%s~]~", i,
+    res = snprintf(buff, len, "[~%d~address~%s~cost~%s~]~", i,
                    rawIpAddrToString(&tc_edge->T_dest_addr, ipAddrLen),
-                   olsr_etx_to_string(olsr_calc_tc_etx(tc_edge)));
+                   get_linkcost_text(tc_edge->cost, OLSR_FALSE));
 
     if (res < len)
       buff += res;
@@ -324,7 +330,6 @@ static void parserFunc(union olsr_message *msg, struct interface *inInt,
 {
   char *mess = (char *)msg;
   union olsr_ip_addr *orig = (union olsr_ip_addr *)(mess + 4);
-  unsigned short seqNo = (mess[ipAddrLen + 6] << 8) | mess[ipAddrLen + 7];
   int len = (mess[2] << 8) | mess[3];
   char *service, *string;
   int i;
@@ -344,8 +349,6 @@ static void parserFunc(union olsr_message *msg, struct interface *inInt,
     return;
   }
 
-  if (olsr_check_dup_table_proc(orig, seqNo) != 0)
-  {
     len -= ipAddrLen + 8;
     service = mess + ipAddrLen + 8;
 
@@ -375,9 +378,8 @@ static void parserFunc(union olsr_message *msg, struct interface *inInt,
     }
 
     httpAddTasMessage(service, string, rawIpAddrToString(orig, ipAddrLen));
-  }
 
-  olsr_forward_message(msg, orig, seqNo, inInt, neighIntAddr);
+  olsr_forward_message(msg, neighIntAddr);
 }
 
 void sendMessage(const char *service, const char *string)
@@ -433,7 +435,7 @@ void sendMessage(const char *service, const char *string)
   }
 }
 
-static void serviceFunc(void)
+static void serviceFunc(void *context __attribute__((unused)))
 {
   static int up = 0;
 
@@ -467,7 +469,9 @@ int olsrd_plugin_init(void)
 
   httpInit();
   
-  olsr_register_timeout_function(serviceFunc, OLSR_FALSE);
+  olsr_start_timer(OLSR_TAS_SERVICE_INT, 0, OLSR_TIMER_PERIODIC,
+                   &serviceFunc, NULL, 0);
+
   olsr_parser_add_function(parserFunc, MESSAGE_TYPE, 1);
 
   return 0;
index 6e24ec5..9eeb69b 100644 (file)
@@ -39,6 +39,8 @@
  *
  */
 
+#define OLSR_TAS_SERVICE_INT 100 /* msec */
+
 extern void sendMessage(const char *service, const char *string);
 extern void iterLinkTabInit(void);
 extern int iterLinkTabNext(char *buff, int len);
index 602c7e5..e5ccf75 100644 (file)
@@ -76,6 +76,7 @@
 #include "link_set.h"
 #include "socket_parser.h"
 #include "net_olsr.h"
+#include "lq_plugin.h"
 
 #include "olsrd_txtinfo.h"
 #include "olsrd_plugin.h"
@@ -95,11 +96,13 @@ static int ipc_socket_up;
 /* IPC initialization function */
 static int plugin_ipc_init(void);
 
-static void  send_info(int neighonly);
+static void send_info(int send_what);
 
 static void ipc_action(int);
 
-static void ipc_print_neigh_link(void);
+static void ipc_print_neigh(void);
+
+static void ipc_print_link(void);
 
 static void ipc_print_routes(void);
 
@@ -110,6 +113,16 @@ static void ipc_print_hna(void);
 static void ipc_print_mid(void);
 
 #define TXT_IPC_BUFSIZE 256
+
+#define SIW_ALL 0
+#define SIW_NEIGH 1
+#define SIW_LINK 2
+#define SIW_ROUTE 3
+#define SIW_HNA 4
+#define SIW_MID 5
+#define SIW_TOPO 6
+#define SIW_NEIGHLINK 7
+
 static int ipc_sendf(const char* format, ...) __attribute__((format(printf, 1, 2)));
 
 /**
@@ -230,7 +243,7 @@ static void ipc_action(int fd)
     char addr[INET6_ADDRSTRLEN];
     fd_set rfds;
     struct timeval tv;
-    int neighonly = 0;
+    int send_what = 0;
 
     socklen_t addrlen = sizeof(struct sockaddr_storage);
 
@@ -285,65 +298,70 @@ static void ipc_action(int fd)
              * page the normal output is somewhat lengthy. The
              * header parsing is sufficient for standard wget.
              */
-            neighonly = (0 != strstr(requ, "/neighbours"));
+            if (0 != strstr(requ, "/neighbours")) send_what=SIW_NEIGHLINK;
+            else if (0 != strstr(requ, "/neigh")) send_what=SIW_NEIGH;
+            else if (0 != strstr(requ, "/link")) send_what=SIW_LINK;
+            else if (0 != strstr(requ, "/route")) send_what=SIW_ROUTE;
+            else if (0 != strstr(requ, "/hna")) send_what=SIW_HNA;
+            else if (0 != strstr(requ, "/mid")) send_what=SIW_MID;
+            else if (0 != strstr(requ, "/topo")) send_what=SIW_TOPO;
         }
     }
 
-    send_info(neighonly);
+       send_info(send_what);
          
     close(ipc_connection);
     ipc_open = 0;
 }
 
-static void ipc_print_neigh_link(void)
+static void ipc_print_neigh(void)
 {
-    struct ipaddr_str buf1, buf2;
+    struct ipaddr_str buf1;
     struct neighbor_entry *neigh;
     struct neighbor_2_list_entry *list_2;
+    int thop_cnt;
+
+    ipc_sendf("\nTable: Neighbors\nIP address\tSYM\tMPR\tMPRS\tWillingness\t2 Hop Neighbors\n");
+
+    /* Neighbors */
+    OLSR_FOR_ALL_NBR_ENTRIES(neigh) {
+        ipc_sendf("%s\t%s\t%s\t%s\t%d\t", 
+                  olsr_ip_to_string(&buf1, &neigh->neighbor_main_addr),
+                  (neigh->status == SYM) ? "YES" : "NO",
+                  neigh->is_mpr ? "YES" : "NO",
+                  olsr_lookup_mprs_set(&neigh->neighbor_main_addr) ? "YES" : "NO",
+                  neigh->willingness);
+        thop_cnt = 0;
+
+        for(list_2 = neigh->neighbor_2_list.next;
+            list_2 != &neigh->neighbor_2_list;
+            list_2 = list_2->next)
+        {
+            //size += sprintf(&buf[size], "<option>%s</option>\n", olsr_ip_to_string(&buf1, &list_2->neighbor_2->neighbor_2_addr));
+            thop_cnt ++;
+        }
+        ipc_sendf("%d\n", thop_cnt);
+    } OLSR_FOR_ALL_NBR_ENTRIES_END(neigh);
+    ipc_sendf("\n");
+}
+
+static void ipc_print_link(void)
+{
+    struct ipaddr_str buf1, buf2;
     struct link_entry *link = NULL;
-    int index, thop_cnt;
 
-    ipc_sendf("Table: Links\nLocal IP\tremote IP\tHysteresis\tLinkQuality\tlost\ttotal\tNLQ\tETX\n");
+    ipc_sendf("Table: Links\nLocal IP\tremote IP\tHysteresis\tLinkcost\n");
 
     /* Link set */
-    link = link_set;
-    while(link)        {
-       ipc_sendf( "%s\t%s\t%s\t%s\t%d\t%d\t%s\t%s\t\n",
+    OLSR_FOR_ALL_LINK_ENTRIES(link) {
+       ipc_sendf( "%s\t%s\t%0.2f\t%s\t%s\t\n",
                    olsr_ip_to_string(&buf1, &link->local_iface_addr),
                    olsr_ip_to_string(&buf2, &link->neighbor_iface_addr),
-                   olsr_etx_to_string(link->L_link_quality), 
-                   olsr_etx_to_string(link->loss_link_quality),
-                   link->lost_packets, 
-                   link->total_packets,
-                   olsr_etx_to_string(link->neigh_link_quality), 
-                   olsr_etx_to_string(olsr_calc_link_etx(link)));
-        link = link->next;
-    }
-    ipc_sendf("\nTable: Neighbors\nIP address\tSYM\tMPR\tMPRS\tWillingness\t2 Hop Neighbors\n");
+                   link->L_link_quality, 
+                   get_link_entry_text(link),
+                   get_linkcost_text(link->linkcost, OLSR_FALSE));
+    } OLSR_FOR_ALL_LINK_ENTRIES_END(link);
 
-    /* Neighbors */
-    for(index = 0; index < HASHSIZE; index++) {
-        for(neigh = neighbortable[index].next;
-            neigh != &neighbortable[index];
-            neigh = neigh->next) {
-            ipc_sendf("%s\t%s\t%s\t%s\t%d\t", 
-                      olsr_ip_to_string(&buf1, &neigh->neighbor_main_addr),
-                      (neigh->status == SYM) ? "YES" : "NO",
-                      neigh->is_mpr ? "YES" : "NO",
-                      olsr_lookup_mprs_set(&neigh->neighbor_main_addr) ? "YES" : "NO",
-                      neigh->willingness);
-            thop_cnt = 0;
-
-            for(list_2 = neigh->neighbor_2_list.next;
-                list_2 != &neigh->neighbor_2_list;
-                list_2 = list_2->next)
-                {
-                    //size += sprintf(&buf[size], "<option>%s</option>\n", olsr_ip_to_string(&buf1, &list_2->neighbor_2->neighbor_2_addr));
-                    thop_cnt ++;
-                }
-            ipc_sendf("%d\n", thop_cnt);
-       }
-    }
     ipc_sendf("\n");
 }
 
@@ -367,7 +385,7 @@ static void ipc_print_routes(void)
                    rt->rt_dst.prefix_len,
                    olsr_ip_to_string(&buf2, &rt->rt_best->rtp_nexthop.gateway),
                    rt->rt_best->rtp_metric.hops,
-                   olsr_etx_to_string(rt->rt_best->rtp_metric.etx),
+                   get_linkcost_text(rt->rt_best->rtp_metric.cost, OLSR_TRUE),
                    if_ifwithindex_name(rt->rt_best->rtp_nexthop.iif_index));
     }
     ipc_sendf("\n");
@@ -378,19 +396,18 @@ static void ipc_print_topology(void)
 {
     struct tc_entry *tc;
     
-    ipc_sendf("Table: Topology\nDestination IP\tLast hop IP\tLQ\tILQ\tETX\n");
+    ipc_sendf("Table: Topology\nDestination IP\tLast hop IP\tLinkcost\n");
 
     /* Topology */  
     OLSR_FOR_ALL_TC_ENTRIES(tc) {
         struct tc_edge_entry *tc_edge;
         OLSR_FOR_ALL_TC_EDGE_ENTRIES(tc, tc_edge) {
             struct ipaddr_str dstbuf, addrbuf;
-            ipc_sendf( "%s\t%s\t%s\t%s\t%s\n", 
+            ipc_sendf( "%s\t%s\t%s\t%s\n", 
                        olsr_ip_to_string(&dstbuf, &tc_edge->T_dest_addr),
                        olsr_ip_to_string(&addrbuf, &tc->addr), 
-                       olsr_etx_to_string(tc_edge->link_quality),
-                       olsr_etx_to_string(tc_edge->inverse_link_quality),
-                       olsr_etx_to_string(olsr_calc_tc_etx(tc_edge)));
+                       get_tc_edge_entry_text(tc_edge),
+                       get_linkcost_text(tc_edge->cost, OLSR_FALSE));
 
         } OLSR_FOR_ALL_TC_EDGE_ENTRIES_END(tc, tc_edge);
     } OLSR_FOR_ALL_TC_ENTRIES_END(tc);
@@ -482,7 +499,7 @@ static void ipc_print_mid(void)
 }
 
 
-static void  send_info(int neighonly)
+static void  send_info(int send_what)
 {
     /* Print minimal http header */
     ipc_sendf("HTTP/1.0 200 OK\n");
@@ -491,19 +508,21 @@ static void  send_info(int neighonly)
     /* Print tables to IPC socket */
        
     /* links + Neighbors */
-    ipc_print_neigh_link();
+    if ((send_what==SIW_ALL)||(send_what==SIW_NEIGHLINK)||(send_what==SIW_LINK)) ipc_print_link();
+
+    if ((send_what==SIW_ALL)||(send_what==SIW_NEIGHLINK)||(send_what==SIW_NEIGH)) ipc_print_neigh();
        
     /* topology */
-    if (!neighonly) ipc_print_topology();
+    if ((send_what==SIW_ALL)||(send_what==SIW_TOPO)) ipc_print_topology();
        
     /* hna */
-    if (!neighonly) ipc_print_hna();
+    if ((send_what==SIW_ALL)||(send_what==SIW_HNA)) ipc_print_hna();
 
     /* mid */
-    if (!neighonly) ipc_print_mid();
+    if ((send_what==SIW_ALL)||(send_what==SIW_MID)) ipc_print_mid();
 
     /* routes */
-    if (!neighonly) ipc_print_routes();
+    if ((send_what==SIW_ALL)||(send_what==SIW_ROUTE)) ipc_print_routes();
 }
 
 /*
index efe7e90..9a4784a 100644 (file)
@@ -91,10 +91,16 @@ extern FILE *debug_handle;
   } while (0)
 #endif
 
-/* Provides a timestamp s1 milliseconds in the future
-   according to system ticks returned by times(2) */
+/*
+ * Provides a timestamp s1 milliseconds in the future according
+ * to system ticks returned by times(2)
+*/
 #define GET_TIMESTAMP(s1)      (now_times + ((s1) / olsr_cnf->system_tick_divider))
 
+/* Compute the time in milliseconds when a timestamp will expire. */
+#define TIME_DUE(s1)   ((int)((s1) * olsr_cnf->system_tick_divider) - now_times)
+
+/* Returns TRUE if a timestamp is expired */
 #define TIMED_OUT(s1)  ((int)((s1) - now_times) < 0)
 
 
@@ -132,13 +138,10 @@ extern FILE *debug_handle;
 /*
  * Global olsrd configuragtion
  */
-
 extern struct olsrd_config *olsr_cnf;
 
 /* Timer data */
-extern clock_t now_times;              /* current idea of times(2) reported uptime */
-extern struct timeval now;            /* current idea of time */
-extern struct tm *nowtm;              /* current idea of time (in tm) */
+extern clock_t now_times; /* current idea of times(2) reported uptime */
 
 #if defined WIN32
 extern olsr_bool olsr_win32_end_request;
index 6a9240c..f41db9f 100644 (file)
-/*
- * The olsr.org Optimized Link-State Routing daemon(olsrd)
- * Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
- * 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 "ipcalc.h"
 #include "duplicate_set.h"
-#include "scheduler.h"
+#include "ipcalc.h"
+#include "lq_avl.h"
 #include "olsr.h"
-#include "net_olsr.h"
-
-/* The duplicate table */
-static struct dup_entry dup_set[HASHSIZE];
-
-/**
- *Initialize the duplicate table entrys
- *
- *@return nada
- */
-void
-olsr_init_duplicate_table(void)
-{
-  int i;
-
-  OLSR_PRINTF(3, "Initializing duplicatetable - hashsize %d\n", HASHSIZE);
-
-  /* Since the holdingtime is rather large for duplicate
-   * entries the timeoutfunction is only ran every 2 seconds
-   */
-  olsr_register_scheduler_event_dijkstra(&olsr_time_out_duplicate_table, NULL, 2.0, 0.0, NULL);
-  
-  for(i = 0; i < HASHSIZE; i++)
-    {
-      dup_set[i].next = &dup_set[i];
-      dup_set[i].prev = &dup_set[i];
-    }
-}
-
-
-/**
- *Add an entry to the duplicate set. The set is not checked
- *for duplicate entries.
- *
- *@param originator IP address of the sender of the message
- *@param seqno seqno of the message
- *
- *@return positive on success
- */
-static struct dup_entry *
-olsr_add_dup_entry(const union olsr_ip_addr *originator, const olsr_u16_t seqno)
-{
-  olsr_u32_t hash;
-  struct dup_entry *new_dup_entry;
-
-
-  /* Hash the senders address */
-  hash = HASHMASK & seqno;
-
-  new_dup_entry = olsr_malloc(sizeof(struct dup_entry), "New dup entry");
-
-  /* Address */
-  new_dup_entry->addr = *originator;
-  /* Seqno */
-  new_dup_entry->seqno = seqno;
-  /* Set timer */
-  new_dup_entry->timer = GET_TIMESTAMP(DUP_HOLD_TIME*1000);
-  /* Interfaces */
-  new_dup_entry->ifaces = NULL;
-  /* Forwarded */
-  new_dup_entry->forwarded = 0;
-
-  /* Insert into set */
-  QUEUE_ELEM(dup_set[hash], new_dup_entry);
-  /*
-  dup_set[hash].next->prev = new_dup_entry;
-  new_dup_entry->next = dup_set[hash].next;
-  dup_set[hash].next = new_dup_entry;
-  new_dup_entry->prev = &dup_set[hash];
-  */
-  return new_dup_entry;
-}
-
-
-/**
- * Check wether or not a message should be processed
- *
- */
-int
-olsr_check_dup_table_proc(const union olsr_ip_addr *originator, const olsr_u16_t seqno)
-{
-  olsr_u32_t hash;
-  struct dup_entry *tmp_dup_table;
-
-  /* Hash the senders address */
-  hash = HASHMASK & seqno;
-
-  /* Check for entry */
-  for(tmp_dup_table = dup_set[hash].next;
-      tmp_dup_table != &dup_set[hash];
-      tmp_dup_table = tmp_dup_table->next)
-    {
-      if(ipequal(&tmp_dup_table->addr, originator) &&
-        (tmp_dup_table->seqno == seqno))
-       {
-         return 0;
-       }
-    }
-
-  return 1;
-}
-
-
-/**
- * Check wether or not a message should be forwarded
- *
- */
-int
-olsr_check_dup_table_fwd(const union olsr_ip_addr *originator, 
-                         const olsr_u16_t seqno,
-                         const union olsr_ip_addr *int_addr)
-{
-  olsr_u32_t hash;
-  struct dup_entry *tmp_dup_table;
-
-  /* Hash the senders address */
-  hash = HASHMASK & seqno;
-
-  /* Check for entry */
-  for(tmp_dup_table = dup_set[hash].next;
-      tmp_dup_table != &dup_set[hash];
-      tmp_dup_table = tmp_dup_table->next)
-    {
-      if(ipequal(&tmp_dup_table->addr, originator) &&
-        (tmp_dup_table->seqno == seqno))
-       {
-         struct dup_iface *tmp_dup_iface;
-         /* Check retransmitted */
-         if(tmp_dup_table->forwarded)
-           return 0;
-         /* Check for interface */
-         tmp_dup_iface = tmp_dup_table->ifaces;
-         while(tmp_dup_iface)
-           {
-             if(ipequal(&tmp_dup_iface->addr, int_addr))
-               return 0;
-             
-             tmp_dup_iface = tmp_dup_iface->next;
-           }
-       }
-    }
-  
-
-  return 1;
-}
-
+#include "mid_set.h"
 
-/**
- *Delete and dequeue a duplicate entry
- *
- *@param entry the entry to delete
- *
- */
-void
-olsr_del_dup_entry(struct dup_entry *entry)
-{
-  struct dup_iface *tmp_iface, *del_iface;
+struct avl_tree duplicate_set;
 
-  tmp_iface = entry->ifaces;
-
-  /* Free interfaces */
-  while(tmp_iface)
-    {
-      del_iface = tmp_iface;
-      tmp_iface = tmp_iface->next;
-      free(del_iface);
-    }
-
-  /* Dequeue */
-  DEQUEUE_ELEM(entry);
-  free(entry);
+void olsr_init_duplicate_set(void) {
+  avl_init(&duplicate_set, olsr_cnf->ip_version == AF_INET ? &avl_comp_ipv4 : &avl_comp_ipv6);
 }
 
-
-
-void
-olsr_time_out_duplicate_table(void *foo __attribute__((unused)))
-{
-  int i;
-
-  for(i = 0; i < HASHSIZE; i++)
-    {      
-      struct dup_entry *tmp_dup_table;
-      tmp_dup_table = dup_set[i].next;
-
-      while(tmp_dup_table != &dup_set[i])
-       {
-         if(TIMED_OUT(tmp_dup_table->timer))
-           {
-             struct dup_entry *entry_to_delete = tmp_dup_table;
-#ifdef DEBUG
-#ifndef NODEBUG
-              struct ipaddr_str buf;
-#endif
-             OLSR_PRINTF(5, "DUP TIMEOUT[%s] s: %d\n", 
-                         olsr_ip_to_string(&buf, &tmp_dup_table->addr),
-                         tmp_dup_table->seqno);
-#endif
-             tmp_dup_table = tmp_dup_table->next;
-             olsr_del_dup_entry(entry_to_delete);
-           }
-         else
-           {
-             tmp_dup_table = tmp_dup_table->next;
-           }
-       }
-    }
+struct duplicate_entry *olsr_create_duplicate_entry(void *ip, olsr_u16_t seqnr) {
+  struct duplicate_entry *entry;
+  entry = olsr_malloc(sizeof(struct duplicate_entry), "New duplicate entry");
+  if (entry != NULL) {
+    memcpy (&entry->ip, ip, olsr_cnf->ip_version == AF_INET ? sizeof(entry->ip.v4) : sizeof(entry->ip.v6)); 
+    entry->seqnr = seqnr;
+    entry->too_low_counter = 0;
+    entry->avl.key = &entry->ip;
+  }
+  return entry;
 }
 
-
-int
-olsr_update_dup_entry(const union olsr_ip_addr *originator, 
-                     const olsr_u16_t seqno, 
-                     const union olsr_ip_addr *iface)
-{
-  olsr_u32_t hash;
-  struct dup_entry *tmp_dup_table;
-  struct dup_iface *new_iface;
-
-  /* Hash the senders address */
-  hash = HASHMASK & seqno;
-
-
-  /* Check for entry */
-  for(tmp_dup_table = dup_set[hash].next;
-      tmp_dup_table != &dup_set[hash];
-      tmp_dup_table = tmp_dup_table->next)
-    {
-      if(ipequal(&tmp_dup_table->addr, originator) &&
-        (tmp_dup_table->seqno == seqno))
-       {
-         break;
-       }
-    }
-
-  if(tmp_dup_table == &dup_set[hash])
-    /* Did not find entry - create it */
-    tmp_dup_table = olsr_add_dup_entry(originator, seqno);
+int olsr_shall_process_message(void *ip, olsr_u16_t seqnr) {
+  struct duplicate_entry *entry;
+  int diff;
+  void *mainIp;
   
-  /* 0 for now */
-  tmp_dup_table->forwarded = 0;
+  // get main address
+  mainIp = mid_lookup_main_addr(ip);
+  if (mainIp == NULL) {
+    mainIp = ip;
+  }
   
-  new_iface = olsr_malloc(sizeof(struct dup_iface), "New dup iface");
+  entry = (struct duplicate_entry *)avl_find(&duplicate_set, ip);
+  if (entry == NULL) {
+    entry = olsr_create_duplicate_entry(ip, seqnr);
+    if (entry != NULL) {
+      avl_insert(&duplicate_set, &entry->avl, 0);
+    }
+    return 1; // okay, we process this package
+  }
 
-  new_iface->addr = *iface;
-  new_iface->next = tmp_dup_table->ifaces;
-  tmp_dup_table->ifaces = new_iface;
+  diff = (int)seqnr - (int)(entry->seqnr);
   
-  /* Set timer */
-  tmp_dup_table->timer = GET_TIMESTAMP(DUP_HOLD_TIME*1000);
+  // overflow ?
+  if (diff > (1<<15)) {
+    diff -= (1<<16);
+  }
   
-  return 1;
-}
-
-int
-olsr_set_dup_forward(const union olsr_ip_addr *originator, 
-                    const olsr_u16_t seqno)
-{
-#if !defined(NODEBUG) && defined(DEBUG)
-  struct ipaddr_str buf;
-#endif
-  olsr_u32_t hash;
-  struct dup_entry *tmp_dup_table;
-
-  /* Hash the senders address */
-  hash = HASHMASK & seqno;
-
-  /* Check for entry */
-  for(tmp_dup_table = dup_set[hash].next;
-      tmp_dup_table != &dup_set[hash];
-      tmp_dup_table = tmp_dup_table->next)
-    {
-      if(ipequal(&tmp_dup_table->addr, originator) &&
-        (tmp_dup_table->seqno == seqno))
-       {
-         break;
-       }
+  if (diff < -31) {
+    entry->too_low_counter ++;
+    
+    // client did restart with a lower number ?
+    if (entry->too_low_counter > 16) {
+      entry->too_low_counter = 0;
+      entry->seqnr = seqnr;
+      entry->array = 1;
+      return 1;
     }
-
-  if(tmp_dup_table == &dup_set[hash])
-    /* Did not find entry !! */
     return 0;
+  }
   
-#ifdef DEBUG
-  OLSR_PRINTF(3, "Setting DUP %s/%d forwarded\n", olsr_ip_to_string(&buf, &tmp_dup_table->addr), seqno);
-#endif
-
-  /* Set forwarded */
-  tmp_dup_table->forwarded = 1;
-  
-  /* Set timer */
-  tmp_dup_table->timer = GET_TIMESTAMP(DUP_HOLD_TIME*1000);
-  
+  entry->too_low_counter = 0;
+  if (diff <= 0) {
+    olsr_u32_t bitmask = 1 << ((olsr_u32_t) (-diff));
+    
+    if ((entry->array & bitmask) != 0) {
+//      printf("blocked\n");
+      return 0;
+    }
+    entry->array |= bitmask;
+//    printf("processed\n");
+    return 1;
+  }
+  else if (diff < 32) {
+    entry->array <<= (olsr_u32_t)diff;
+  }
+  else {
+    entry->array = 0;
+  }
+  entry->array |= 1;
+  entry->seqnr = seqnr;
+//  printf("processed\n");
   return 1;
 }
 
-void
-olsr_print_duplicate_table(void)
-{
-  int i;
-
-  printf("\nDUP TABLE:\n");
-
-  for(i = 0; i < HASHSIZE; i++)
-    {      
-      struct dup_entry *tmp_dup_table = dup_set[i].next;
-      
-      //printf("Timeout %d %d\n", i, j);
-      while(tmp_dup_table != &dup_set[i])
-       {
-          struct ipaddr_str buf;
-          printf("[%s] s: %d\n", 
-                olsr_ip_to_string(&buf, &tmp_dup_table->addr),
-                tmp_dup_table->seqno);
-         tmp_dup_table = tmp_dup_table->next;
-       }
-    }
-  printf("\n");
-
+void olsr_print_duplicate_table(void) {
+  
 }
index 60dca28..2680275 100644 (file)
@@ -1,93 +1,20 @@
-/*
- * The olsr.org Optimized Link-State Routing daemon(olsrd)
- * Copyright (c) 2004, Andreas TÃ\83¸nnesen(andreto@olsr.org)
- * 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.
- *
- */
-
-#ifndef _OLSR_DUP_TABLE
-#define _OLSR_DUP_TABLE
-
-#include "olsr_types.h"
-
-#define UNKNOWN_MESSAGE 0
-
-struct dup_entry
-{
-  union olsr_ip_addr     addr;      /* IP address of originator */
-  olsr_u16_t             seqno;     /* Seqno of message */
-  olsr_u8_t              forwarded; /* If this message was forwarded or not */
-  clock_t                timer;            /* Holding time */
-  struct dup_iface       *ifaces;   /* Interfaces this message was recieved on */
-  struct dup_entry       *next;     /* Next entry */
-  struct dup_entry       *prev;     /* Prev entry */
+#ifndef DUPLICATE_SET_2_H_
+#define DUPLICATE_SET_2_H_
+
+#include "lq_avl.h"
+#include "olsr.h"
+
+struct duplicate_entry {
+  struct avl_node avl;
+  union olsr_ip_addr ip;
+  olsr_u16_t seqnr;
+  olsr_u16_t too_low_counter;
+  olsr_u32_t array;
 };
 
-struct dup_iface
-{
-  union olsr_ip_addr     addr;      /* Addess of the interface */
-  struct dup_iface       *next;     /* Next in line */
-};
-
-
-void
-olsr_init_duplicate_table(void);
-
-void
-olsr_time_out_duplicate_table(void *);
-
-int
-olsr_check_dup_table_proc(const union olsr_ip_addr *, const olsr_u16_t);
-
-int
-olsr_check_dup_table_fwd(const union olsr_ip_addr *, const olsr_u16_t, const union olsr_ip_addr *);
-
-void
-olsr_del_dup_entry(struct dup_entry *);
-
-void
-olsr_print_duplicate_table(void);
-
-int
-olsr_update_dup_entry(const union olsr_ip_addr *, const olsr_u16_t, const union olsr_ip_addr *);
-
-int
-olsr_set_dup_forward(const union olsr_ip_addr *, const olsr_u16_t);
-
-int
-olsr_check_dup_forward(union olsr_ip_addr *, olsr_u16_t);
+void olsr_init_duplicate_set(void);
+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
+#endif /*DUPLICATE_SET_2_H_*/
index 42dea71..bd175ca 100644 (file)
@@ -43,7 +43,7 @@
 
 #include "interfaces.h"
 
-#define STDOUT_PULSE_INT 0.6
+#define STDOUT_PULSE_INT 600 /* msec */
 
 /* Functions */
 
index 009dab0..d04e20e 100644 (file)
  * Hashing function. Creates a key based on
  * an 32-bit address.
  * @param address the address to hash
- * @return the hash(a value in the 0-31 range)
+ * @return the hash(a value in the (0 to HASHMASK-1) range)
  */
-olsr_u32_t olsr_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);
-    }
-    return hash & HASHMASK;
+  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);
+  }
+  return hash & HASHMASK;
 }
 
 /*
  * Local Variables:
- * mode: c
- * style: linux
- * c-basic-offset: 4
- * indent-tabs-mode: nil
+ * c-basic-offset: 2
  * End:
  */
index 2f90d94..0e2b238 100644 (file)
@@ -47,8 +47,6 @@
 
 #include "olsr_types.h"
 
-olsr_u32_t
-olsr_hashing(const union olsr_ip_addr *);
-
+olsr_u32_t olsr_ip_hashing(const union olsr_ip_addr *);
 
 #endif
index f3e0e4a..1dc0041 100644 (file)
@@ -56,11 +56,6 @@ olsr_init_hna_set(void)
 {
   int idx;
 
-  /* Since the holdingtime is assumed to be rather large for 
-   * HNA entries, the timeoutfunction is only ran once every second
-   */
-  olsr_register_scheduler_event_dijkstra(&olsr_time_out_hna_set, NULL, 1, 0, NULL);
-
   for(idx=0;idx<HASHSIZE;idx++)
     {
       hna_set[idx].next = &hna_set[idx];
@@ -105,7 +100,7 @@ struct hna_entry *
 olsr_lookup_hna_gw(const union olsr_ip_addr *gw)
 {
   struct hna_entry *tmp_hna;
-  olsr_u32_t hash = olsr_hashing(gw);
+  olsr_u32_t hash = olsr_ip_hashing(gw);
 
 #if 0
   OLSR_PRINTF(5, "HNA: lookup entry\n");
@@ -149,7 +144,7 @@ olsr_add_hna_entry(const union olsr_ip_addr *addr)
   new_entry->networks.prev = &new_entry->networks;
 
   /* queue */
-  hash = olsr_hashing(addr);
+  hash = olsr_ip_hashing(addr);
   
   hna_set[hash].next->prev = new_entry;
   new_entry->next = hna_set[hash].next;
@@ -183,6 +178,9 @@ olsr_add_hna_net(struct hna_entry *hna_gw, const union olsr_ip_addr *net, olsr_u
   new_net->A_network_addr = *net;
   new_net->prefixlen = prefixlen;
 
+  /* Set backpointer */
+  new_net->hna_gw = hna_gw;
+
   /* Queue */
   hna_gw->networks.next->prev = new_net;
   new_net->next = hna_gw->networks.next;
@@ -200,8 +198,43 @@ olsr_add_hna_net(struct hna_entry *hna_gw, const union olsr_ip_addr *net, olsr_u
   return new_net;
 }
 
+/**
+ * Callback for the hna_net timer.
+ */
+static void
+olsr_expire_hna_net_entry(void *context)
+{
+#if !defined(NODEBUG) && defined(DEBUG)
+  struct ipaddr_str buf1, buf2;
+#endif
+  struct hna_net *net_to_delete;
+  struct hna_entry *hna_gw;
+
+  net_to_delete = (struct hna_net *)context;
+  net_to_delete->hna_net_timer = NULL; /* be pedandic */
+  hna_gw = net_to_delete->hna_gw;
+
+#ifdef DEBUG
+  OLSR_PRINTF(5, "HNA: timeout %s/%u via hna-gw %s\n", 
+              olsr_ip_to_string(&buf1, &net_to_delete->A_network_addr),
+              net_to_delete->prefixlen,
+              olsr_ip_to_string(&buf2, &hna_gw->A_gateway_addr));
+#endif
+
+  /*
+   * Delete the rt_path for the entry.
+   */
+  olsr_delete_routing_table(&net_to_delete->A_network_addr,
+                            net_to_delete->prefixlen,
+                            &hna_gw->A_gateway_addr);
 
 
+  /* Delete hna_gw if empty */
+  if (hna_gw->networks.next == &hna_gw->networks) {
+    DEQUEUE_ELEM(hna_gw);
+    free(hna_gw);
+  }
+}
 
 /**
  * Update a HNA entry. If it does not exist it
@@ -217,95 +250,33 @@ olsr_add_hna_net(struct hna_entry *hna_gw, const union olsr_ip_addr *net, olsr_u
  *@return nada
  */
 void
-olsr_update_hna_entry(const union olsr_ip_addr *gw, const union olsr_ip_addr *net, olsr_u8_t prefixlen, const float vtime)
+olsr_update_hna_entry(const union olsr_ip_addr *gw, const union olsr_ip_addr *net,
+                      olsr_u8_t prefixlen, const float vtime)
 {
   struct hna_entry *gw_entry = olsr_lookup_hna_gw(gw);
   struct hna_net *net_entry;
 
   if (gw_entry == NULL) {
+
     /* Need to add the entry */
     gw_entry = olsr_add_hna_entry(gw);
   }
   net_entry = olsr_lookup_hna_net(&gw_entry->networks, net, prefixlen);
   if (net_entry == NULL)  {
+
     /* Need to add the net */
     net_entry = olsr_add_hna_net(gw_entry, net, prefixlen);
     changes_hna = OLSR_TRUE;
   }
 
-  /* Update holdingtime */
-  net_entry->A_time = GET_TIMESTAMP(vtime*1000);
+  olsr_set_timer(&net_entry->hna_net_timer, vtime * MSEC_PER_SEC,
+                 OLSR_HNA_NET_JITTER, OLSR_TIMER_ONESHOT,
+                 &olsr_expire_hna_net_entry, net_entry, 0);
 }
 
 
-
-
-
-
-/**
- *Function that times out all entrys in the hna set and
- *deletes the timed out ones.
- *
- *@return nada
- */
-void
-olsr_time_out_hna_set(void *foo __attribute__((unused)))
-{
-  int idx;
-
-  for(idx=0;idx<HASHSIZE;idx++)
-    {
-      struct hna_entry *tmp_hna = hna_set[idx].next;
-      /* Check all entrys */
-      while(tmp_hna != &hna_set[idx])
-       {
-         /* Check all networks */
-         struct hna_net *tmp_net = tmp_hna->networks.next;
-
-         while(tmp_net != &tmp_hna->networks)
-           {
-             if(TIMED_OUT(tmp_net->A_time))
-               {
-                 struct hna_net *net_to_delete = tmp_net;
-                 tmp_net = tmp_net->next;
-                 DEQUEUE_ELEM(net_to_delete);
-
-                  /*
-                   * Delete the rt_path for the entry.
-                   */
-                  olsr_delete_routing_table(&net_to_delete->A_network_addr,
-                                            net_to_delete->prefixlen,
-                                            &tmp_hna->A_gateway_addr);
-                 free(net_to_delete);
-                 changes_hna = OLSR_TRUE;
-               }
-             else
-               tmp_net = tmp_net->next;
-           }
-
-         /* Delete gw entry if empty */
-         if(tmp_hna->networks.next == &tmp_hna->networks)
-           {
-             struct hna_entry *hna_to_delete = tmp_hna;
-             tmp_hna = tmp_hna->next;
-
-             /* Dequeue */
-             DEQUEUE_ELEM(hna_to_delete);
-             /* Delete */
-             free(hna_to_delete);
-           }
-         else
-           tmp_hna = tmp_hna->next;
-       }
-    }
-
-}
-
-
-
 /**
- *Function that times out all entrys in the hna set and
- *deletes the timed out ones.
+ * Print all HNA entries.
  *
  *@return nada
  */
index a03bf6b..704956a 100644 (file)
@@ -53,11 +53,14 @@ struct hna_net
 {
   union olsr_ip_addr A_network_addr;
   olsr_u8_t          prefixlen;
-  clock_t            A_time;
+  struct timer_entry *hna_net_timer;
+  struct hna_entry   *hna_gw; /* backpointer to the owning HNA entry */
   struct hna_net     *next;
   struct hna_net     *prev;
 };
 
+#define OLSR_HNA_NET_JITTER 5 /* percent */
+
 struct hna_entry
 {
   union olsr_ip_addr A_gateway_addr;
@@ -95,3 +98,9 @@ void
 olsr_print_hna_set(void);
 
 #endif
+
+/*
+ * Local Variables:
+ * c-basic-offset: 2
+ * End:
+ */
index 698a149..50e0bce 100644 (file)
 #include "olsr.h"
 #include "net_olsr.h"
 #include "ipcalc.h"
+#include "scheduler.h"
 
-#ifdef USE_FPM
-#define hscaling ftofpm(olsr_cnf->hysteresis_param.scaling)
-#define hhigh    ftofpm(olsr_cnf->hysteresis_param.thr_high)
-#define hlow     ftofpm(olsr_cnf->hysteresis_param.thr_low)
-#else
 #define hscaling olsr_cnf->hysteresis_param.scaling
 #define hhigh    olsr_cnf->hysteresis_param.thr_high
 #define hlow     olsr_cnf->hysteresis_param.thr_low
-#endif
 
-#ifdef USE_FPM
-fpm
-olsr_hyst_calc_stability(fpm old_quality)
-{
-  return fpmadd(fpmmul(fpmsub(itofpm(1), hscaling), old_quality), hscaling);
-}
-#else
 float
 olsr_hyst_calc_stability(float old_quality)
 {
   return (((1 - hscaling) * old_quality) + hscaling);
 }
-#endif
 
 
 
-#ifdef USE_FPM
-fpm
-olsr_hyst_calc_instability(fpm old_quality)
-{
-  return fpmmul(fpmsub(itofpm(1), hscaling), old_quality);
-}
-#else
 float
 olsr_hyst_calc_instability(float old_quality)
 {
   return ((1 - hscaling) * old_quality);
 }
-#endif
 
 
 
 int
 olsr_process_hysteresis(struct link_entry *entry)
 {
-  clock_t tmp_timer;
-
   //printf("PROCESSING QUALITY: %f\n", entry->L_link_quality);
   if(entry->L_link_quality > hhigh)
     {
@@ -139,12 +116,8 @@ olsr_process_hysteresis(struct link_entry *entry)
        changes_neighborhood = OLSR_TRUE;
 
       /* Timer = min (L_time, current time + NEIGHB_HOLD_TIME) */
-      //tmp_timer = now;
-      //tmp_timer.tv_sec += NEIGHB_HOLD_TIME; /* Takafumi fix */
-      tmp_timer = now_times + get_hold_time_neighbor();
-
-       entry->L_LOST_LINK_time = 
-         entry->time > tmp_timer ? tmp_timer : entry->time;
+      entry->L_LOST_LINK_time = MIN(GET_TIMESTAMP(NEIGHB_HOLD_TIME * MSEC_PER_SEC),
+                                    entry->link_timer->timer_clock);
 
       /* (the link is then considered as lost according to section
         8.5 and this may produce a neighbor loss).
@@ -179,12 +152,11 @@ olsr_update_hysteresis_hello(struct link_entry *entry, double htime)
 #ifndef NODEBUG
   struct ipaddr_str buf;
 #endif
-  OLSR_PRINTF(3, "HYST[%s]: HELLO update vtime %f\n", olsr_ip_to_string(&buf, &entry->neighbor_iface_addr), htime*1.5);
-  /* hello timeout = current time + hint time */
-  /* SET TIMER TO 1.5 TIMES THE INTERVAL */
-  /* Update timer */
+  OLSR_PRINTF(3, "HYST[%s]: HELLO update vtime %f\n",
+              olsr_ip_to_string(&buf, &entry->neighbor_iface_addr), htime*1.5);
 
-  entry->hello_timeout = GET_TIMESTAMP(htime*1500);
+  olsr_set_timer(&entry->link_hello_timer, htime * 1500, OLSR_LINK_HELLO_JITTER,
+                 OLSR_TIMER_PERIODIC, &olsr_expire_link_hello_timer, entry, 0);
 
   return;
 }
@@ -204,7 +176,7 @@ update_hysteresis_incoming(union olsr_ip_addr *remote, struct interface *local,
 #endif
       lnk->L_link_quality = olsr_hyst_calc_stability(lnk->L_link_quality);
 #ifdef DEBUG
-      OLSR_PRINTF(3, "HYST[%s]: %s\n", olsr_ip_to_string(&buf, remote), olsr_etx_to_string(lnk->L_link_quality));
+      OLSR_PRINTF(3, "HYST[%s]: %f\n", olsr_ip_to_string(&buf, remote), lnk->L_link_quality);
 #endif
 
       /* 
@@ -220,14 +192,10 @@ update_hysteresis_incoming(union olsr_ip_addr *remote, struct interface *local,
            {
              lnk->L_link_quality = olsr_hyst_calc_instability(lnk->L_link_quality);
 #ifdef DEBUG
-             OLSR_PRINTF(5, "HYST[%s] PACKET LOSS! %s\n",
-                         olsr_ip_to_string(&buf, remote), olsr_etx_to_string(lnk->L_link_quality));
+             OLSR_PRINTF(5, "HYST[%s] PACKET LOSS! %f\n",
+                         olsr_ip_to_string(&buf, remote), lnk->L_link_quality);
 #endif
-#ifdef USE_FPM
-             if(lnk->L_link_quality < ftofpm(olsr_cnf->hysteresis_param.thr_low))
-#else
              if(lnk->L_link_quality < olsr_cnf->hysteresis_param.thr_low)
-#endif
                break;
 
              lnk->olsr_seqno++;
index 7ce66ab..f4eea6a 100644 (file)
 
 #include "link_set.h"
 
-#ifdef USE_FPM
-fpm
-olsr_hyst_calc_stability(fpm);
-#else
 float
 olsr_hyst_calc_stability
 (float);
-#endif
 
 int
 olsr_process_hysteresis(struct link_entry *);
 
-#ifdef USE_FPM
-fpm
-olsr_hyst_calc_instability(fpm);
-#else
 float
 olsr_hyst_calc_instability(float);
-#endif
 
 void
 olsr_update_hysteresis_hello(struct link_entry *, double);
index 76e8fcb..606980d 100644 (file)
@@ -71,26 +71,23 @@ ifinit(void)
 {
   struct olsr_if *tmp_if;
 
-
   /* Initial values */
   ifnet = NULL;
 
   OLSR_PRINTF(1, "\n ---- Interface configuration ---- \n\n");
-    /* Run trough all interfaces immedeatly */
-    for(tmp_if = olsr_cnf->interfaces; tmp_if != NULL; tmp_if = tmp_if->next)
-      {
-       if(!tmp_if->host_emul)
-         {
-           if(!olsr_cnf->host_emul) /* XXX: TEMPORARY! */
-             chk_if_up(tmp_if, 1);     
-         }
-       else
-         add_hemu_if(tmp_if);
-      }
+  /* Run trough all interfaces immedeatly */
+  for (tmp_if = olsr_cnf->interfaces; tmp_if != NULL; tmp_if = tmp_if->next) {
+    if (!tmp_if->host_emul) {
+      if (!olsr_cnf->host_emul) /* XXX: TEMPORARY! */
+        chk_if_up(tmp_if, 1);  
+    } else {
+      add_hemu_if(tmp_if);
+    }
+  }
   
-  /* register network interface update function with scheduler */
-  olsr_register_scheduler_event(&check_interface_updates, NULL, 
-                                olsr_cnf->nic_chgs_pollrate, 0, NULL);
+  /* Kick a periodic timer for the network interface update function */
+  olsr_start_timer((unsigned int)olsr_cnf->nic_chgs_pollrate * MSEC_PER_SEC, 5,
+                   OLSR_TIMER_PERIODIC, &check_interface_updates, NULL, 0);
 
   return (ifnet == NULL) ? 0 : 1;
 }
@@ -338,3 +335,9 @@ del_ifchgf(int (*f)(struct interface *, int))
 
   return 0;
 }
+
+/*
+ * Local Variables:
+ * c-basic-offset: 2
+ * End:
+ */
index ac9fca0..8ed76f1 100644 (file)
@@ -143,6 +143,13 @@ struct interface
   int           is_wireless;                    /* wireless interface or not*/
   char         *int_name;                      /* from kernel if structure */
   olsr_u16_t    olsr_seqnum;                    /* Olsr message seqno */
+
+  /* Periodic message generation timers */
+  struct timer_entry *hello_gen_timer;
+  struct timer_entry *hna_gen_timer;
+  struct timer_entry *mid_gen_timer;
+  struct timer_entry *tc_gen_timer;
+
 #ifdef linux
 /* Struct used to store original redirect/ingress setting */
   struct nic_state
@@ -211,3 +218,9 @@ int
 del_ifchgf(int (*f)(struct interface *, int));
 
 #endif
+
+/*
+ * Local Variables:
+ * c-basic-offset: 2
+ * End:
+ */
index befb577..7705554 100644 (file)
 #include "lq_route.h"
 #include "net_olsr.h"
 #include "ipcalc.h"
+#include "lq_plugin.h"
 
+/* head node for all link sets */
+struct list_node link_entry_head;
 
-static clock_t hold_time_neighbor;
-
-struct link_entry *link_set;
+olsr_bool link_changes; /* is set if changes occur in MPRS set */ 
 
+void
+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 void
-olsr_time_out_hysteresis(void);
-
-static void olsr_time_out_packet_loss(void);
-
 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 void
-olsr_time_out_link_set(void);
-
 static int
 get_neighbor_status(const union olsr_ip_addr *);
 
-
-clock_t 
-get_hold_time_neighbor(void)
-{
-  return hold_time_neighbor;
-}
-
-struct link_entry *
-get_link_set(void)
-{
-  return link_set;
-}
-
 void
 olsr_init_link_set(void)
 {
 
-  /* Timers */
-  hold_time_neighbor = (NEIGHB_HOLD_TIME*1000) / olsr_cnf->system_tick_divider;
-
-  olsr_register_timeout_function(&olsr_time_out_link_set, OLSR_TRUE);
-  if(olsr_cnf->use_hysteresis)
-    {
-      olsr_register_timeout_function(&olsr_time_out_hysteresis, OLSR_TRUE);
-    }
-
-  if (olsr_cnf->lq_level > 0)
-    {
-      olsr_register_timeout_function(&olsr_time_out_packet_loss, OLSR_TRUE);
-    }
+  /* Init list head */
+  list_head_init(&link_entry_head);
 }
 
 
-
 /**
  * Get the status of a link. The status is based upon different
  * timeouts in the link entry.
@@ -124,8 +97,9 @@ int
 lookup_link_status(const struct link_entry *entry)
 {
 
-  if(entry == NULL || link_set == NULL)
+  if(entry == NULL || list_is_empty(&link_entry_head)) {
     return UNSPEC_LINK;
+  }
 
   /*
    * Hysteresis
@@ -158,8 +132,9 @@ lookup_link_status(const struct link_entry *entry)
       */
     }
 
-  if(!TIMED_OUT(entry->SYM_time))
+  if (entry->link_sym_timer) {
     return SYM_LINK;
+  }
 
   if(!TIMED_OUT(entry->ASYM_time))
     return ASYM_LINK;
@@ -170,10 +145,6 @@ lookup_link_status(const struct link_entry *entry)
 }
 
 
-
-
-
-
 /**
  *Find the "best" link status to a
  *neighbor
@@ -241,11 +212,7 @@ 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;
   int curr_metric = MAX_IF_METRIC;
-#ifdef USE_FPM
-  fpm curr_lq = itofpm(-1);
-#else
-  float curr_lq = -1.0;
-#endif
+  olsr_linkcost curr_lcost = LINK_COST_BROKEN;
   
   // main address lookup
 
@@ -263,10 +230,9 @@ get_best_link_to_neighbor(const union olsr_ip_addr *remote)
 
   // loop through all links that we have
 
-  for (walker = link_set; walker != NULL; walker = walker->next)
-  {
-    // if this is not a link to the neighour in question, skip
+  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;
 
@@ -309,30 +275,21 @@ get_best_link_to_neighbor(const union olsr_ip_addr *remote)
 
     else
     {
-#ifdef USE_FPM
-      fpm tmp_lq;
-#else
-      float tmp_lq;
-#endif
+      olsr_linkcost tmp_lc;
 
-      // calculate the bi-directional link quality - we select the link
-      // with the best link quality
+      // get the link cost
 
-#ifdef USE_FPM
-      tmp_lq = fpmmul(walker->loss_link_quality, walker->neigh_link_quality);
-#else
-      tmp_lq = walker->loss_link_quality * walker->neigh_link_quality;
-#endif
+      tmp_lc = walker->linkcost; 
 
       // is this link better than anything we had before?
              
-      if((tmp_lq > curr_lq) ||
+      if((tmp_lc < curr_lcost) ||
          // use the requested remote interface address as a tie-breaker
-         ((tmp_lq == curr_lq) && ipequal(&walker->local_iface_addr, remote)))
+         ((tmp_lc == curr_lcost) && ipequal(&walker->local_iface_addr, remote)))
       {
         // memorize the link quality
 
-        curr_lq = tmp_lq;
+        curr_lcost = tmp_lc;
 
         // prefer symmetric links over asymmetric links
 
@@ -343,7 +300,7 @@ get_best_link_to_neighbor(const union olsr_ip_addr *remote)
           backup_link = walker;
       }
     }
-  }
+  } OLSR_FOR_ALL_LINK_ENTRIES_END(walker);
 
   // if we haven't found any symmetric links, try to return an
   // asymmetric link
@@ -356,11 +313,7 @@ static void set_loss_link_multiplier(struct link_entry *entry)
   struct interface *inter;
   struct olsr_if *cfg_inter;
   struct olsr_lq_mult *mult;
-#ifdef USE_FPM
-  fpm val = itofpm(-1);
-#else
   float val = -1.0;
-#endif
   union olsr_ip_addr null_addr;
 
   // find the interface for the link
@@ -385,95 +338,164 @@ static void set_loss_link_multiplier(struct link_entry *entry)
     // use the default multiplier only if there isn't any entry that
     // has a matching IP address
 
-#ifdef USE_FPM
-    if ((ipequal(&mult->addr, &null_addr) && val < itofpm(0)) ||
-#else
     if ((ipequal(&mult->addr, &null_addr) && val < 0.0) ||
-#endif
         ipequal(&mult->addr, &entry->neighbor_iface_addr))
-#ifdef USE_FPM
-      val = ftofpm(mult->val);
-#else
       val = mult->val;
-#endif
   }
 
   // if we have not found an entry, then use the default multiplier
 
-#ifdef USE_FPM
-  if (val < itofpm(0))
-    val = itofpm(1);
-#else
   if (val < 0)
     val = 1.0;
-#endif
 
   // store the multiplier
 
   entry->loss_link_multiplier = val;
 }
 
-/**
- *Delete all interface link entries
- *
- *@param interface ip address
+/*
+ * Delete, unlink and free a link entry.
  */
+static void
+olsr_delete_link_entry(struct link_entry *link)
+{
+
+  /* Delete neighbor entry */
+  if (link->neighbor->linkcount == 1) {
+    olsr_delete_neighbor_table(&link->neighbor->neighbor_main_addr);
+  } else {
+    link->neighbor->linkcount--;
+  }
+
+  /* Kill running timers */
+  olsr_stop_timer(link->link_timer);
+  link->link_timer = NULL;
+  olsr_stop_timer(link->link_sym_timer);
+  link->link_sym_timer = NULL;
+  olsr_stop_timer(link->link_hello_timer);
+  link->link_hello_timer = NULL;
+  olsr_stop_timer(link->link_loss_timer);
+  link->link_loss_timer = NULL;
+
+  list_remove(&link->link_list);
+
+  free(link->if_name);
+  free(link);
+
+  changes_neighborhood = OLSR_TRUE;
+}
 
 void
-del_if_link_entries(const union olsr_ip_addr *int_addr)
+olsr_delete_link_entry_by_ip(const union olsr_ip_addr *int_addr)
 {
-  struct link_entry *tmp_link_set, *last_link_entry;
+  struct link_entry *link;
 
-  if(link_set == NULL)
+  if (list_is_empty(&link_entry_head)) {
     return;
+  }
 
-  tmp_link_set = link_set;
-  last_link_entry = NULL;
+  OLSR_FOR_ALL_LINK_ENTRIES(link) {
+    if (ipequal(int_addr, &link->local_iface_addr)) {
+      olsr_delete_link_entry(link);
+    }
+  } OLSR_FOR_ALL_LINK_ENTRIES_END(link);
+}
 
-  while(tmp_link_set)
-    {
+/**
+ * Callback for the link loss timer.
+ */
+static void
+olsr_expire_link_loss_timer(void *context)
+{
+  struct link_entry *link;
+  
+  link = (struct link_entry *)context;
 
-      if(ipequal(int_addr, &tmp_link_set->local_iface_addr))
-        {
-          if(last_link_entry != NULL)
-            {
-              last_link_entry->next = tmp_link_set->next;
-
-              /* Delete neighbor entry */
-              if(tmp_link_set->neighbor->linkcount == 1)
-                olsr_delete_neighbor_table(&tmp_link_set->neighbor->neighbor_main_addr);
-              else
-                tmp_link_set->neighbor->linkcount--;
-
-              //olsr_delete_neighbor_if_no_link(&tmp_link_set->neighbor->neighbor_main_addr);
-              changes_neighborhood = OLSR_TRUE;
-
-              free(tmp_link_set);
-              tmp_link_set = last_link_entry;
-            }
-          else
-            {
-              link_set = tmp_link_set->next; /* CHANGED */
-
-              /* Delete neighbor entry */
-              if(tmp_link_set->neighbor->linkcount == 1)
-                olsr_delete_neighbor_table(&tmp_link_set->neighbor->neighbor_main_addr);
-              else
-                tmp_link_set->neighbor->linkcount--;
-
-              changes_neighborhood = OLSR_TRUE;
-
-              free(tmp_link_set);
-              tmp_link_set = link_set;
-              continue;
-            }
-        }
-
-      last_link_entry = tmp_link_set;
-      tmp_link_set = tmp_link_set->next;
-    }
+  /* count the lost packet */
+  olsr_update_packet_loss_worker(link, OLSR_TRUE);
+
+  /* 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);
+}
+
+/**
+ * Callback for the link SYM timer.
+ */
+static void
+olsr_expire_link_sym_timer(void *context)
+{
+  struct link_entry *link;
+
+  link = (struct link_entry *)context;
+  link->link_sym_timer = NULL; /* be pedandic */
+
+  if (link->prev_status != SYM_LINK) {
+    return;
+  } 
 
-  return;
+  link->prev_status = lookup_link_status(link);
+  update_neighbor_status(link->neighbor,
+                         get_neighbor_status(&link->neighbor_iface_addr));
+  changes_neighborhood = OLSR_TRUE;
+}
+
+/**
+ * Callback for the link_hello timer.
+ */
+void
+olsr_expire_link_hello_timer(void *context)
+{
+#ifndef NODEBUG
+  struct ipaddr_str buf;
+#endif
+  struct link_entry *link;
+
+  link = (struct link_entry *)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);
+
+  /* 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);
+
+  /* Update hysteresis values */
+  olsr_process_hysteresis(link);
+         
+  /* update neighbor status */
+  update_neighbor_status(link->neighbor,
+                         get_neighbor_status(&link->neighbor_iface_addr));
+
+  /* Update seqno - not mentioned in the RFC... kind of a hack.. */
+  link->olsr_seqno++;
+}
+
+/**
+ * Callback for the link timer.
+ */
+static void
+olsr_expire_link_entry(void *context)
+{
+  struct link_entry *link;
+
+  link = (struct link_entry *)context;
+  link->link_timer = NULL; /* be pedandic */
+
+  olsr_delete_link_entry(link);
+}
+
+/**
+ * Set the link expiration timer.
+ */
+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);
 }
 
 /**
@@ -502,6 +524,7 @@ add_link_entry(const union olsr_ip_addr *local,
   if (tmp_link_set) {
     return tmp_link_set;
   }
+
   /*
    * if there exists no link tuple with
    * L_neighbor_iface_addr == Source Address
@@ -518,9 +541,7 @@ add_link_entry(const union olsr_ip_addr *local,
 
   /* a new tuple is created with... */
 
-  new_link = olsr_malloc(sizeof(struct link_entry), "new link entry");
-
-  memset(new_link, 0 , sizeof(struct link_entry));
+  new_link = olsr_malloc_link_entry("new link entry");
   
   /* copy if_name, if it is defined */
   if (local_if->int_name)
@@ -542,11 +563,8 @@ add_link_entry(const union olsr_ip_addr *local,
   /* L_neighbor_iface_addr = Source Address */
   new_link->neighbor_iface_addr = *remote;
 
-  /* L_SYM_time            = current time - 1 (expired) */
-  new_link->SYM_time = now_times - 1;
-
   /* L_time = current time + validity time */
-  new_link->time = GET_TIMESTAMP(vtime*1000);
+  olsr_set_link_timer(new_link, vtime * MSEC_PER_SEC);
 
   new_link->prev_status = ASYM_LINK;
 
@@ -555,62 +573,29 @@ add_link_entry(const union olsr_ip_addr *local,
     {
       new_link->L_link_pending = 1;
       new_link->L_LOST_LINK_time = GET_TIMESTAMP(vtime*1000);
-      new_link->hello_timeout = GET_TIMESTAMP(htime*1500);
+      olsr_update_hysteresis_hello(new_link, htime);
       new_link->last_htime = htime;
       new_link->olsr_seqno = 0;
       new_link->olsr_seqno_valid = OLSR_FALSE;
     }
 
-#ifdef USE_FPM
-  new_link->L_link_quality = itofpm(0);
-#else
   new_link->L_link_quality = 0.0;
-#endif
 
   if (olsr_cnf->lq_level > 0)
     {
       new_link->loss_hello_int = htime;
 
-      new_link->loss_timeout = GET_TIMESTAMP(htime * 1500.0);
-
-      new_link->loss_seqno = 0;
-      new_link->loss_seqno_valid = 0;
-      new_link->loss_missed_hellos = 0;
-
-      new_link->lost_packets = 0;
-      new_link->total_packets = 0;
-
-      new_link->loss_index = 0;
-
-      memset(new_link->loss_bitmap, 0, sizeof (new_link->loss_bitmap));
+      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);
     }
 
-#ifdef USE_FPM
-  new_link->loss_link_quality = itofpm(0);
-  new_link->neigh_link_quality = itofpm(0);
-
-  new_link->loss_link_quality2 = itofpm(0);
-  new_link->neigh_link_quality2 = itofpm(0);
-
-  new_link->saved_loss_link_quality = itofpm(0);
-  new_link->saved_neigh_link_quality = itofpm(0);
-#else
-  new_link->loss_link_quality = 0.0;
-  new_link->neigh_link_quality = 0.0;
-
-  new_link->loss_link_quality2 = 0.0;
-  new_link->neigh_link_quality2 = 0.0;
-
-  new_link->saved_loss_link_quality = 0.0;
-  new_link->saved_neigh_link_quality = 0.0;
-#endif
+  new_link->linkcost = LINK_COST_BROKEN;
 
   /* Add to queue */
-  new_link->next = link_set;
-  link_set = new_link;
-
+  list_add_before(&link_entry_head, &new_link->link_list);
 
   /*
    * Create the neighbor entry
@@ -631,50 +616,27 @@ add_link_entry(const union olsr_ip_addr *local,
 
   neighbor->linkcount++;
   new_link->neighbor = neighbor;
-  if(!ipequal(remote, remote_main))
-    {
-      /* Add MID alias if not already registered */
-      /* This is kind of sketchy... and not specified
-       * in the RFC. We can only guess a vtime.
-       * We'll go for one that is hopefully long
-       * enough in most cases. 10 seconds
-       */
 
-    /* Erik Tromp - commented out. It is not RFC-compliant. Also, MID aliases
-     * that are not explicitly declared by a node will be removed as soon as
-     * the olsr_prune_aliases(...) function is called.
-     *
-     * OLSR_PRINTF(1, "Adding MID alias main %s ", olsr_ip_to_string(remote_main));
-     * OLSR_PRINTF(1, "-> %s based on HELLO\n\n", olsr_ip_to_string(remote));
-     * insert_mid_alias(remote_main, remote, MID_ALIAS_HACK_VTIME);
-     */
-    }
-
-  return link_set;
+  return new_link;
 }
 
 
 /**
- *Lookup the status of a link.
- *
- *@param int_addr address of the remote interface
+ * Lookup the status of a link.
  *
- *@return 1 of the link is symmertic 0 if not
+ * @param int_addr address of the remote interface
+ * @return 1 of the link is symmertic 0 if not
  */
-
 int
 check_neighbor_link(const union olsr_ip_addr *int_addr)
 {
-  struct link_entry *tmp_link_set;
+  struct link_entry *link;
 
-  tmp_link_set = link_set;
+  OLSR_FOR_ALL_LINK_ENTRIES(link) {
+    if (ipequal(int_addr, &link->neighbor_iface_addr))
+      return lookup_link_status(link);
+  } OLSR_FOR_ALL_LINK_ENTRIES_END(link);
 
-  while(tmp_link_set)
-    {
-      if(ipequal(int_addr, &tmp_link_set->neighbor_iface_addr))
-       return lookup_link_status(tmp_link_set);
-      tmp_link_set = tmp_link_set->next;
-    }
   return UNSPEC_LINK;
 }
 
@@ -689,27 +651,24 @@ check_neighbor_link(const union olsr_ip_addr *int_addr)
  *@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)
+lookup_link_entry(const union olsr_ip_addr *remote,
+                  const union olsr_ip_addr *remote_main,
+                  const struct interface *local)
 {
-  struct link_entry *tmp_link_set;
+  struct link_entry *link;
 
-  tmp_link_set = link_set;
+  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)) &&
 
-  while(tmp_link_set)
-    {
-      if(ipequal(remote, &tmp_link_set->neighbor_iface_addr) &&
-        (tmp_link_set->if_name
-          ? !strcmp(tmp_link_set->if_name, local->int_name)
-          : ipequal(&local->ip_addr, &tmp_link_set->local_iface_addr)
-          ) &&
-         /* check the remote-main address only if there is one given */
-         (remote_main == NULL || ipequal(remote_main, &tmp_link_set->neighbor->neighbor_main_addr))
-         )
-       return tmp_link_set;
-      tmp_link_set = tmp_link_set->next;
+       /* check the remote-main address only if there is one given */
+       (!remote_main || ipequal(remote_main, &link->neighbor->neighbor_main_addr))) {
+      return link;
     }
-  return NULL;
+  } OLSR_FOR_ALL_LINK_ENTRIES_END(link);
 
+  return NULL;
 }
 
 
@@ -755,26 +714,27 @@ update_link_entry(const union olsr_ip_addr *local,
   switch(entry->prev_status)
     {
     case(LOST_LINK):
-      /* L_SYM_time = current time - 1 (i.e., expired) */
-      entry->SYM_time = now_times - 1;
-
+      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 */
-      //printf("updating SYM time for %s\n", olsr_ip_to_string(remote));
-      entry->SYM_time = GET_TIMESTAMP(message->vtime*1000);
+      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 */
-      entry->time = entry->SYM_time + hold_time_neighbor;
-
+      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->time < entry->ASYM_time)
-    entry->time = 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));
+  }
 
 
   /*
@@ -809,29 +769,22 @@ int
 replace_neighbor_link_set(const struct neighbor_entry *old,
                          struct neighbor_entry *new)
 {
-  struct link_entry *tmp_link_set;
-  int retval;
-
-  retval = 0;
+  struct link_entry *link;
+  int retval = 0;
 
-  if(link_set == NULL)
+  if (list_is_empty(&link_entry_head)) {
     return retval;
+  }
       
-  tmp_link_set = link_set;
+  OLSR_FOR_ALL_LINK_ENTRIES(link) {
 
-  while(tmp_link_set)
-    {
-
-      if(tmp_link_set->neighbor == old)
-       {
-         tmp_link_set->neighbor = new;
-         retval++;
-       }
-      tmp_link_set = tmp_link_set->next;
+    if (link->neighbor == old) {
+      link->neighbor = new;
+      retval++;
     }
+  } OLSR_FOR_ALL_LINK_ENTRIES_END(link);
 
   return retval;
-
 }
 
 
@@ -871,133 +824,6 @@ check_link_status(const struct hello_message *message, const struct interface *i
   return ret;
 }
 
-
-/**
- *Time out the link set. In other words, the link
- *set is traversed and all non-valid entries are
- *deleted.
- *
- */
-static void
-olsr_time_out_link_set(void)
-{
-
-  struct link_entry *tmp_link_set, *last_link_entry;
-
-  if(link_set == NULL)
-    return;
-      
-  tmp_link_set = link_set;
-  last_link_entry = NULL;
-
-  while(tmp_link_set)
-    {
-
-      if(TIMED_OUT(tmp_link_set->time))
-       {
-         if(last_link_entry != NULL)
-           {
-             last_link_entry->next = tmp_link_set->next;
-
-             /* Delete neighbor entry */
-             if(tmp_link_set->neighbor->linkcount == 1)
-               olsr_delete_neighbor_table(&tmp_link_set->neighbor->neighbor_main_addr);
-             else
-               tmp_link_set->neighbor->linkcount--;
-
-             //olsr_delete_neighbor_if_no_link(&tmp_link_set->neighbor->neighbor_main_addr);
-             changes_neighborhood = OLSR_TRUE;
-             free(tmp_link_set->if_name);
-             free(tmp_link_set);
-             tmp_link_set = last_link_entry;
-           }
-         else
-           {
-             link_set = tmp_link_set->next; /* CHANGED */
-
-             /* Delete neighbor entry */
-             if(tmp_link_set->neighbor->linkcount == 1)
-               olsr_delete_neighbor_table(&tmp_link_set->neighbor->neighbor_main_addr);
-             else
-               tmp_link_set->neighbor->linkcount--;
-
-             changes_neighborhood = OLSR_TRUE;
-
-             free(tmp_link_set->if_name);
-             free(tmp_link_set);
-             tmp_link_set = link_set;
-             continue;
-           }       
-       }
-      else if((tmp_link_set->prev_status == SYM_LINK) &&
-             TIMED_OUT(tmp_link_set->SYM_time))
-       {
-         tmp_link_set->prev_status = lookup_link_status(tmp_link_set);
-         update_neighbor_status(tmp_link_set->neighbor, 
-                                get_neighbor_status(&tmp_link_set->neighbor_iface_addr));
-         changes_neighborhood = OLSR_TRUE;
-       }
-      
-      last_link_entry = tmp_link_set;
-      tmp_link_set = tmp_link_set->next;
-    }
-
-  return;
-}
-
-
-
-
-/**
- *Updates links that we have not received
- *HELLO from in expected time according to 
- *hysteresis.
- *
- *@return nada
- */
-static void
-olsr_time_out_hysteresis(void)
-{
-  struct link_entry *tmp_link_set;
-
-  if(link_set == NULL)
-    return;
-
-  tmp_link_set = link_set;
-
-  while(tmp_link_set)
-    {
-      if(TIMED_OUT(tmp_link_set->hello_timeout))
-       {
-#ifndef NODEBUG
-          struct ipaddr_str buf;
-#endif
-         tmp_link_set->L_link_quality = olsr_hyst_calc_instability(tmp_link_set->L_link_quality);
-         OLSR_PRINTF(1, "HYST[%s] HELLO timeout %s\n",
-                      olsr_ip_to_string(&buf, &tmp_link_set->neighbor_iface_addr),
-                      olsr_etx_to_string(tmp_link_set->L_link_quality));
-         /* Update hello_timeout - NO SLACK THIS TIME */
-         tmp_link_set->hello_timeout = GET_TIMESTAMP(tmp_link_set->last_htime*1000);
-         /* Recalculate status */
-         /* Update hysteresis values */
-         olsr_process_hysteresis(tmp_link_set);
-         
-         /* update neighbor status */
-
-
-         /* Update neighbor */
-         update_neighbor_status(tmp_link_set->neighbor, 
-                                get_neighbor_status(&tmp_link_set->neighbor_iface_addr));
-
-         /* Update seqno - not mentioned in the RFC... kind of a hack.. */
-         tmp_link_set->olsr_seqno++;
-       }
-      tmp_link_set = tmp_link_set->next;
-    }
-
-  return;
-}
-
 void olsr_print_link_set(void)
 {
 #ifndef NODEBUG
@@ -1005,166 +831,23 @@ void olsr_print_link_set(void)
   struct link_entry *walker;
   const int addrsize = olsr_cnf->ip_version == AF_INET ? 15 : 39;
 
-  OLSR_PRINTF(0, "\n--- %02d:%02d:%02d.%02d ---------------------------------------------------- LINKS\n\n",
-              nowtm->tm_hour,
-              nowtm->tm_min,
-              nowtm->tm_sec,
-              (int)now.tv_usec/10000U);
-  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 %-6s %-6s %-6s %-6s %s\n", addrsize,
+              "IP address", "hyst", "LQ", "lost", "total","NLQ", "ETX");
 
-  for (walker = link_set; walker != NULL; walker = walker->next)
-  {
-    struct ipaddr_str buf;
-#ifdef USE_FPM
-    fpm etx;
+  OLSR_FOR_ALL_LINK_ENTRIES(walker) {
 
-    if (walker->loss_link_quality < MIN_LINK_QUALITY || walker->neigh_link_quality < MIN_LINK_QUALITY)
-      etx = itofpm(0);
-    else
-      etx = fpmdiv(itofpm(1), fpmmul(walker->loss_link_quality, walker->neigh_link_quality));
-#else
-    float etx;
-
-    if (walker->loss_link_quality < MIN_LINK_QUALITY || walker->neigh_link_quality < MIN_LINK_QUALITY)
-      etx = 0.0;
-    else
-      etx = 1.0 / (walker->loss_link_quality * walker->neigh_link_quality);
-#endif
-
-    OLSR_PRINTF(1, "%-*s  %s  %s  %-3d    %-3d    %s  %s\n",
+    struct ipaddr_str buf;
+    OLSR_PRINTF(1, "%-*s  %5.3f  %-13s %s\n",
                 addrsize, olsr_ip_to_string(&buf, &walker->neighbor_iface_addr),
-                olsr_etx_to_string(walker->L_link_quality),
-                olsr_etx_to_string(walker->loss_link_quality),
-               walker->lost_packets,
-                walker->total_packets,
-               olsr_etx_to_string(walker->neigh_link_quality),
-                olsr_etx_to_string(etx));
-  }
+                walker->L_link_quality,
+                get_link_entry_text(walker),
+                get_linkcost_text(walker->linkcost, OLSR_FALSE));
+  } OLSR_FOR_ALL_LINK_ENTRIES_END(walker);
 #endif
 }
 
-static void update_packet_loss_worker(struct link_entry *entry, int lost)
-{
-  unsigned char mask = 1 << (entry->loss_index & 7);
-  const int idx = entry->loss_index >> 3;
-#ifdef USE_FPM
-  fpm rel_lq, saved_lq;
-#else
-  double rel_lq, saved_lq;
-#endif
-
-  if (lost == 0)
-    {
-      // packet not lost
-
-      if ((entry->loss_bitmap[idx] & mask) != 0)
-        {
-          // but the packet that we replace was lost
-          // => decrement packet loss
-
-          entry->loss_bitmap[idx] &= ~mask;
-          entry->lost_packets--;
-        }
-    }
-
-  else
-    {
-      // packet lost
-
-      if ((entry->loss_bitmap[idx] & mask) == 0)
-        {
-          // but the packet that we replace was not lost
-          // => increment packet loss
-
-          entry->loss_bitmap[idx] |= mask;
-          entry->lost_packets++;
-        }
-    }
-
-  // move to the next packet
-
-  entry->loss_index++;
-
-  // wrap around at the end of the packet loss window
-
-  if (entry->loss_index >= olsr_cnf->lq_wsize)
-    entry->loss_index = 0;
-
-  // count the total number of handled packets up to the window size
-
-  if (entry->total_packets < olsr_cnf->lq_wsize)
-    entry->total_packets++;
-
-  // the current reference link quality
-
-  saved_lq = entry->saved_loss_link_quality;
-
-#ifdef USE_FPM
-  if (saved_lq == itofpm(0))
-    saved_lq = itofpm(-1);
-#else
-  if (saved_lq == 0.0)
-    saved_lq = -1.0;
-#endif
-
-  // calculate the new link quality
-  //
-  // start slowly: receive the first packet => link quality = 1 / n
-  //               (n = window size)
-#ifdef USE_FPM
-  entry->loss_link_quality = fpmdiv(
-    itofpm(entry->total_packets - entry->lost_packets),
-    olsr_cnf->lq_wsize < (2 * 4) ? itofpm(olsr_cnf->lq_wsize):
-    fpmidiv(fpmimul(4,fpmadd(fpmmuli(fpmsub(fpmidiv(itofpm(olsr_cnf->lq_wsize),4),
-                                            itofpm(1)),(int)entry->total_packets),
-                             itofpm(olsr_cnf->lq_wsize))),
-            (olsr_32_t)olsr_cnf->lq_wsize));
-#else
-  entry->loss_link_quality =
-    (float)(entry->total_packets - entry->lost_packets) /
-    (float)(olsr_cnf->lq_wsize < (2 * 4) ? olsr_cnf->lq_wsize: 
-    4 * (((float)olsr_cnf->lq_wsize / 4 - 1) * entry->total_packets + olsr_cnf->lq_wsize) / olsr_cnf->lq_wsize);
-#endif
-    
-  // multiply the calculated link quality with the user-specified multiplier
-
-#ifdef USE_FPM
-  entry->loss_link_quality = fpmmul(entry->loss_link_quality, entry->loss_link_multiplier);
-#else
-  entry->loss_link_quality *= entry->loss_link_multiplier;
-#endif
-
-  // if the link quality has changed by more than 10 percent,
-  // print the new link quality table
-
-#ifdef USE_FPM
-  rel_lq = fpmdiv(entry->loss_link_quality, saved_lq);
-#else
-  rel_lq = entry->loss_link_quality / saved_lq;
-#endif
-
-  if (rel_lq > CEIL_LQDIFF || rel_lq < FLOOR_LQDIFF)
-    {
-      entry->saved_loss_link_quality = entry->loss_link_quality;
-
-      if (olsr_cnf->lq_dlimit > 0)
-      {
-        changes_neighborhood = OLSR_TRUE;
-        changes_topology = OLSR_TRUE;
-      }
-
-      else
-        OLSR_PRINTF(3, "Skipping Dijkstra (1)\n");
-
-      // create a new ANSN
-
-      // XXX - we should check whether we actually
-      // announce this neighbour
-
-      signal_link_changes(OLSR_TRUE);
-    }
-}
-
 void olsr_update_packet_loss_hello_int(struct link_entry *entry,
                                        double loss_hello_int)
 {
@@ -1174,119 +857,19 @@ void olsr_update_packet_loss_hello_int(struct link_entry *entry,
   entry->loss_hello_int = loss_hello_int;
 }
 
-void olsr_update_packet_loss(const union olsr_ip_addr *rem, const struct interface *loc,
-                             olsr_u16_t seqno)
+void olsr_update_packet_loss(struct link_entry *entry)
 {
-  struct link_entry *entry;
-
-  // called for every OLSR packet
-
-  entry = lookup_link_entry(rem, NULL, loc);
-
-  // it's the very first LQ HELLO message - we do not yet have a link
-
-  if (entry == NULL)
-    return;
-    
-  // a) have we seen a packet before, i.e. is the sequence number valid?
-
-  // b) heuristically detect a restart (= sequence number reset)
-  //    of our neighbor
-
-  if (entry->loss_seqno_valid != 0 && 
-      (unsigned short)(seqno - entry->loss_seqno) < 100)
-    {
-      // loop through all lost packets
-
-      while (entry->loss_seqno != seqno)
-        {
-          // have we already considered all lost LQ HELLO messages?
-
-          if (entry->loss_missed_hellos == 0)
-            update_packet_loss_worker(entry, 1);
-
-          // if not, then decrement the number of lost LQ HELLOs
-
-          else
-            entry->loss_missed_hellos--;
-
-          entry->loss_seqno++;
-        }
-    }
-
-  // we have received a packet, otherwise this function would not
-  // have been called
-
-  update_packet_loss_worker(entry, 0);
-
-  // (re-)initialize
-
-  entry->loss_missed_hellos = 0;
-  entry->loss_seqno = seqno + 1;
-
-  // we now have a valid serial number for sure
-
-  entry->loss_seqno_valid = 1;
+  olsr_update_packet_loss_worker(entry, OLSR_FALSE);
 
   // timeout for the first lost packet is 1.5 x htime
 
-  entry->loss_timeout = GET_TIMESTAMP(entry->loss_hello_int * 1500.0);
-}
-
-static void olsr_time_out_packet_loss(void)
-{
-  struct link_entry *walker;
-
-  // loop through all links
-
-  for (walker = link_set; walker != NULL; walker = walker->next)
-    {
-      // find a link that has not seen any packets for a very long
-      // time (first time: 1.5 x htime, subsequently: 1.0 x htime)
-
-      if (!TIMED_OUT(walker->loss_timeout))
-        continue;
-      
-      // count the lost packet
-
-      update_packet_loss_worker(walker, 1);
-
-      // memorize that we've counted the packet, so that we do not
-      // count it a second time later
-
-      walker->loss_missed_hellos++;
-
-      // next timeout in 1.0 x htime
-
-      walker->loss_timeout = GET_TIMESTAMP(walker->loss_hello_int * 1000.0);
-    }
-}
-
-void olsr_update_dijkstra_link_qualities(void)
-{
-  struct link_entry *walker;
-
-  for (walker = link_set; walker != NULL; walker = walker->next)
-  {
-    walker->loss_link_quality2 = walker->loss_link_quality;
-    walker->neigh_link_quality2 = walker->neigh_link_quality;
-  }
+  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);
 }
 
-#ifdef USE_FPM
-fpm
-#else
-float
-#endif
-olsr_calc_link_etx(const struct link_entry *link)
-{
-  return link->loss_link_quality < MIN_LINK_QUALITY ||
-         link->neigh_link_quality < MIN_LINK_QUALITY
-#ifdef USE_FPM
-             ? itofpm(0)
-             : fpmdiv(itofpm(1), fpmmul(link->loss_link_quality, link->neigh_link_quality));
-#else
-             ? 0.0
-             : 1.0 / (link->loss_link_quality * link->neigh_link_quality);
-#endif
-}
+/*
+ * Local Variables:
+ * c-basic-offset: 2
+ * End:
+ */
index d7034ac..a589dbf 100644 (file)
@@ -46,7 +46,9 @@
 #ifndef _LINK_SET_H
 #define _LINK_SET_H
 
+#include "lq_plugin.h"
 #include "packet.h"
+#include "lq_list.h"
 
 #define MID_ALIAS_HACK_VTIME  10.0
 
@@ -56,9 +58,9 @@ struct link_entry
   union olsr_ip_addr neighbor_iface_addr;
   const struct interface *inter;
   char *if_name;
-  clock_t SYM_time;
+  struct timer_entry *link_timer;
+  struct timer_entry *link_sym_timer;
   clock_t ASYM_time;
-  clock_t time;
   unsigned int vtime;
   struct neighbor_entry *neighbor;
   olsr_u8_t prev_status;
@@ -66,14 +68,10 @@ struct link_entry
   /*
    *Hysteresis
    */
-#ifdef USE_FPM
-  fpm L_link_quality;
-#else
   float L_link_quality;
-#endif
   int L_link_pending;
   clock_t L_LOST_LINK_time;
-  clock_t hello_timeout; /* 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;
@@ -81,62 +79,50 @@ struct link_entry
   /*
    * packet loss
    */
-  olsr_u16_t loss_seqno;
-  int loss_seqno_valid;
-  int loss_missed_hellos;
-
   double loss_hello_int;
-  clock_t loss_timeout;
-
-  unsigned int lost_packets;
-  unsigned int total_packets;
-
-#ifdef USE_FPM
-  fpm loss_link_quality;
-  fpm loss_link_quality2;
-  fpm loss_link_multiplier;
-#else
-  double loss_link_quality;
-  double loss_link_quality2;
-  double loss_link_multiplier;
-#endif
-
-  unsigned int loss_index;
+  struct timer_entry *link_loss_timer;
 
-  unsigned char loss_bitmap[16];
-
-#ifdef USE_FPM
-  fpm neigh_link_quality, neigh_link_quality2;
-
-  fpm saved_loss_link_quality;
-  fpm saved_neigh_link_quality;
-#else
-  double neigh_link_quality, neigh_link_quality2;
-
-  double saved_loss_link_quality;
-  double saved_neigh_link_quality;
-#endif
+  float loss_link_multiplier; // user defined multiplies for link quality
+  
+  // cost of this link
+  olsr_linkcost linkcost;
 
-  struct link_entry *next;
+  struct list_node link_list; /* double linked list of all link entries */
+  char                  linkquality[0];
 };
 
-
-extern struct link_entry *link_set;
-
+/* 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 */
+
+/* deletion safe macro for link entry traversal */
+#define OLSR_FOR_ALL_LINK_ENTRIES(link) \
+{ \
+  struct list_node *link_head_node, *link_node, *next_link_node; \
+  link_head_node = &link_entry_head; \
+  for (link_node = link_head_node->next; \
+    link_node != link_head_node; link_node = next_link_node) { \
+    next_link_node = link_node->next; \
+    link = list2link(link_node);
+#define OLSR_FOR_ALL_LINK_ENTRIES_END(link) }}
+
+/* Externals */
+extern struct list_node link_entry_head;
+extern olsr_bool link_changes;
 
 /* Function prototypes */
 
-struct link_entry *
-get_link_set(void);
-
-clock_t 
-get_hold_time_neighbor(void);
+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 */
 
-void
-olsr_init_link_set(void);
-
-void
-del_if_link_entries(const union olsr_ip_addr *);
 
 struct link_entry *
 get_best_link_to_neighbor(const union olsr_ip_addr *);
@@ -161,21 +147,11 @@ void
 olsr_update_packet_loss_hello_int(struct link_entry *, double);
 
 void 
-olsr_update_packet_loss(const union olsr_ip_addr *, const struct interface *, olsr_u16_t);
+olsr_update_packet_loss(struct link_entry *entry);
 
 void 
 olsr_print_link_set(void);
 
-void
-olsr_update_dijkstra_link_qualities(void);
-
-#ifdef USE_FPM
-fpm
-#else
-float
-#endif
-olsr_calc_link_etx(const struct link_entry *);
-
 #endif
 
 /*
index 75cf408..2035d2d 100644 (file)
@@ -149,6 +149,8 @@ apm_printinfo(struct olsr_apm_info *ainfo)
              ainfo->ac_line_status,
              ainfo->battery_percentage,
              ainfo->battery_time_left);
+
+  ainfo = NULL; /* squelch compiler warnings */
 }
 
 
index 8659bb2..ddc95b1 100644 (file)
@@ -71,7 +71,7 @@ add_spy_node(union olsr_ip_addr *, char *);
 #define        MAXIPLEN        60
 #define        MAXICMPLEN      76
 
-float poll_int = 0.2;
+float poll_int = 200; /* msec */
 
 int
 iw_get_range_info(char *, struct iw_range *);
@@ -100,7 +100,7 @@ init_link_layer_notification()
        clear_spy_list(ifd->int_name);
     }
 
-  olsr_register_scheduler_event(&poll_link_layer, NULL, poll_int, 0, NULL);
+  olsr_start_timer(poll_int, 0, OLSR_TIMER_PERIODIC, &poll_link_layer, NULL, 0);
 
   return;
 }
index ac0c921..d048eb5 100644 (file)
@@ -42,6 +42,8 @@
 #ifndef _LQ_LIST_H
 #define _LQ_LIST_H
 
+#include "stddef.h"
+
 struct list_node
 {
   struct list_node *next;
@@ -59,5 +61,18 @@ void list_add_after(struct list_node *, struct list_node *);
 
 void list_remove(struct list_node *);
 
+/*
+ * Macro to define an inline function to map from a list_node offset back to the
+ * base of the datastructure. This saves you from populating the data field.
+ */
+#define LISTNODE2STRUCT(funcname, structname, listnodename) \
+static inline structname * funcname (struct list_node *ptr)\
+{\
+  return( \
+    ptr ? \
+      (structname *) (((olsr_u8_t *) ptr) - offsetof(structname, listnodename)) : \
+      NULL); \
+}
+
 #endif
 
index ce30d4f..8423d57 100644 (file)
@@ -44,6 +44,7 @@
 #include "link_set.h"
 #include "lq_mpr.h"
 #include "scheduler.h"
+#include "lq_plugin.h"
 
 void olsr_calculate_lq_mpr(void)
 {
@@ -51,40 +52,33 @@ void olsr_calculate_lq_mpr(void)
   struct neighbor_list_entry *walker;
   int i, k;
   struct neighbor_entry *neigh;
-#ifdef USE_FPM
-  fpm best, best_1hop;
-#else
-  double best, best_1hop;
-#endif
+  olsr_linkcost best, best_1hop;
   olsr_bool mpr_changes = OLSR_FALSE;
 
-  for(i = 0; i < HASHSIZE; i++)
-    {
-      for (neigh = neighbortable[i].next;
-           neigh != &neighbortable[i];
-           neigh = neigh->next)
-        { 
-          // memorize previous MPR status
+  OLSR_FOR_ALL_NBR_ENTRIES(neigh) {
 
-          neigh->was_mpr = neigh->is_mpr;
+    /* Memorize previous MPR status. */
 
-          // clear current MPR status
+    neigh->was_mpr = neigh->is_mpr;
 
-          neigh->is_mpr = OLSR_FALSE;
+    /* Clear current MPR status. */
 
-          // in this pass we are only interested in WILL_ALWAYS neighbours
+    neigh->is_mpr = OLSR_FALSE;
 
-          if(neigh->status == NOT_SYM ||
-             neigh->willingness != WILL_ALWAYS)
-            continue;
+    /* In this pass we are only interested in WILL_ALWAYS neighbours */
 
-          neigh->is_mpr = OLSR_TRUE;
+    if (neigh->status == NOT_SYM || neigh->willingness != WILL_ALWAYS) {
+      continue;
+    }
 
-          if (neigh->is_mpr != neigh->was_mpr)
-            mpr_changes = OLSR_TRUE;
-        }
+    neigh->is_mpr = OLSR_TRUE;
+
+    if (neigh->is_mpr != neigh->was_mpr) {
+      mpr_changes = OLSR_TRUE;
     }
 
+  } OLSR_FOR_ALL_NBR_ENTRIES_END(neigh);
+
   for(i = 0; i < HASHSIZE; i++)
     {
       // loop through all 2-hop neighbours
@@ -93,11 +87,7 @@ void olsr_calculate_lq_mpr(void)
            neigh2 != &two_hop_neighbortable[i];
            neigh2 = neigh2->next)
         {
-#ifdef USE_FPM
-          best_1hop = itofpm(-1);
-#else
-          best_1hop = -1.0;
-#endif
+          best_1hop = LINK_COST_BROKEN;
 
           // check whether this 2-hop neighbour is also a neighbour
 
@@ -119,18 +109,14 @@ void olsr_calculate_lq_mpr(void)
              if (!lnk)
                continue;
 
-#ifdef USE_FPM
-              best_1hop = fpmmul(lnk->loss_link_quality, lnk->neigh_link_quality);
-#else
-              best_1hop = lnk->loss_link_quality * lnk->neigh_link_quality;
-#endif
+              best_1hop = lnk->linkcost;
 
               // see wether we find a better route via an MPR
 
               for (walker = neigh2->neighbor_2_nblist.next;
                    walker != &neigh2->neighbor_2_nblist;
                    walker = walker->next)
-                if (walker->path_link_quality > best_1hop)
+                if (walker->path_linkcost < best_1hop)
                   break;
 
               // we've reached the end of the list, so we haven't found
@@ -157,27 +143,23 @@ void olsr_calculate_lq_mpr(void)
               // yet selected
 
               neigh = NULL;
-#ifdef USE_FPM
-              best = itofpm(-1);
-#else
-              best = -1.0;
-#endif
+              best = LINK_COST_BROKEN;
 
               for (walker = neigh2->neighbor_2_nblist.next;
                    walker != &neigh2->neighbor_2_nblist;
                    walker = walker->next)
                 if (walker->neighbor->status == SYM &&
                     !walker->neighbor->skip &&
-                    walker->path_link_quality > best)
+                    walker->path_linkcost < best)
                   {
                     neigh = walker->neighbor;
-                    best = walker->path_link_quality;
+                    best = walker->path_linkcost;
                   }
 
               // Found a 1-hop neighbor that we haven't previously selected.
               // Use it as MPR only when the 2-hop path through it is better than
               // any existing 1-hop path.
-              if ((neigh != NULL) && (best > best_1hop))
+              if ((neigh != NULL) && (best < best_1hop))
                 {
                   neigh->is_mpr = OLSR_TRUE;
                   neigh->skip = OLSR_TRUE;
@@ -198,3 +180,9 @@ void olsr_calculate_lq_mpr(void)
   if (mpr_changes && olsr_cnf->tc_redundancy > 0)
     signal_link_changes(OLSR_TRUE);
 }
+
+/*
+ * Local Variables:
+ * c-basic-offset: 2
+ * End:
+ */
index 3e39300..499b628 100644 (file)
@@ -56,7 +56,7 @@
 #include "olsr.h"
 #include "build_msg.h"
 #include "net_olsr.h"
-
+#include "lq_plugin.h"
 
 olsr_bool lq_tc_pending = OLSR_FALSE;
 
@@ -86,50 +86,49 @@ create_lq_hello(struct lq_hello_message *lq_hello, struct interface *outif)
   
   // loop through the link set
 
-  for (walker = get_link_set(); walker != NULL; walker = walker->next)
-    {
-      // allocate a neighbour entry
-      struct lq_hello_neighbor *neigh = olsr_malloc(sizeof (struct lq_hello_neighbor), "Build LQ_HELLO");
+  OLSR_FOR_ALL_LINK_ENTRIES(walker) {
 
-      // a) this neighbor interface IS NOT visible via the output interface
-      if(!ipequal(&walker->local_iface_addr, &outif->ip_addr))
-        neigh->link_type = UNSPEC_LINK;
-      
-      // b) this neighbor interface IS visible via the output interface
+    // allocate a neighbour entry
+    struct lq_hello_neighbor *neigh = olsr_malloc_lq_hello_neighbor("Build LQ_HELLO");
 
-      else
-        neigh->link_type = lookup_link_status(walker);
+    // a) this neighbor interface IS NOT visible via the output interface
+    if(!ipequal(&walker->local_iface_addr, &outif->ip_addr))
+      neigh->link_type = UNSPEC_LINK;
+      
+    // b) this neighbor interface IS visible via the output interface
 
-      // set the entry's link quality
+    else
+      neigh->link_type = lookup_link_status(walker);
 
-      neigh->link_quality = walker->loss_link_quality;
-      neigh->neigh_link_quality = walker->neigh_link_quality;
+    // set the entry's link quality
+    olsr_copy_hello_lq(neigh, walker);
 
-      // set the entry's neighbour type
+    // set the entry's neighbour type
 
-      if(walker->neighbor->is_mpr)
-        neigh->neigh_type = MPR_NEIGH;
+    if(walker->neighbor->is_mpr)
+      neigh->neigh_type = MPR_NEIGH;
 
-      else if (walker->neighbor->status == SYM)
-        neigh->neigh_type = SYM_NEIGH;
+    else if (walker->neighbor->status == SYM)
+      neigh->neigh_type = SYM_NEIGH;
 
-      else if (walker->neighbor->status == NOT_SYM)
-        neigh->neigh_type = NOT_NEIGH;
+    else if (walker->neighbor->status == NOT_SYM)
+      neigh->neigh_type = NOT_NEIGH;
         
-      else {
-        OLSR_PRINTF(0, "Error: neigh_type undefined");
-        neigh->neigh_type = NOT_NEIGH;
-      }
+    else {
+      OLSR_PRINTF(0, "Error: neigh_type undefined");
+      neigh->neigh_type = NOT_NEIGH;
+    }
   
-      // set the entry's neighbour interface address
+    // set the entry's neighbour interface address
 
-      neigh->addr = walker->neighbor_iface_addr;
+    neigh->addr = walker->neighbor_iface_addr;
       
-      // queue the neighbour entry
+    // queue the neighbour entry
 
-      neigh->next = lq_hello->neigh;
-      lq_hello->neigh = neigh;
-    }
+    neigh->next = lq_hello->neigh;
+    lq_hello->neigh = neigh;
+
+  } OLSR_FOR_ALL_LINK_ENTRIES_END(walker);
 }
 
 static void
@@ -151,7 +150,9 @@ destroy_lq_hello(struct lq_hello_message *lq_hello)
 static void
 create_lq_tc(struct lq_tc_message *lq_tc, struct interface *outif)
 {
-  int i;
+  struct link_entry *lnk;
+  struct neighbor_entry *walker;
+  struct tc_mpr_addr *neigh;
   static int ttl_list[] = { 2, 8, 2, 16, 2, 8, 2, MAX_TTL};
 
   // remember that we have generated an LQ TC message; this is
@@ -190,63 +191,55 @@ create_lq_tc(struct lq_tc_message *lq_tc, struct interface *outif)
 
   lq_tc->neigh = NULL;
  
-  // loop through all neighbours
-  
-  for(i = 0; i < HASHSIZE; i++)
-    {
-      struct neighbor_entry *walker;
-      struct tc_mpr_addr    *neigh;
-      for(walker = neighbortable[i].next; walker != &neighbortable[i];
-          walker = walker->next)
-        {
-          struct link_entry *lnk;
-          // only consider symmetric neighbours
-
-          if(walker->status != SYM)
-            continue;
+  OLSR_FOR_ALL_NBR_ENTRIES(walker) {
+
+    /*
+     * TC redundancy 2
+     *
+     * Only consider symmetric neighbours.
+     */
+    if (walker->status != SYM) {
+      continue;
+    }
 
-          // TC redundancy == 1: only consider MPRs and MPR selectors
+    /*
+     * TC redundancy 1
+     *
+     * Only consider MPRs and MPR selectors
+     */
+    if (olsr_cnf->tc_redundancy == 1 && !walker->is_mpr &&
+        !olsr_lookup_mprs_set(&walker->neighbor_main_addr)) {
+      continue;
+    }
 
-          if (olsr_cnf->tc_redundancy == 1 && !walker->is_mpr &&
-              olsr_lookup_mprs_set(&walker->neighbor_main_addr) == NULL)
-            continue;
+    /*
+     * TC redundancy 0
+     *
+     * Only consider MPR selectors
+     */
+    if (olsr_cnf->tc_redundancy == 0 &&
+        !olsr_lookup_mprs_set(&walker->neighbor_main_addr)) {
+      continue;
+    }
 
-          // TC redundancy == 0: only consider MPR selectors
-          if (olsr_cnf->tc_redundancy == 0 &&
-              olsr_lookup_mprs_set(&walker->neighbor_main_addr) == NULL)
-            continue;
+    /* Allocate a neighbour entry. */
+    neigh = olsr_malloc_tc_mpr_addr("Build LQ_TC");
 
-          // allocate a neighbour entry          
-          neigh = olsr_malloc(sizeof (struct tc_mpr_addr), "Build LQ_TC");
+    /* Set the entry's main address. */
+    neigh->address = walker->neighbor_main_addr;
 
-          // set the entry's main address
+    /* Set the entry's link quality */
+    lnk = get_best_link_to_neighbor(&neigh->address);
 
-          neigh->address = walker->neighbor_main_addr;
+    if (lnk) {
+      olsr_copylq_link_entry_2_tc_mpr_addr(neigh, lnk);
+    }
 
-          // set the entry's link quality
-          lnk = get_best_link_to_neighbor(&neigh->address);
+    /* Queue the neighbour entry. */
+    neigh->next = lq_tc->neigh;
+    lq_tc->neigh = neigh;
 
-          if (lnk) {
-            neigh->link_quality = lnk->loss_link_quality;
-            neigh->neigh_link_quality = lnk->neigh_link_quality;
-          }
-          else {
-            OLSR_PRINTF(0, "Error: link_qualtiy undefined");
-#ifdef USE_FPM
-            neigh->link_quality = itofpm(0);
-            neigh->neigh_link_quality = itofpm(0);
-#else
-            neigh->link_quality = 0.0;
-            neigh->neigh_link_quality = 0.0;
-#endif
-          }          
-
-          // queue the neighbour entry
-
-          neigh->next = lq_tc->neigh;
-          lq_tc->neigh = neigh;
-        }
-    }
+  } OLSR_FOR_ALL_NBR_ENTRIES_END(walker);
 }
 
 static void
@@ -449,19 +442,7 @@ serialize_lq_hello(struct lq_hello_message *lq_hello, struct interface *outif)
               size += olsr_cnf->ipsize;
 
               // add the corresponding link quality
-
-#ifdef USE_FPM
-              buff[size++] = fpmtoi(fpmmuli(neigh->link_quality, 255));
-              buff[size++] = fpmtoi(fpmmuli(neigh->neigh_link_quality, 255));
-#else
-              buff[size++] = (unsigned char)(neigh->link_quality * 255);
-              buff[size++] = (unsigned char)(neigh->neigh_link_quality * 255);
-#endif
-
-              // pad
-
-              buff[size++] = 0;
-              buff[size++] = 0;
+              size += olsr_serialize_hello_lq_pair(&buff[size], neigh);
 
               is_first = OLSR_FALSE;
             }
@@ -569,17 +550,7 @@ serialize_lq_tc(struct lq_tc_message *lq_tc, struct interface *outif)
       size += olsr_cnf->ipsize;
 
       // add the corresponding link quality
-#ifdef USE_FPM
-      buff[size++] = fpmtoi(fpmmuli(neigh->link_quality, 255));
-      buff[size++] = fpmtoi(fpmmuli(neigh->neigh_link_quality, 255));
-#else
-      buff[size++] = (unsigned char)(neigh->link_quality * 255);
-      buff[size++] = (unsigned char)(neigh->neigh_link_quality * 255);
-#endif
-
-      // pad
-      buff[size++] = 0;
-      buff[size++] = 0;
+      size += olsr_serialize_tc_lq_pair(&buff[size], neigh);
     }
 
   // finalize the OLSR header
@@ -661,3 +632,9 @@ olsr_output_lq_tc(void *para)
     set_buffer_timer(outif);
   }
 }
+
+/*
+ * Local Variables:
+ * c-basic-offset: 2
+ * End:
+ */
index 868c2f3..2b0670f 100644 (file)
@@ -94,15 +94,9 @@ struct lq_hello_neighbor
 {
   olsr_u8_t                link_type;
   olsr_u8_t                neigh_type;
-#ifdef USE_FPM
-  fpm                      link_quality;
-  fpm                      neigh_link_quality;
-#else
-  double                   link_quality;
-  double                   neigh_link_quality;
-#endif
   union olsr_ip_addr       addr;
   struct lq_hello_neighbor *next;
+  char                  linkquality[0];
 };
 
 struct lq_hello_message
@@ -155,11 +149,7 @@ static INLINE void       pkt_get_s32(const olsr_u8_t **p, olsr_32_t *var)
 static INLINE void    pkt_get_double(const olsr_u8_t **p, double *var)             { *var = me_to_double(**p);                       *p += sizeof(olsr_u8_t); }
 static INLINE void pkt_get_ipaddress(const olsr_u8_t **p, union olsr_ip_addr *var) { memcpy(var, *p, olsr_cnf->ipsize);              *p += olsr_cnf->ipsize; }
 static INLINE void pkt_get_prefixlen(const olsr_u8_t **p, olsr_u8_t *var)          { *var = netmask_to_prefix(*p, olsr_cnf->ipsize); *p += olsr_cnf->ipsize; }
-#ifdef USE_FPM
-static INLINE void        pkt_get_lq(const olsr_u8_t **p, fpm *var)                { *var = fpmidiv(itofpm(**p), 255);               *p += sizeof(olsr_u8_t); }
-#else
-static INLINE void        pkt_get_lq(const olsr_u8_t **p, double *var)             { *var = (const double)**p / 255.0;               *p += sizeof(olsr_u8_t); }
-#endif
+static INLINE void        pkt_get_lq(const olsr_u8_t **p, float *var)              { *var = (const float)**p / 255.0;               *p += sizeof(olsr_u8_t); }
 
 static INLINE void        pkt_ignore_u8(const olsr_u8_t **p) { *p += sizeof(olsr_u8_t); }
 static INLINE void       pkt_ignore_u16(const olsr_u8_t **p) { *p += sizeof(olsr_u16_t); }
@@ -179,7 +169,7 @@ static INLINE void       pkt_put_s32(olsr_u8_t **p, olsr_32_t var)
 static INLINE void    pkt_put_double(olsr_u8_t **p, double var)                    { **p = double_to_me(var);            *p += sizeof(olsr_u8_t); }
 static INLINE void pkt_put_ipaddress(olsr_u8_t **p, const union olsr_ip_addr *var) { memcpy(*p, var, olsr_cnf->ipsize); *p += olsr_cnf->ipsize; }
 static INLINE void pkt_put_prefixlen(olsr_u8_t **p, olsr_u8_t var)                 { prefix_to_netmask(*p, olsr_cnf->ipsize, var); *p += olsr_cnf->ipsize; }
-static INLINE void        pkt_put_lq(olsr_u8_t **p, double var)                    { **p  = var * 255.0;                 *p += sizeof(olsr_u8_t); }
+static INLINE void        pkt_put_lq(olsr_u8_t **p, float var)                     { **p  = var * 255.0;                 *p += sizeof(olsr_u8_t); }
 
 void olsr_output_lq_hello(void *para);
 
diff --git a/src/lq_plugin.c b/src/lq_plugin.c
new file mode 100644 (file)
index 0000000..facb38a
--- /dev/null
@@ -0,0 +1,378 @@
+#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"
+#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;
+
+/*
+ * set_lq_handler
+ * 
+ * this function is used by routing metric plugins to activate their link
+ * quality handler
+ * 
+ * @param pointer to lq_handler structure
+ * @param name of the link quality handler for debug output
+ */
+void set_lq_handler(struct lq_handler *handler, 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;
+  }
+}
+
+/*
+ * olsr_calc_tc_cost
+ * 
+ * this function calculates the linkcost of a tc_edge_entry
+ * 
+ * @param pointer to the tc_edge_entry
+ * @return linkcost
+ */
+olsr_linkcost olsr_calc_tc_cost(const struct tc_edge_entry *tc_edge)
+{
+  return active_lq_handler->calc_tc_cost(tc_edge->linkquality);
+}
+
+/*
+ * olsr_is_relevant_costchange
+ * 
+ * decides if the difference between two costs is relevant
+ * (for changing the route for example)
+ * 
+ * @param first linkcost value
+ * @param second linkcost value
+ * @return boolean
+ */
+olsr_bool olsr_is_relevant_costchange(olsr_linkcost c1, olsr_linkcost c2) {
+  return active_lq_handler->is_relevant_costchange(c1, c2);
+}
+
+/*
+ * olsr_serialize_hello_lq_pair
+ * 
+ * this function converts the lq information of a lq_hello_neighbor into binary package
+ * format
+ * 
+ * @param pointer to binary buffer to write into
+ * @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);
+}
+
+/*
+ * olsr_deserialize_hello_lq_pair
+ * 
+ * this function reads the lq information of a binary package into a hello_neighbor
+ * It also initialize the cost variable of the 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);
+}
+
+/*
+ * olsr_serialize_tc_lq_pair
+ * 
+ * this function converts the lq information of a olsr_serialize_tc_lq_pair
+ * into binary package format
+ * 
+ * @param pointer to binary buffer to write into
+ * @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);
+}
+
+/*
+ * olsr_deserialize_tc_lq_pair
+ * 
+ * this function reads the lq information of a binary package into a tc_edge_entry
+ * 
+ * @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);
+}
+
+/*
+ * olsr_update_packet_loss_worker
+ * 
+ * this function is called every times a hello package for a certain link_entry
+ * is lost (timeout) or received. This way the lq-plugin can update the links link
+ * quality value.
+ * 
+ * @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)
+{
+       olsr_linkcost lq;
+       lq = active_lq_handler->packet_loss_handler(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;
+    }
+
+    else
+      OLSR_PRINTF(3, "Skipping Dijkstra (1)\n");
+    
+    // XXX - we should check whether we actually
+    // announce this neighbour
+    signal_link_changes(OLSR_TRUE);
+  }
+}
+
+/*
+ * olsr_memorize_foreign_hello_lq
+ * 
+ * this function is called to copy the link quality information from a received
+ * hello package into a link_entry.
+ * 
+ * @param pointer to link_entry
+ * @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) {
+  if (foreign) {
+    active_lq_handler->memorize_foreign_hello(local->linkquality, foreign->linkquality);
+  }
+  else {
+    active_lq_handler->memorize_foreign_hello(local->linkquality, NULL);
+  }
+}
+
+/*
+ * get_link_entry_text
+ * 
+ * this function returns the text representation of a link_entry cost value.
+ * It's not thread save and should not be called twice with the same println
+ * value in the same context (a single printf command for example).
+ * 
+ * @param pointer to link_entry
+ * @return pointer to a buffer with the text representation
+ */
+char *get_link_entry_text(struct link_entry *entry) {
+  return active_lq_handler->print_hello_lq(entry->linkquality);
+}
+
+/*
+ * get_tc_edge_entry_text
+ * 
+ * this function returns the text representation of a tc_edge_entry cost value.
+ * It's not thread save and should not be called twice with the same println
+ * value in the same context (a single printf command for example).
+ * 
+ * @param pointer to tc_edge_entry
+ * @return pointer to a buffer with the text representation
+ */
+char *get_tc_edge_entry_text(struct tc_edge_entry *entry) {
+  return active_lq_handler->print_tc_lq(entry->linkquality);
+}
+
+const char *get_linkcost_text(olsr_linkcost cost, olsr_bool route) {
+  static const char *infinite = "INFINITE";
+  
+  if (route) {
+    if (cost == ROUTE_COST_BROKEN) {
+      return infinite;
+    }
+  }
+  else {
+    if (cost >= LINK_COST_BROKEN) {
+      return infinite;
+    }
+  }
+  return active_lq_handler->print_cost(cost);
+}
+
+/*
+ * olsr_copy_hello_lq
+ * 
+ * this function copies the link quality information from a link_entry to a
+ * lq_hello_neighbor.
+ * 
+ * @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);
+}
+
+/*
+ * olsr_copylq_link_entry_2_tc_mpr_addr
+ * 
+ * this function copies the link quality information from a link_entry to a
+ * tc_mpr_addr.
+ * 
+ * @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);
+}
+
+/*
+ * olsr_copylq_link_entry_2_tc_edge_entry
+ * 
+ * this function copies the link quality information from a link_entry to a
+ * tc_edge_entry.
+ * 
+ * @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);
+}
+
+/*
+ * olsr_clear_tc_lq
+ * 
+ * this function resets the linkquality value of a tc_mpr_addr
+ * 
+ * @param pointer to tc_mpr_addr
+ */
+void olsr_clear_tc_lq(struct tc_mpr_addr *target) {
+  active_lq_handler->clear_tc(target->linkquality);
+}
+
+/*
+ * olsr_malloc_hello_neighbor
+ * 
+ * this function allocates memory for an hello_neighbor inclusive
+ * linkquality data.
+ * 
+ * @param id string for memory debugging
+ * 
+ * @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;
+}
+
+/*
+ * olsr_malloc_tc_mpr_addr
+ * 
+ * this function allocates memory for an tc_mpr_addr inclusive
+ * linkquality data.
+ * 
+ * @param id string for memory debugging
+ * 
+ * @return pointer to tc_mpr_addr
+ */
+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);
+  
+  active_lq_handler->clear_tc(t->linkquality);
+  return t;
+}
+
+/*
+ * olsr_malloc_lq_hello_neighbor
+ * 
+ * this function allocates memory for an lq_hello_neighbor inclusive
+ * linkquality data.
+ * 
+ * @param id string for memory debugging
+ * 
+ * @return pointer to lq_hello_neighbor
+ */
+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);
+  
+  active_lq_handler->clear_hello(h->linkquality);
+  return h;
+}
+
+/*
+ * olsr_malloc_link_entry
+ * 
+ * this function allocates memory for an link_entry inclusive
+ * linkquality data.
+ * 
+ * @param id string for memory debugging
+ * 
+ * @return pointer to link_entry
+ */
+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);
+  
+  active_lq_handler->clear_hello(h->linkquality);
+  return h;
+}
+
+/*
+ * olsr_malloc_tc_edge_entry
+ * 
+ * this function allocates memory for an tc_edge_entry inclusive
+ * linkquality data.
+ * 
+ * @param id string for memory debugging
+ * 
+ * @return pointer to tc_edge_entry
+ */
+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);
+  
+  active_lq_handler->clear_tc(t);
+  return t;
+}
diff --git a/src/lq_plugin.h b/src/lq_plugin.h
new file mode 100644 (file)
index 0000000..8e7f48f
--- /dev/null
@@ -0,0 +1,68 @@
+#ifndef LQPLUGIN_H_
+#define LQPLUGIN_H_
+
+#include "tc_set.h"
+#include "link_set.h"
+#include "lq_route.h"
+#include "lq_packet.h"
+#include "packet.h"
+
+#define LINK_COST_BROKEN 65535
+#define ROUTE_COST_BROKEN (0xffffffff)
+#define ZERO_ROUTE_COST 0
+
+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);
+  
+  char *(*print_hello_lq)(void *ptr);
+  char *(*print_tc_lq)(void *ptr);
+  char *(*print_cost)(olsr_linkcost cost);
+  
+  size_t hello_lq_size;
+  size_t tc_lq_size;
+};
+
+void set_lq_handler(struct lq_handler *handler, 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_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_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);
+
+char *get_link_entry_text(struct link_entry *entry);
+char *get_tc_edge_entry_text(struct tc_edge_entry *entry);
+const char *get_linkcost_text(olsr_linkcost cost, olsr_bool route);
+
+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);
+struct tc_mpr_addr *olsr_malloc_tc_mpr_addr(const char *id);
+struct lq_hello_neighbor *olsr_malloc_lq_hello_neighbor(const char *id);
+struct link_entry *olsr_malloc_link_entry(const char *id);
+struct tc_edge_entry *olsr_malloc_tc_edge_entry(const char *id);
+
+#endif /*LQPLUGIN_H_*/
diff --git a/src/lq_plugin_default.c b/src/lq_plugin_default.c
new file mode 100644 (file)
index 0000000..1d94084
--- /dev/null
@@ -0,0 +1,114 @@
+#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));
+}
+
+char *default_olsr_print_lq(void *ptr) {
+  static char output_buffer[16];
+  struct default_lq *lq = ptr;
+  
+  sprintf(output_buffer, "%2.3f/%2.3f", lq->lq, lq->nlq);
+  return output_buffer;
+}
+
+char *default_olsr_print_cost(olsr_linkcost cost) {
+  static char output_buffer[16];
+  sprintf(output_buffer, "%2.3f", ((float)cost)/LQ_PLUGIN_LC_MULTIPLIER);
+  return output_buffer;
+}
diff --git a/src/lq_plugin_default.h b/src/lq_plugin_default.h
new file mode 100644 (file)
index 0000000..eecc45f
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef LQ_PLUGIN_DEFAULT_H_
+#define LQ_PLUGIN_DEFAULT_H_
+
+#include "olsr_types.h"
+
+#define LQ_PLUGIN_LC_MULTIPLIER 1024
+#define LQ_PLUGIN_RELEVANT_COSTCHANGE 16
+
+struct default_lq {
+       float lq, nlq;
+};
+
+olsr_linkcost default_calc_cost(const void *lq);
+
+olsr_bool default_olsr_is_relevant_costchange(olsr_linkcost c1, olsr_linkcost c2);
+
+olsr_linkcost default_packet_loss_worker(void *lq, olsr_bool lost);
+void default_olsr_memorize_foreign_hello_lq(void *local, void *foreign);
+
+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_olsr_copy_link_lq_into_tc(void *target, void *source);
+void default_olsr_clear_lq(void *target);
+
+char *default_olsr_print_lq(void *ptr);
+char *default_olsr_print_cost(olsr_linkcost cost);
+
+#endif /*LQ_PLUGIN_DEFAULT_H_*/
index 155778a..b0d6847 100644 (file)
@@ -64,6 +64,9 @@
 #include "lq_avl.h"
 #include "lq_route.h"
 #include "net_olsr.h"
+#include "lq_plugin.h"
+
+struct timer_entry *spf_backoff_timer = NULL;
 
 /*
  * avl_comp_etx
 static int
 avl_comp_etx (const void *etx1, const void *etx2)
 {       
-  if (*(const float *)etx1 < *(const float *)etx2) {
+  if (*(const olsr_linkcost *)etx1 < *(const olsr_linkcost *)etx2) {
     return -1;
   }
 
-  if (*(const float *)etx1 > *(const float *)etx2) {
+  if (*(const olsr_linkcost *)etx1 > *(const olsr_linkcost *)etx2) {
     return +1;
   }
 
@@ -100,13 +103,13 @@ olsr_spf_add_cand_tree (struct avl_tree *tree,
 #if !defined(NODEBUG) && defined(DEBUG)
   struct ipaddr_str buf;
 #endif
-  tc->cand_tree_node.key = &tc->path_etx;
+  tc->cand_tree_node.key = &tc->path_cost;
   tc->cand_tree_node.data = tc;
 
 #ifdef DEBUG
-  OLSR_PRINTF(1, "SPF: insert candidate %s, cost %s\n",
+  OLSR_PRINTF(2, "SPF: insert candidate %s, cost %s\n",
               olsr_ip_to_string(&buf, &tc->addr),
-              olsr_etx_to_string(tc->path_etx));
+              get_linkcost_text(tc->path_cost, OLSR_FALSE));
 #endif
 
   avl_insert(tree, &tc->cand_tree_node, AVL_DUP);
@@ -126,9 +129,9 @@ olsr_spf_del_cand_tree (struct avl_tree *tree,
 #ifndef NODEBUG
   struct ipaddr_str buf;
 #endif
-  OLSR_PRINTF(1, "SPF: delete candidate %s, cost %s\n",
+  OLSR_PRINTF(2, "SPF: delete candidate %s, cost %s\n",
               olsr_ip_to_string(&buf, &tc->addr),
-              olsr_etx_to_string(tc->path_etx));
+              get_linkcost_text(tc->path_cost, OLSR_FALSE));
 #endif
 
   avl_delete(tree, &tc->cand_tree_node);
@@ -149,9 +152,9 @@ olsr_spf_add_path_list (struct list_node *head, int *path_count,
   tc->path_list_node.data = tc;
 
 #ifdef DEBUG
-  OLSR_PRINTF(1, "SPF: append path %s, cost %s, via %s\n",
+  OLSR_PRINTF(2, "SPF: append path %s, cost %s, via %s\n",
               olsr_ip_to_string(&pathbuf, &tc->addr),
-              olsr_etx_to_string(tc->path_etx),
+              get_linkcost_text(tc->path_cost, OLSR_FALSE),
               tc->next_hop ? olsr_ip_to_string(
                 &nbuf, &tc->next_hop->neighbor_iface_addr) : "-");
 #endif
@@ -185,19 +188,15 @@ static void
 olsr_spf_relax (struct avl_tree *cand_tree, struct tc_entry *tc)
 {
   struct avl_node *edge_node;
-#ifdef USE_FPM
-  fpm new_etx;
-#else
-  float new_etx;
-#endif
+  olsr_linkcost new_cost;
 
 #ifdef DEBUG
 #ifndef NODEBUG
   struct ipaddr_str buf, nbuf;
 #endif
-  OLSR_PRINTF(1, "SPF: exploring node %s, cost %s\n",
+  OLSR_PRINTF(2, "SPF: exploring node %s, cost %s\n",
               olsr_ip_to_string(&buf, &tc->addr),
-              olsr_etx_to_string(tc->path_etx));
+              get_linkcost_text(tc->path_cost, OLSR_FALSE));
 #endif
 
   /*
@@ -215,13 +214,13 @@ olsr_spf_relax (struct avl_tree *cand_tree, struct tc_entry *tc)
      */
     if (!tc_edge->edge_inv || (tc_edge->flags & OLSR_TC_EDGE_DOWN)) {
 #ifdef DEBUG
-      OLSR_PRINTF(1, "SPF:   ignoring edge %s\n",
+      OLSR_PRINTF(2, "SPF:   ignoring edge %s\n",
                   olsr_ip_to_string(&buf, &tc_edge->T_dest_addr));
       if (tc_edge->flags & OLSR_TC_EDGE_DOWN) {
-        OLSR_PRINTF(1, "SPF:     edge down\n");
+        OLSR_PRINTF(2, "SPF:     edge down\n");
       }
       if (!tc_edge->edge_inv) {
-        OLSR_PRINTF(1, "SPF:     no inverse edge\n");
+        OLSR_PRINTF(2, "SPF:     no inverse edge\n");
       }
 #endif
       continue;
@@ -231,17 +230,12 @@ olsr_spf_relax (struct avl_tree *cand_tree, struct tc_entry *tc)
      * total quality of the path through this vertex
      * to the destination of this edge
      */
-#ifdef USE_FPM
-    new_etx = INFINITE_ETX <= tc->path_etx || INFINITE_ETX <= tc_edge->etx
-      ? INFINITE_ETX : fpmadd(tc->path_etx, tc_edge->etx);
-#else
-    new_etx = tc->path_etx + tc_edge->etx;
-#endif
+    new_cost = tc->path_cost + tc_edge->cost;
 
 #ifdef DEBUG
-      OLSR_PRINTF(1, "SPF:   exploring edge %s, cost %s\n",
+      OLSR_PRINTF(2, "SPF:   exploring edge %s, cost %s\n",
                   olsr_ip_to_string(&buf, &tc_edge->T_dest_addr),
-                  olsr_etx_to_string(new_etx));
+                  get_linkcost_text(new_cost, OLSR_TRUE));
 #endif
 
       /* 
@@ -250,15 +244,15 @@ olsr_spf_relax (struct avl_tree *cand_tree, struct tc_entry *tc)
        */
     new_tc = tc_edge->edge_inv->tc;
 
-    if (new_etx < new_tc->path_etx) {
+    if (new_cost < new_tc->path_cost) {
 
       /* if this node has been on the candidate tree delete it */
-      if (new_tc->path_etx != INFINITE_ETX) {
+      if (new_tc->path_cost < ROUTE_COST_BROKEN) {
         olsr_spf_del_cand_tree(cand_tree, new_tc);
       }
 
       /* re-insert on candidate tree with the better metric */
-      new_tc->path_etx = new_etx;
+      new_tc->path_cost = new_cost;
       olsr_spf_add_cand_tree(cand_tree, new_tc);
 
       /* pull-up the next-hop and bump the hop count */
@@ -268,10 +262,9 @@ olsr_spf_relax (struct avl_tree *cand_tree, struct tc_entry *tc)
       new_tc->hops = tc->hops + 1;
 
 #ifdef DEBUG
-      OLSR_PRINTF(1, "SPF:   better path to %s, cost %s -> %s, via %s, hops %u\n",
+      OLSR_PRINTF(2, "SPF:   better path to %s, cost %s, via %s, hops %u\n",
                   olsr_ip_to_string(&buf, &new_tc->addr),
-                  olsr_etx_to_string(new_tc->path_etx),
-                  olsr_etx_to_string(new_etx),
+                  get_linkcost_text(new_cost, OLSR_TRUE),
                   tc->next_hop ? olsr_ip_to_string(
                     &nbuf, &tc->next_hop->neighbor_iface_addr) : "<none>",
                   new_tc->hops);
@@ -314,22 +307,41 @@ olsr_spf_run_full (struct avl_tree *cand_tree, struct list_node *path_list,
   }
 }
 
+/**
+ * Callback for the SPF backoff timer.
+ */
+static void
+olsr_expire_spf_backoff(void *context __attribute__((unused)))
+{
+  spf_backoff_timer = NULL;
+}
+
 void
-olsr_calculate_routing_table (void)
+olsr_calculate_routing_table (void *context __attribute__((unused)))
 {
+#ifdef SPF_PROFILING
+  struct timeval t1, t2, t3, t4, t5, spf_init, spf_run, route, kernel, total;
+#endif
   struct avl_tree cand_tree;
   struct avl_node *rtp_tree_node;
   struct list_node path_list; /* head of the path_list */
-  int i, path_count = 0;
   struct tc_entry *tc;
   struct rt_path *rtp;
   struct tc_edge_entry *tc_edge;
   struct neighbor_entry *neigh;
   struct link_entry *link;
+  int path_count = 0;
+
+  /* We are done if our backoff timer is running */
+  if (!spf_backoff_timer) {
+    spf_backoff_timer = 
+      olsr_start_timer(1000, 5, OLSR_TIMER_ONESHOT, &olsr_expire_spf_backoff,
+                       NULL, 0);
+  } else {
+    return;
+  }
 
 #ifdef SPF_PROFILING
-  struct timeval t1, t2, t3, t4, t5, spf_init, spf_run, route, kernel, total;
-
   gettimeofday(&t1, NULL);
 #endif
 
@@ -345,7 +357,7 @@ olsr_calculate_routing_table (void)
    */
   OLSR_FOR_ALL_TC_ENTRIES(tc) {
     tc->next_hop = NULL;
-    tc->path_etx = INFINITE_ETX;
+    tc->path_cost = ROUTE_COST_BROKEN;
     tc->hops = 0;
   } OLSR_FOR_ALL_TC_ENTRIES_END(tc);
 
@@ -353,62 +365,56 @@ olsr_calculate_routing_table (void)
    * zero ourselves and add us to the candidate tree.
    */
   olsr_change_myself_tc();
-  tc_myself->path_etx = ZERO_ETX;
+  tc_myself->path_cost = ZERO_ROUTE_COST;
   olsr_spf_add_cand_tree(&cand_tree, tc_myself);
 
   /*
    * add edges to and from our neighbours.
    */
-  for (i = 0; i < HASHSIZE; i++)
-    for (neigh = neighbortable[i].next; neigh != &neighbortable[i];
-         neigh = neigh->next) {
-
-      if (neigh->status == SYM) {
-
-        tc_edge = olsr_lookup_tc_edge(tc_myself, &neigh->neighbor_main_addr);
-        link = get_best_link_to_neighbor(&neigh->neighbor_main_addr);
-       if (!link) {
-
-          /*
-           * If there is no best link to this neighbor
-           * and we had an edge before then flush the edge.
-           */
-          if (tc_edge) {
-            olsr_delete_tc_edge_entry(tc_edge);
-          }
-         continue;
-        }
+  OLSR_FOR_ALL_NBR_ENTRIES(neigh) {
 
-        /* find the interface for the link */
-        if (link->if_name) {
-          link->inter = if_ifwithname(link->if_name);
-        } else {
-          link->inter = if_ifwithaddr(&link->local_iface_addr);
-        }
+    if (neigh->status == SYM) {
+
+      tc_edge = olsr_lookup_tc_edge(tc_myself, &neigh->neighbor_main_addr);
+      link = get_best_link_to_neighbor(&neigh->neighbor_main_addr);
+      if (!link) {
 
         /*
-         * Set the next-hops of our neighbors. 
+         * If there is no best link to this neighbor
+         * and we had an edge before then flush the edge.
          */
-        if (!tc_edge) {
-          tc_edge = olsr_add_tc_edge_entry(tc_myself, &neigh->neighbor_main_addr,
-                                           0, link->vtime,
-                                           link->loss_link_quality2,
-                                           link->neigh_link_quality2);
-        } else {
-
-          /*
-           * Update LQ and timers, such that the edge does not get deleted.
-           */
-          tc_edge->link_quality = link->loss_link_quality2;
-          tc_edge->inverse_link_quality = link->neigh_link_quality2;
-          olsr_set_tc_edge_timer(tc_edge, link->vtime*1000);
-          olsr_calc_tc_edge_entry_etx(tc_edge);
-        }
-        if (tc_edge->edge_inv) {
-          tc_edge->edge_inv->tc->next_hop = link;
+        if (tc_edge) {
+          olsr_delete_tc_edge_entry(tc_edge);
         }
+        continue;
+      }
+
+      /* find the interface for the link */
+      if (link->if_name) {
+        link->inter = if_ifwithname(link->if_name);
+      } else {
+        link->inter = if_ifwithaddr(&link->local_iface_addr);
+      }
+
+      /*
+       * Set the next-hops of our neighbors. 
+       */
+      if (!tc_edge) {
+        tc_edge = olsr_add_tc_edge_entry(tc_myself, &neigh->neighbor_main_addr,
+                                         0, link->vtime);
+      } else {
+        /*
+         * Update LQ and timers, such that the edge does not get deleted.
+         */
+        olsr_copylq_link_entry_2_tc_edge_entry(tc_edge, link);
+        olsr_set_tc_edge_timer(tc_edge, link->vtime*1000);
+        olsr_calc_tc_edge_entry_etx(tc_edge);
+      }
+      if (tc_edge->edge_inv) {
+        tc_edge->edge_inv->tc->next_hop = link;
       }
     }
+  } OLSR_FOR_ALL_NBR_ENTRIES_END(neigh);
 
 #ifdef SPF_PROFILING
   gettimeofday(&t2, NULL);
@@ -419,11 +425,8 @@ olsr_calculate_routing_table (void)
    */
   olsr_spf_run_full(&cand_tree, &path_list, &path_count);
 
-  OLSR_PRINTF(2, "\n--- %02d:%02d:%02d.%02d ------------------------------------------------- DIJKSTRA\n\n",
-              nowtm->tm_hour,
-              nowtm->tm_min,
-              nowtm->tm_sec,
-              (int)now.tv_usec/10000);
+  OLSR_PRINTF(2, "\n--- %s ------------------------------------------------- DIJKSTRA\n\n",
+              olsr_wallclock_string());
 
 #ifdef SPF_PROFILING
   gettimeofday(&t3, NULL);
@@ -447,7 +450,7 @@ olsr_calculate_routing_table (void)
 #ifndef NODEBUG
         struct ipaddr_str buf;
 #endif
-        OLSR_PRINTF(1, "SPF: %s no next-hop\n", olsr_ip_to_string(&buf, &tc->addr));
+        OLSR_PRINTF(2, "SPF: %s no next-hop\n", olsr_ip_to_string(&buf, &tc->addr));
       }
 #endif
       continue;
index 1ce225b..8aaba2d 100644 (file)
@@ -41,6 +41,6 @@
 #ifndef _LQ_ROUTE_H
 #define _LQ_ROUTE_H
 
-void olsr_calculate_routing_table(void);
+void olsr_calculate_routing_table(void *);
 
 #endif
index b0019aa..22377d0 100644 (file)
@@ -154,10 +154,6 @@ main(int argc, char *argv[])
 
   /* Grab initial timestamp */
   now_times = times(&tms_buf);
-  do {
-    time_t t = now.tv_sec;
-    nowtm = localtime(&t);
-  } while (nowtm == NULL);
     
   printf("\n *** %s ***\n Build date: %s on %s\n http://www.olsr.org\n\n", 
         olsrd_version, 
@@ -233,6 +229,9 @@ main(int argc, char *argv[])
   olsr_cnf->system_tick_divider = 1;
 #endif
 
+  /* Initialize timers */
+  olsr_init_timers();
+
   /*
    * Process olsrd options.
    */
@@ -357,12 +356,11 @@ main(int argc, char *argv[])
   /* Print heartbeat to stdout */
 
 #if !defined WINCE
-  if(olsr_cnf->debug_level > 0 && isatty(STDOUT_FILENO))
-    olsr_register_scheduler_event(&generate_stdout_pulse, NULL, STDOUT_PULSE_INT, 0, NULL);
+  if (olsr_cnf->debug_level > 0 && isatty(STDOUT_FILENO)) {
+    olsr_start_timer(STDOUT_PULSE_INT, 0, OLSR_TIMER_PERIODIC,
+                     &generate_stdout_pulse, NULL, 0);
+  }
 #endif
-  
-  gettimeofday(&now, NULL);
-
 
   /* Initialize the IPC socket */
 
@@ -406,16 +404,15 @@ 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
 
-  /* Register socket poll event */
-  olsr_register_timeout_function(&poll_sockets, OLSR_FALSE);
+  link_changes = OLSR_FALSE;
 
   /* Starting scheduler */
-  scheduler();
+  olsr_scheduler();
 
   /* Like we're ever going to reach this ;-) */
   return 1;
@@ -885,3 +882,9 @@ olsr_process_arguments(int argc, char *argv[],
     }
   return 0;
 }
+
+/*
+ * Local Variables:
+ * c-basic-offset: 2
+ * End:
+ */
index 4df44dd..83654a6 100644 (file)
@@ -130,3 +130,40 @@ double me_to_double(const olsr_u8_t me)
     const olsr_u8_t b = me & 0x0F;
     return ((16 + a) << b) * VTIME_SCALE_FACTOR / 16.0;
 }
+
+#if 0
+/*
+ * Since the original VTIME_SCALE_FACTOR simply divides
+ * values by 16 (equals >> 4), we can shorten calculations.
+ * For details refer to RFC 3626 (search for "mantissa").
+ */
+olsr_u8_t fpm_to_me(const fpm interval)
+{
+  olsr_u8_t a = 0, b = 0; /* Underflow defaults */
+  const unsigned int unscaled_interval = (sfpm)interval >> (FPM_BIT - 4);
+
+  while (unscaled_interval >= (1U << b)) b++;
+
+  if (0 < b) {
+    b--;
+    if (15 < b) {
+      a = 15; /* Overflow defaults */
+      b = 15;
+    }
+    else
+    {
+      assert(FPM_BIT >= 8);
+      a = ((sfpm)interval >> (FPM_BIT + b - 8)) - 16;
+    }
+  }
+  return (a << 4) | (b & 0x0F);
+}
+
+fpm me_to_fpm(const olsr_u8_t me)
+{
+  const olsr_u8_t a = me >> 4;
+  const olsr_u8_t b = me & 0x0F;
+  assert(FPM_BIT >= 8);
+  return (fpm)(((sfpm)a + 16) << (b + FPM_BIT - 8));
+}
+#endif
index 403d20f..9148d35 100644 (file)
@@ -68,11 +68,6 @@ olsr_init_mid_set(void)
 
   OLSR_PRINTF(5, "MID: init\n");
 
-  /* Since the holdingtime is assumed to be rather large for 
-   * MID entries, the timeoutfunction is only ran once every second
-   */
-  olsr_register_scheduler_event_dijkstra(&olsr_time_out_mid_set, NULL, 1, 0, NULL);
-
   for(idx=0;idx<HASHSIZE;idx++)
     {
       mid_set[idx].next = &mid_set[idx];
@@ -85,6 +80,43 @@ olsr_init_mid_set(void)
   return 1;
 }
 
+/**
+ * Wrapper for the timer callback.
+ */
+static void
+olsr_expire_mid_entry(void *context)
+{
+#if !defined(NODEBUG) && defined(DEBUG)
+  struct ipaddr_str buf;
+#endif
+  struct mid_entry *mid;
+
+  mid = (struct mid_entry *)context;
+  mid->mid_timer = NULL;
+
+#ifdef DEBUG
+  OLSR_PRINTF(1, "MID info for %s timed out.. deleting it\n",
+              olsr_ip_to_string(&buf, &mid->main_addr));
+#endif
+
+  mid_delete_node(mid);
+}
+
+
+/**
+ * Set the mid set expiration timer.
+ *
+ * all timer setting shall be done using this function.
+ * The timer param is a relative timer expressed in milliseconds.
+ */
+static void
+olsr_set_mid_timer(struct mid_entry *mid, unsigned int rel_timer)
+{
+
+  olsr_set_timer(&mid->mid_timer, rel_timer, OLSR_MID_JITTER,
+                 OLSR_TIMER_ONESHOT, &olsr_expire_mid_entry, mid, 0);
+}
+
 
 /**
  *Insert a new interface alias to the interface association set.
@@ -105,8 +137,8 @@ insert_mid_tuple(union olsr_ip_addr *m_addr, struct mid_address *alias, float vt
   olsr_u32_t hash, alias_hash;
   union olsr_ip_addr *registered_m_addr;
 
-  hash = olsr_hashing(m_addr);
-  alias_hash = olsr_hashing(&alias->alias);
+  hash = olsr_ip_hashing(m_addr);
+  alias_hash = olsr_ip_hashing(&alias->alias);
 
   /* Check for registered entry */
   for(tmp = mid_set[hash].next;
@@ -139,19 +171,18 @@ insert_mid_tuple(union olsr_ip_addr *m_addr, struct mid_address *alias, float vt
       alias->main_entry = tmp;
       QUEUE_ELEM(reverse_mid_set[alias_hash], alias);
       alias->next_alias = tmp_adr;
-      tmp->ass_timer = GET_TIMESTAMP(vtime*1000);
+      olsr_set_mid_timer(tmp, vtime * MSEC_PER_SEC);
     }
   else
     {
       /*Create new node*/
       tmp = olsr_malloc(sizeof(struct mid_entry), "MID new alias");
-      memset(tmp, 0, sizeof(struct mid_entry));
 
       tmp->aliases = alias;
       alias->main_entry = tmp;
       QUEUE_ELEM(reverse_mid_set[alias_hash], alias);
       tmp->main_addr = *m_addr;
-      tmp->ass_timer = GET_TIMESTAMP(vtime*1000);
+      olsr_set_mid_timer(tmp, vtime * MSEC_PER_SEC);
       /* Queue */
       QUEUE_ELEM(mid_set[hash], tmp);
     }
@@ -242,7 +273,6 @@ insert_mid_alias(union olsr_ip_addr *main_add, const union olsr_ip_addr *alias,
   OLSR_PRINTF(1, "%s\n", olsr_ip_to_string(&buf1, main_add));
 
   adr = olsr_malloc(sizeof(struct mid_address), "Insert MID alias");
-  memset(adr, 0, sizeof(struct mid_address));
 
   adr->alias = *alias;
   adr->next_alias = NULL;
@@ -294,7 +324,7 @@ mid_lookup_main_addr(const union olsr_ip_addr *adr)
   olsr_u32_t hash;
   struct mid_address *tmp_list;
 
-  hash = olsr_hashing(adr);
+  hash = olsr_ip_hashing(adr);
   /*Traverse MID list*/
   for(tmp_list = reverse_mid_set[hash].next; 
       tmp_list != &reverse_mid_set[hash];
@@ -320,7 +350,7 @@ mid_lookup_entry_bymain(const union olsr_ip_addr *adr)
 
   //OLSR_PRINTF(1, "MID: lookup entry...");
 
-  hash = olsr_hashing(adr);
+  hash = olsr_ip_hashing(adr);
 
   /* Check all registered nodes...*/
   for(tmp_list = mid_set[hash].next;
@@ -365,7 +395,7 @@ olsr_update_mid_table(const union olsr_ip_addr *adr, float vtime)
   struct mid_entry *tmp_list = mid_set;
 
   OLSR_PRINTF(3, "MID: update %s\n", olsr_ip_to_string(&buf, adr));
-  hash = olsr_hashing(adr);
+  hash = olsr_ip_hashing(adr);
 
   /* Check all registered nodes...*/
   for(tmp_list = mid_set[hash].next;
@@ -376,7 +406,7 @@ olsr_update_mid_table(const union olsr_ip_addr *adr, float vtime)
       if(ipequal(&tmp_list->main_addr, adr))
        {
          // printf("MID: Updating timer for node %s\n", olsr_ip_to_string(&buf, &tmp_list->main_addr));
-         tmp_list->ass_timer = GET_TIMESTAMP(vtime*1000);
+          olsr_set_mid_timer(tmp_list, vtime * MSEC_PER_SEC);
 
          return 1;
        }
@@ -402,7 +432,7 @@ olsr_prune_aliases(const union olsr_ip_addr *m_addr, struct mid_alias *declared_
   struct mid_address *previous_alias;
   struct mid_alias *save_declared_aliases = declared_aliases;
 
-  hash = olsr_hashing(m_addr);
+  hash = olsr_ip_hashing(m_addr);
 
   /* Check for registered entry */
   for(entry = mid_set[hash].next;
@@ -479,47 +509,6 @@ olsr_prune_aliases(const union olsr_ip_addr *m_addr, struct mid_alias *declared_
 }
 
 
-
-/**
- *Find timed out entries and delete them
- *
- *@return nada
- */
-void
-olsr_time_out_mid_set(void *foo __attribute__((unused)))
-{
-  int idx;
-
-  for(idx=0;idx<HASHSIZE;idx++)
-    {
-      struct mid_entry *tmp_list = mid_set[idx].next;
-      /*Traverse MID list*/
-      while(tmp_list != &mid_set[idx])
-       {
-         /*Check if the entry is timed out*/
-         if(TIMED_OUT(tmp_list->ass_timer))
-           {
-#if !defined(NODEBUG) && defined(DEBUG)
-              struct ipaddr_str buf;
-#endif
-             struct mid_entry *entry_to_delete = tmp_list;
-             tmp_list = tmp_list->next;
-#ifdef DEBUG
-             OLSR_PRINTF(1, "MID info for %s timed out.. deleting it\n",
-                         olsr_ip_to_string(&buf, &entry_to_delete->main_addr));
-#endif
-             /*Delete it*/
-             mid_delete_node(entry_to_delete);
-           }
-         else
-             tmp_list = tmp_list->next;
-       }
-    }
-
-  return;
-}
-
-
 /*
  *Delete an entry
  *
@@ -549,6 +538,15 @@ mid_delete_node(struct mid_entry *mid)
 
       free(tmp_aliases);
     }
+
+  /*
+   * Kill any pending timers.
+   */
+  if (mid->mid_timer) {
+    olsr_stop_timer(mid->mid_timer);
+    mid->mid_timer = NULL;
+  }
+
   /* Dequeue */
   DEQUEUE_ELEM(mid);
   free(mid);
@@ -566,7 +564,8 @@ olsr_print_mid_set(void)
 {
   int idx;
 
-  OLSR_PRINTF(1, "mid set: %02d:%02d:%02d.%06lu\n",nowtm->tm_hour, nowtm->tm_min, nowtm->tm_sec, now.tv_usec);
+  OLSR_PRINTF(1, "\n--- %s ------------------------------------------------- MID\n\n",
+              olsr_wallclock_string());
 
   for(idx=0;idx<HASHSIZE;idx++)
     {
index db7ade5..2b778b7 100644 (file)
@@ -66,9 +66,10 @@ struct mid_entry
   struct mid_address *aliases;
   struct mid_entry   *prev;
   struct mid_entry   *next;
-  clock_t             ass_timer;  
+  struct timer_entry  *mid_timer;
 };
 
+#define OLSR_MID_JITTER 5 /* percent */
 
 extern struct mid_entry mid_set[HASHSIZE];
 extern struct mid_address reverse_mid_set[HASHSIZE];
index 5d2c834..87a5440 100644 (file)
--- a/src/mpr.c
+++ b/src/mpr.c
@@ -241,36 +241,31 @@ static struct neighbor_entry *
 olsr_find_maximum_covered(int willingness)
 {
   olsr_u16_t                  maximum;
-  olsr_u8_t                   index;
   struct neighbor_entry       *a_neighbor;
-  struct neighbor_entry       *mpr_candidate=NULL;
+  struct neighbor_entry       *mpr_candidate = NULL;
    
   maximum = 0;
-  
-  for (index=0;index<HASHSIZE;index++)
-    {
-      for(a_neighbor = neighbortable[index].next;
-         a_neighbor != &neighbortable[index];
-         a_neighbor = a_neighbor->next)
-       {
-         /*      
-         printf("[%s] nocov: %d mpr: %d will: %d max: %d\n\n", 
-                olsr_ip_to_string(&buf, &a_neighbor->neighbor_main_addr), 
-                a_neighbor->neighbor_2_nocov,
-                a_neighbor->is_mpr,
-                a_neighbor->willingness,
-                maximum);
-         */
-         if((!a_neighbor->is_mpr) &&
-            (a_neighbor->willingness == willingness) && 
-            (maximum < a_neighbor->neighbor_2_nocov))
-           {
-             //printf("ADDING\n");
-             maximum = a_neighbor->neighbor_2_nocov;
-             mpr_candidate = a_neighbor;
-           }
-       }
-    }
+
+  OLSR_FOR_ALL_NBR_ENTRIES(a_neighbor) {
+
+#if 0
+      printf("[%s] nocov: %d mpr: %d will: %d max: %d\n\n", 
+             olsr_ip_to_string(&buf, &a_neighbor->neighbor_main_addr), 
+             a_neighbor->neighbor_2_nocov,
+             a_neighbor->is_mpr,
+             a_neighbor->willingness,
+             maximum);
+#endif
+
+      if ((!a_neighbor->is_mpr) &&
+          (a_neighbor->willingness == willingness) && 
+          (maximum < a_neighbor->neighbor_2_nocov)) {
+
+          maximum = a_neighbor->neighbor_2_nocov;
+          mpr_candidate = a_neighbor;
+      }
+  } OLSR_FOR_ALL_NBR_ENTRIES_END(a_neighbor);
+
   return mpr_candidate;
 }
 
@@ -281,32 +276,25 @@ olsr_find_maximum_covered(int willingness)
 static void
 olsr_clear_mprs(void)
 {
-  olsr_u32_t index;
-  
-  for (index=0;index<HASHSIZE;index++)
-    {
-      struct neighbor_entry   *a_neighbor;
-      for(a_neighbor = neighbortable[index].next;
-         a_neighbor != &neighbortable[index];
-         a_neighbor = a_neighbor->next)
-       {
-          struct neighbor_2_list_entry *two_hop_list;
-         /* Clear MPR selection */
-         if(a_neighbor->is_mpr)
-           {
-             a_neighbor->was_mpr = OLSR_TRUE;
-             a_neighbor->is_mpr = OLSR_FALSE;
-           }
+  struct neighbor_entry *a_neighbor;
+  struct neighbor_2_list_entry *two_hop_list;
 
-         /* Clear two hop neighbors coverage count */
-         for(two_hop_list = a_neighbor->neighbor_2_list.next;
-             two_hop_list != &a_neighbor->neighbor_2_list;
-             two_hop_list = two_hop_list->next)
-           {
-             two_hop_list->neighbor_2->mpr_covered_count = 0;
-           }
-       }
+  OLSR_FOR_ALL_NBR_ENTRIES(a_neighbor) {
+
+    /* Clear MPR selection. */
+    if (a_neighbor->is_mpr) {
+      a_neighbor->was_mpr = OLSR_TRUE;
+      a_neighbor->is_mpr = OLSR_FALSE;
+    }
+
+    /* Clear two hop neighbors coverage count/ */
+    for (two_hop_list = a_neighbor->neighbor_2_list.next;
+         two_hop_list != &a_neighbor->neighbor_2_list;
+         two_hop_list = two_hop_list->next) {
+      two_hop_list->neighbor_2->mpr_covered_count = 0;
     }
+
+  } OLSR_FOR_ALL_NBR_ENTRIES_END(a_neighbor);
 }
 
 
@@ -318,26 +306,21 @@ olsr_clear_mprs(void)
 static int
 olsr_check_mpr_changes(void)
 {
-  olsr_u32_t index;
+  struct neighbor_entry *a_neighbor;
   int retval;
 
   retval = 0;
   
-  for (index=0;index<HASHSIZE;index++)
-    {
-      struct neighbor_entry *a_neighbor;
-      for(a_neighbor = neighbortable[index].next;
-         a_neighbor != &neighbortable[index];
-         a_neighbor = a_neighbor->next)
-       {
-         if(a_neighbor->was_mpr)
-           {
-             a_neighbor->was_mpr = OLSR_FALSE;
-             if(!a_neighbor->is_mpr)
-               retval = 1;
-           }
-       }
+  OLSR_FOR_ALL_NBR_ENTRIES(a_neighbor) {
+
+    if (a_neighbor->was_mpr) {
+      a_neighbor->was_mpr = OLSR_FALSE;
+
+      if (!a_neighbor->is_mpr) {
+        retval = 1;
+      }
     }
+  } OLSR_FOR_ALL_NBR_ENTRIES_END(a_neighbor);
 
   return retval;
 }
@@ -373,49 +356,42 @@ olsr_clear_two_hop_processed(void)
 static olsr_u16_t
 olsr_calculate_two_hop_neighbors(void)
 {
-  olsr_u8_t                    index;
-  olsr_u16_t                   sum = 0;
+  struct neighbor_entry *a_neighbor, *dup_neighbor;
+  struct neighbor_2_list_entry *twohop_neighbors;
+  olsr_u16_t count = 0;
+  olsr_u16_t n_count = 0;
+  olsr_u16_t sum = 0;
   
   /* Clear 2 hop neighs */
   olsr_clear_two_hop_processed();
 
-  for(index=0;index<HASHSIZE;index++)
-    {
-      struct neighbor_entry *a_neighbor;
-      for(a_neighbor = neighbortable[index].next; a_neighbor != &neighbortable[index]; a_neighbor = a_neighbor->next)
-       { 
-          struct neighbor_2_list_entry *twohop_neighbors;
-          olsr_u16_t                   count = 0;
-          olsr_u16_t                   n_count = 0;
-          if(a_neighbor->status == NOT_SYM)
-           {       
-             a_neighbor->neighbor_2_nocov = count;
-             continue;
-           }
+  OLSR_FOR_ALL_NBR_ENTRIES(a_neighbor) {
 
-         for(twohop_neighbors = a_neighbor->neighbor_2_list.next;
-             twohop_neighbors != &a_neighbor->neighbor_2_list;
-             twohop_neighbors = twohop_neighbors->next)
-           {
-             //printf("\tChecking %s....", olsr_ip_to_string(&buf, &twohop_neighbors->neighbor_2->neighbor_2_addr));
-              struct neighbor_entry *dup_neighbor = olsr_lookup_neighbor_table(&twohop_neighbors->neighbor_2->neighbor_2_addr);
+    if (a_neighbor->status == NOT_SYM) {           
+      a_neighbor->neighbor_2_nocov = count;
+      continue;
+    }
+
+    for (twohop_neighbors = a_neighbor->neighbor_2_list.next;
+         twohop_neighbors != &a_neighbor->neighbor_2_list;
+         twohop_neighbors = twohop_neighbors->next) {
+
+      dup_neighbor = olsr_lookup_neighbor_table(&twohop_neighbors->neighbor_2->neighbor_2_addr);
              
-             if((dup_neighbor == NULL) || (dup_neighbor->status != SYM))
-               {
-                 n_count++;
-                 if(!twohop_neighbors->neighbor_2->processed)
-                   {
-                     count++;
-                     twohop_neighbors->neighbor_2->processed = 1;
-                   }
-               }
-           }
-         a_neighbor->neighbor_2_nocov = n_count;
-         
-         /* Add the two hop count */
-         sum += count;
-       }
+      if ((dup_neighbor == NULL) || (dup_neighbor->status != SYM)) {
+        n_count++;
+        if (!twohop_neighbors->neighbor_2->processed) {
+          count++;
+          twohop_neighbors->neighbor_2->processed = 1;
+        }
+      }
     }
+    a_neighbor->neighbor_2_nocov = n_count;
+         
+    /* Add the two hop count */
+    sum += count;
+
+  } OLSR_FOR_ALL_NBR_ENTRIES_END(a_neighbor);
   
   OLSR_PRINTF(3, "Two hop neighbors: %d\n", sum);
   return sum;
@@ -430,32 +406,31 @@ olsr_calculate_two_hop_neighbors(void)
 static olsr_u16_t
 add_will_always_nodes(void)
 {
-  olsr_u16_t                   count = 0;
-  olsr_u8_t                    idx;
+  struct neighbor_entry *a_neighbor;
+  olsr_u16_t count = 0;
 
-  //printf("\nAdding WILL ALWAYS nodes....\n");
+#if 0
+  printf("\nAdding WILL ALWAYS nodes....\n");
+#endif
 
-  for(idx=0;idx<HASHSIZE;idx++)
-    {
-      struct neighbor_entry        *a_neighbor;
-      for(a_neighbor = neighbortable[idx].next;
-         a_neighbor != &neighbortable[idx];
-         a_neighbor = a_neighbor->next)
-       { 
+  OLSR_FOR_ALL_NBR_ENTRIES(a_neighbor) {
 #ifndef NODEBUG
-          struct ipaddr_str buf;
+    struct ipaddr_str buf;
 #endif
-         if((a_neighbor->status == NOT_SYM) || (a_neighbor->willingness != WILL_ALWAYS)) {
-           continue;
-          }
-         olsr_chosen_mpr(a_neighbor, &count); 
+    if ((a_neighbor->status == NOT_SYM) ||
+        (a_neighbor->willingness != WILL_ALWAYS)) {
+      continue;
+    }
+    olsr_chosen_mpr(a_neighbor, &count); 
 
-         OLSR_PRINTF(3, "Adding WILL_ALWAYS: %s\n", olsr_ip_to_string(&buf, &a_neighbor->neighbor_main_addr));
+    OLSR_PRINTF(3, "Adding WILL_ALWAYS: %s\n",
+                olsr_ip_to_string(&buf, &a_neighbor->neighbor_main_addr));
 
-       }
-    }
-  
-  //OLSR_PRINTF(1, "Count: %d\n", count);
+  } OLSR_FOR_ALL_NBR_ENTRIES_END(a_neighbor);
+
+#if 0  
+  OLSR_PRINTF(1, "Count: %d\n", count);
+#endif
   return count;
 }
 
@@ -547,58 +522,52 @@ olsr_calculate_mpr(void)
 static void
 olsr_optimize_mpr_set(void)
 {
+  struct neighbor_entry *a_neighbor, *dup_neighbor;
+  struct neighbor_2_list_entry *two_hop_list;
   int i, remove;
 
-  //printf("\n**MPR OPTIMIZING**\n\n");
+#if 0
+  printf("\n**MPR OPTIMIZING**\n\n");
+#endif
 
-  for(i = WILL_NEVER + 1; i < WILL_ALWAYS; i++)
-    {
-      int idx;
-      for(idx=0;idx<HASHSIZE;idx++)
-       {
-          struct neighbor_entry *a_neighbor;
-         for(a_neighbor = neighbortable[idx].next;
-             a_neighbor != &neighbortable[idx];
-             a_neighbor = a_neighbor->next)
-           {
+  for(i = WILL_NEVER + 1; i < WILL_ALWAYS; i++) {
+
+    OLSR_FOR_ALL_NBR_ENTRIES(a_neighbor) {
              
-             if(a_neighbor->willingness != i)
-               continue;
+      if (a_neighbor->willingness != i) {
+        continue;
+      }
              
-             if(a_neighbor->is_mpr)
-               {
-                  struct neighbor_2_list_entry *two_hop_list;
-                 //printf("\tChecking %s\n", olsr_ip_to_string(&buf, &a_neighbor->neighbor_main_addr));
-                 remove = 1;
+      if (a_neighbor->is_mpr) {
+        remove = 1;
 
-                 for(two_hop_list = a_neighbor->neighbor_2_list.next;
-                     two_hop_list != &a_neighbor->neighbor_2_list;
-                     two_hop_list = two_hop_list->next)
-                   {
+        for (two_hop_list = a_neighbor->neighbor_2_list.next;
+             two_hop_list != &a_neighbor->neighbor_2_list;
+             two_hop_list = two_hop_list->next) {
                      
-                      const struct neighbor_entry * const dup_neighbor = olsr_lookup_neighbor_table(&two_hop_list->neighbor_2->neighbor_2_addr);
+          dup_neighbor = olsr_lookup_neighbor_table(&two_hop_list->neighbor_2->neighbor_2_addr);
                      
-                     if((dup_neighbor != NULL) && (dup_neighbor->status != NOT_SYM))
-                       continue;
-                     
-                     //printf("\t[%s] coverage %d\n", olsr_ip_to_string(&buf, &two_hop_list->neighbor_2->neighbor_2_addr), two_hop_list->neighbor_2->mpr_covered_count);
-                     /* Do not remove if we find a entry which need this MPR */
-                     if(two_hop_list->neighbor_2->mpr_covered_count <= olsr_cnf->mpr_coverage)
-                       remove = 0;
+          if ((dup_neighbor != NULL) && (dup_neighbor->status != NOT_SYM)) {
+            continue;
+          }
                      
-                   }
-                 if(remove)
-                   {
+          //printf("\t[%s] coverage %d\n", olsr_ip_to_string(&buf, &two_hop_list->neighbor_2->neighbor_2_addr), two_hop_list->neighbor_2->mpr_covered_count);
+          /* Do not remove if we find a entry which need this MPR */
+          if (two_hop_list->neighbor_2->mpr_covered_count <= olsr_cnf->mpr_coverage) {
+            remove = 0;
+          }      
+        }
+
+        if (remove) {
 #ifndef NODEBUG
-                      struct ipaddr_str buf;
+          struct ipaddr_str buf;
 #endif
-                     OLSR_PRINTF(3, "MPR OPTIMIZE: removiong mpr %s\n\n", olsr_ip_to_string(&buf, &a_neighbor->neighbor_main_addr));
-                     a_neighbor->is_mpr = OLSR_FALSE;
-                   }
-               }
-           }
-       }
-    }
+          OLSR_PRINTF(3, "MPR OPTIMIZE: removiong mpr %s\n\n", olsr_ip_to_string(&buf, &a_neighbor->neighbor_main_addr));
+          a_neighbor->is_mpr = OLSR_FALSE;
+        }
+      }
+    } OLSR_FOR_ALL_NBR_ENTRIES_END(a_neighbor);
+  }
 }
 
 void
@@ -606,22 +575,27 @@ olsr_print_mpr_set(void)
 {
 #ifndef NODEBUG
   /* The whole function makes no sense without it. */
-  int idx;
+  struct neighbor_entry *a_neighbor;
 
   OLSR_PRINTF(1, "MPR SET: ");
 
-  for(idx = 0; idx < HASHSIZE; idx++) {
-    struct neighbor_entry *a_neighbor;
-    for(a_neighbor = neighbortable[idx].next; a_neighbor != &neighbortable[idx]; a_neighbor = a_neighbor->next) { 
-      /* 
-       * Remove MPR settings
-       */
-      if(a_neighbor->is_mpr) {
-        struct ipaddr_str buf;
-        OLSR_PRINTF(1, "[%s] ", olsr_ip_to_string(&buf, &a_neighbor->neighbor_main_addr));
-      }
+  OLSR_FOR_ALL_NBR_ENTRIES(a_neighbor) {
+
+    /* 
+     * Remove MPR settings
+     */
+    if (a_neighbor->is_mpr) {
+      struct ipaddr_str buf;
+      OLSR_PRINTF(1, "[%s] ", olsr_ip_to_string(&buf, &a_neighbor->neighbor_main_addr));
     }
-  }
+  } OLSR_FOR_ALL_NBR_ENTRIES_END(a_neighbor);
+
   OLSR_PRINTF(1, "\n");
 #endif
 }
+
+/*
+ * Local Variables:
+ * c-basic-offset: 2
+ * End:
+ */
index d209fbe..7b58fe9 100644 (file)
@@ -59,11 +59,10 @@ void
 olsr_init_mprs_set(void)
 {
   OLSR_PRINTF(5, "MPRS: Init\n");
+
   /* Initial values */
   ansn = 0;
 
-  olsr_register_timeout_function(&olsr_time_out_mprs_set, OLSR_TRUE);
-  
   mprs_list.next = &mprs_list;
   mprs_list.prev = &mprs_list;
 }
@@ -93,6 +92,49 @@ olsr_is_mpr(void)
 }
 #endif
 
+
+/**
+ * Wrapper for the timer callback.
+ */
+static void
+olsr_expire_mpr_sel_entry(void *context)
+{
+#if !defined(NODEBUG) && defined(DEBUG)
+  struct ipaddr_str buf;
+#endif
+  struct mpr_selector *mpr_sel;
+
+  mpr_sel = (struct mpr_selector *)context;
+  mpr_sel->MS_timer = NULL;
+
+#ifdef DEBUG
+  OLSR_PRINTF(1, "MPRS: Timing out %st\n",
+              olsr_ip_to_string(&buf, &mpr_sel->MS_main_addr));
+#endif
+
+  DEQUEUE_ELEM(mpr_sel);
+
+  /* Delete entry */
+  free(mpr_sel);
+  signal_link_changes(OLSR_TRUE);
+}
+
+
+/**
+ * Set the mpr selector expiration timer.
+ *
+ * all timer setting shall be done using this function.
+ * The timer param is a relative timer expressed in milliseconds.
+ */
+static void
+olsr_set_mpr_sel_timer(struct mpr_selector *mpr_sel, unsigned int rel_timer)
+{
+
+  olsr_set_timer(&mpr_sel->MS_timer, rel_timer, OLSR_MPR_SEL_JITTER,
+                 OLSR_TIMER_ONESHOT, &olsr_expire_mpr_sel_entry, mpr_sel, 0);
+}
+
+
 /**
  *Add a MPR selector to the MPR selector set
  *
@@ -112,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;
-  new_entry->MS_time = GET_TIMESTAMP(vtime*1000);
-
+  olsr_set_mpr_sel_timer(new_entry, vtime * MSEC_PER_SEC);
   /* Queue */
   QUEUE_ELEM(mprs_list, new_entry);
   /*
@@ -182,42 +222,10 @@ olsr_update_mprs_set(const union olsr_ip_addr *addr, float vtime)
     signal_link_changes(OLSR_TRUE);
     return 1;
   }
-  mprs->MS_time = GET_TIMESTAMP(vtime*1000);
+  olsr_set_mpr_sel_timer(mprs, vtime * MSEC_PER_SEC);
   return 0;
 }
 
-/**
- *Time out MPR selector entries
- *
- *@return nada
- */
-void
-olsr_time_out_mprs_set(void)
-{
-  struct mpr_selector *mprs = mprs_list.next;
-
-  while(mprs != &mprs_list) {
-      if(TIMED_OUT(mprs->MS_time))
-       {
-         /* Dequeue */
-         struct mpr_selector *mprs_to_delete = mprs;
-#ifndef NODEBUG
-          struct ipaddr_str buf;
-#endif
-         mprs = mprs->next;
-
-         OLSR_PRINTF(1, "MPRS: Timing out %s\n", olsr_ip_to_string(&buf, &mprs_to_delete->MS_main_addr));
-
-         DEQUEUE_ELEM(mprs_to_delete);
-
-         /* Delete entry */
-         free(mprs_to_delete);
-         signal_link_changes(OLSR_TRUE);
-       }
-      else
-       mprs = mprs->next;
-    }
-}
 
 #if 0
 /**
@@ -238,3 +246,8 @@ olsr_print_mprs_set(void)
 }
 #endif
 
+/*
+ * Local Variables:
+ * c-basic-offset: 2
+ * End:
+ */
index 4eb9ebc..e00ccdc 100644 (file)
 struct mpr_selector
 {
   union olsr_ip_addr  MS_main_addr;
-  clock_t             MS_time;
+  struct timer_entry  *MS_timer;
   struct mpr_selector *next;
   struct mpr_selector *prev;
 };
 
+#define OLSR_MPR_SEL_JITTER 5 /* percent */
 
 #if 0
 olsr_bool
@@ -88,3 +89,9 @@ olsr_print_mprs_set(void);
 #endif
 
 #endif
+
+/*
+ * Local Variables:
+ * c-basic-offset: 2
+ * End:
+ */
index 9f2eeef..bf71e4f 100644 (file)
@@ -59,7 +59,6 @@ olsr_init_neighbor_table(void)
 {
   int i;
 
-  olsr_register_timeout_function(&olsr_time_out_neighborhood_tables, OLSR_TRUE);
   for(i = 0; i < HASHSIZE; i++)
     {
       neighbortable[i].next = &neighbortable[i];
@@ -67,38 +66,61 @@ olsr_init_neighbor_table(void)
     }
 }
 
+/**
+ * Unlink, delete and free a nbr2_list entry.
+ */
+static void
+olsr_del_nbr2_list(struct neighbor_2_list_entry *nbr2_list)
+{
+  struct neighbor_entry *nbr;
+  struct neighbor_2_entry *nbr2;
+
+  nbr = nbr2_list->nbr2_nbr;
+  nbr2 = nbr2_list->neighbor_2;
+
+  if (nbr2->neighbor_2_pointer < 1) {
+      DEQUEUE_ELEM(nbr2);
+      free(nbr2);
+  }
+
+  /*
+   * Kill running timers.
+   */
+  olsr_stop_timer(nbr2_list->nbr2_list_timer);
+  nbr2_list->nbr2_list_timer = NULL;
+  
+  /* Dequeue */
+  DEQUEUE_ELEM(nbr2_list);
+  
+  free(nbr2_list);
+
+  /* Set flags to recalculate the MPR set and the routing table */
+  changes_neighborhood = OLSR_TRUE;
+  changes_topology = OLSR_TRUE;
+}
 
 /**
- *Delete a two hop neighbor from a neighbors two 
- *hop neighbor list.
+ * Delete a two hop neighbor from a neighbors two hop neighbor list.
  *
- *@param neighbor the neighbor to delete the two hop 
- *neighbor from.
- *@param address the IP address of the two hop neighbor 
- *to delete.
+ * @param neighbor the neighbor to delete the two hop neighbor from.
+ * @param address the IP address of the two hop neighbor to delete.
  *
- *@return positive if entry deleted
+ * @return positive if entry deleted
  */
 int
 olsr_delete_neighbor_2_pointer(struct neighbor_entry *neighbor, union olsr_ip_addr *address)
 {
-
-  struct neighbor_2_list_entry *entry;
+  struct neighbor_2_list_entry *nbr2_list;
   
-  entry = neighbor->neighbor_2_list.next;
+  nbr2_list = neighbor->neighbor_2_list.next;
 
-  while(entry != &neighbor->neighbor_2_list)
-    {      
-      if(ipequal(&entry->neighbor_2->neighbor_2_addr, address))
-       {
-         /* Dequeue */
-         DEQUEUE_ELEM(entry);
-         /* Delete */
-         free(entry);
-         return 1;       
-       }
-      entry = entry->next;      
+  while (nbr2_list != &neighbor->neighbor_2_list) {
+    if (ipequal(&nbr2_list->neighbor_2->neighbor_2_addr, address)) {
+      olsr_del_nbr2_list(nbr2_list);
+      return 1;          
     }
+    nbr2_list = nbr2_list->next;      
+  }
   return 0;
 }
 
@@ -152,7 +174,7 @@ olsr_delete_neighbor_table(const union olsr_ip_addr *neighbor_addr)
 
   //printf("inserting neighbor\n");
 
-  hash = olsr_hashing(neighbor_addr);
+  hash = olsr_ip_hashing(neighbor_addr);
 
   entry = neighbortable[hash].next;
 
@@ -173,28 +195,15 @@ olsr_delete_neighbor_table(const union olsr_ip_addr *neighbor_addr)
 
   two_hop_list = entry->neighbor_2_list.next;
 
-  while(two_hop_list != &entry->neighbor_2_list)
-    {
-      struct neighbor_2_entry *two_hop_entry = two_hop_list->neighbor_2;
-      
-      two_hop_entry->neighbor_2_pointer--;
-
-      olsr_delete_neighbor_pointer(two_hop_entry, &entry->neighbor_main_addr);
-
-      /* Delete entry if it has no more one hop neighbors pointing to it */
-      if(two_hop_entry->neighbor_2_pointer < 1)
-       {
-         DEQUEUE_ELEM(two_hop_entry);
-
-         free(two_hop_entry);
-       }
-
-
+  while (two_hop_list != &entry->neighbor_2_list) {
       two_hop_to_delete = two_hop_list;
       two_hop_list = two_hop_list->next;
-      /* Delete entry */
-      free(two_hop_to_delete);
-      
+
+      two_hop_to_delete->neighbor_2->neighbor_2_pointer--;
+      olsr_delete_neighbor_pointer(two_hop_to_delete->neighbor_2,
+                                   &entry->neighbor_main_addr);
+
+      olsr_del_nbr2_list(two_hop_to_delete);
     }
 
 
@@ -223,7 +232,7 @@ olsr_insert_neighbor_table(const union olsr_ip_addr *main_addr)
   olsr_u32_t             hash;
   struct neighbor_entry  *new_neigh;
   
-  hash = olsr_hashing(main_addr);
+  hash = olsr_ip_hashing(main_addr);
 
   /* Check if entry exists */
   
@@ -292,7 +301,7 @@ struct neighbor_entry *
 olsr_lookup_neighbor_table_alias(const union olsr_ip_addr *dst)
 {
   struct neighbor_entry  *entry;
-  olsr_u32_t             hash = olsr_hashing(dst);
+  olsr_u32_t             hash = olsr_ip_hashing(dst);
   
   //printf("\nLookup %s\n", olsr_ip_to_string(&buf, dst));
   for(entry = neighbortable[hash].next;
@@ -357,69 +366,28 @@ update_neighbor_status(struct neighbor_entry *entry, int lnk)
 }
 
 
-
 /**
- *Times out the entries in the two hop neighbor table and 
- *deletes those who have exceeded their time to live since 
- *last update.
- *
- *@return nada
+ * Callback for the nbr2_list timer.
  */
-
 void
-olsr_time_out_two_hop_neighbors(struct neighbor_entry  *neighbor)
+olsr_expire_nbr2_list(void *context)
 {
-  struct neighbor_2_list_entry *two_hop_list = neighbor->neighbor_2_list.next;
+  struct neighbor_2_list_entry *nbr2_list;
+  struct neighbor_entry *nbr;
+  struct neighbor_2_entry *nbr2; 
 
-  while(two_hop_list != &neighbor->neighbor_2_list)
-    {
-      if(TIMED_OUT(two_hop_list->neighbor_2_timer))
-       {
-         struct neighbor_2_list_entry *two_hop_to_delete;
-         struct neighbor_2_entry      *two_hop_entry = two_hop_list->neighbor_2;
+  nbr2_list = (struct neighbor_2_list_entry *)context;
+  nbr2_list->nbr2_list_timer = NULL;
 
-         two_hop_entry->neighbor_2_pointer--;
-         olsr_delete_neighbor_pointer(two_hop_entry, &neighbor->neighbor_main_addr);
-         
-         if(two_hop_entry->neighbor_2_pointer < 1)
-           {
-             DEQUEUE_ELEM(two_hop_entry);
-             free(two_hop_entry);
-           }
-         
-         two_hop_to_delete = two_hop_list;
-         two_hop_list = two_hop_list->next;
-         
-         /* Dequeue */
-         DEQUEUE_ELEM(two_hop_to_delete);
-         
-         free(two_hop_to_delete);
+  nbr = nbr2_list->nbr2_nbr;
+  nbr2 = nbr2_list->neighbor_2;
 
-         /* This flag is set to OLSR_TRUE to recalculate the MPR set and the routing table*/
-         changes_neighborhood = OLSR_TRUE;
-         changes_topology = OLSR_TRUE;
-         
-       }
-      else
-       two_hop_list = two_hop_list->next;
+  nbr2->neighbor_2_pointer--;
+  olsr_delete_neighbor_pointer(nbr2, &nbr->neighbor_main_addr); 
 
-    }
+  olsr_del_nbr2_list(nbr2_list);
 }
 
-void
-olsr_time_out_neighborhood_tables(void)
-{
-  int idx;
-  
-  for(idx=0;idx<HASHSIZE;idx++)
-    {
-      struct neighbor_entry *entry;
-      for(entry = neighbortable[idx].next; entry != &neighbortable[idx]; entry = entry->next)
-       {         
-         olsr_time_out_two_hop_neighbors(entry);
-       }
-    }
-}
 
 /**
  *Prints the registered neighbors and two hop neighbors
@@ -467,3 +435,9 @@ olsr_print_neighbor_table(void)
   }
 #endif
 }
+
+/*
+ * Local Variables:
+ * c-basic-offset: 2
+ * End:
+ */
index fb5cc4a..9ddecb8 100644 (file)
 
 struct neighbor_2_list_entry 
 {
+  struct neighbor_entry *nbr2_nbr; /* backpointer to owning nbr entry */
   struct neighbor_2_entry      *neighbor_2;
-  clock_t                     neighbor_2_timer;
+  struct timer_entry *nbr2_list_timer;
   struct neighbor_2_list_entry *next;
   struct neighbor_2_list_entry *prev;
 };
 
-
+#define OLSR_NBR2_LIST_JITTER 5 /* percent */
 
 struct neighbor_entry
 {
@@ -71,6 +72,15 @@ struct neighbor_entry
   struct neighbor_entry        *prev;
 };
 
+#define OLSR_FOR_ALL_NBR_ENTRIES(nbr) \
+{ \
+  int _idx; \
+  for (_idx = 0; _idx < HASHSIZE; _idx++) { \
+    for(nbr = neighbortable[_idx].next; \
+        nbr != &neighbortable[_idx]; \
+        nbr = nbr->next)
+#define OLSR_FOR_ALL_NBR_ENTRIES_END(nbr) }}
+
 
 /*
  * The neighbor table
@@ -104,6 +114,7 @@ olsr_time_out_two_hop_neighbors(struct neighbor_entry  *);
 
 void
 olsr_time_out_neighborhood_tables(void);
+void olsr_expire_nbr2_list(void *);
 
 void
 olsr_print_neighbor_table(void);
@@ -113,3 +124,9 @@ int
 update_neighbor_status(struct neighbor_entry *, int);
 
 #endif
+
+/*
+ * Local Variables:
+ * c-basic-offset: 2
+ * End:
+ */
index a721020..91b8a52 100644 (file)
@@ -442,7 +442,6 @@ net_output(struct interface *ifp)
   // if we've just transmitted a TC message, let Dijkstra use the current
   // link qualities for the links to our neighbours
 
-  olsr_update_dijkstra_link_qualities();
   lq_tc_pending = OLSR_FALSE;
 
   return retval;
index 0af5d34..a8f0967 100644 (file)
@@ -169,7 +169,7 @@ olsr_process_changes(void)
 
   /* calculate the routing table */
   if (changes_neighborhood || changes_topology || changes_hna) {
-    olsr_calculate_routing_table();
+    olsr_calculate_routing_table(NULL);
   }
   
   if (olsr_cnf->debug_level > 0)
@@ -239,9 +239,6 @@ olsr_init_tables(void)
   /* Initialize link set */
   olsr_init_link_set();
 
-  /* Initialize duplicate table */
-  olsr_init_duplicate_table();
-
   /* Initialize neighbor table */
   olsr_init_neighbor_table();
 
@@ -262,6 +259,12 @@ olsr_init_tables(void)
 
   /* Initialize HNA set */
   olsr_init_hna_set();  
+
+  /* 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,
+                     OLSR_TIMER_PERIODIC, &olsr_calculate_routing_table, NULL, 0);
+  }
 }
 
 /**
@@ -276,9 +279,6 @@ olsr_init_tables(void)
  */
 int
 olsr_forward_message(union olsr_message *m, 
-                    union olsr_ip_addr *originator, 
-                    olsr_u16_t seqno,
-                    struct interface *in_if, 
                     union olsr_ip_addr *from_addr)
 {
   union olsr_ip_addr *src;
@@ -300,14 +300,6 @@ olsr_forward_message(union olsr_message *m,
     if (2 > m->v6.ttl || 255 < (int)m->v6.hopcnt + (int)m->v6.ttl) return 0;
   }
 
-  if(!olsr_check_dup_table_fwd(originator, seqno, &in_if->ip_addr))
-    {
-#ifdef DEBUG
-      OLSR_PRINTF(3, "Message already forwarded!\n");
-#endif
-      return 0;
-    }
-
   /* Lookup sender address */
   src = mid_lookup_main_addr(from_addr);
   if(!src)
@@ -320,10 +312,6 @@ olsr_forward_message(union olsr_message *m,
   if(neighbor->status != SYM)
     return 0;
 
-  /* Update duplicate table interface */
-  olsr_update_dup_entry(originator, seqno, &in_if->ip_addr);
-
-  
   /* Check MPR */
   if(olsr_lookup_mprs_set(src) == NULL)
     {
@@ -350,9 +338,6 @@ olsr_forward_message(union olsr_message *m,
       m->v6.ttl--; 
     }
 
-  /* Update dup forwarded */
-  olsr_set_dup_forward(originator, seqno);
-
   /* Update packet data */
   msgsize = ntohs(m->v4.olsr_msgsize);
 
@@ -404,9 +389,14 @@ set_buffer_timer(struct interface *ifn)
 void
 olsr_init_willingness(void)
 {
-  if(olsr_cnf->willingness_auto)
-    olsr_register_scheduler_event(&olsr_update_willingness, 
-                                 NULL, olsr_cnf->will_int, olsr_cnf->will_int, NULL);
+  if (olsr_cnf->willingness_auto) {
+
+    /* Run it first and then periodic. */
+    olsr_update_willingness(NULL);
+
+    olsr_start_timer((unsigned int)olsr_cnf->will_int * MSEC_PER_SEC, 5,
+                     OLSR_TIMER_PERIODIC, &olsr_update_willingness, NULL, 0);
+  }
 }
 
 void
index 8f50a75..46856d9 100644 (file)
@@ -64,9 +64,6 @@ get_msg_seqno(void);
 
 int
 olsr_forward_message(union olsr_message *, 
-                    union olsr_ip_addr *, 
-                    olsr_u16_t, 
-                    struct interface *, 
                     union olsr_ip_addr *);
 
 void
index 56d45a1..9ebcfa1 100644 (file)
 #define MID_INTERVAL          TC_INTERVAL
 #define HNA_INTERVAL          TC_INTERVAL
 
+
+/* Emission Jitter */
+#define HELLO_JITTER         25 /* percent */
+#define HNA_JITTER           25 /* percent */
+#define MID_JITTER           25 /* percent */
+#define TC_JITTER            25 /* percent */
+
 /*
  *Holding Time
  */
@@ -434,3 +441,9 @@ union olsr_packet
 
 
 #endif
+
+/*
+ * Local Variables:
+ * c-basic-offset: 2
+ * End:
+ */
index e644974..691ad70 100644 (file)
@@ -64,6 +64,9 @@ typedef enum {
     OLSR_TRUE
 } olsr_bool;
 
+/* user defined cookies */
+typedef uint16_t        olsr_cookie_t;
+
 #if defined linux || defined __MacOSX__ || defined WIN32 || defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__
 
 typedef uint8_t         olsr_u8_t;
@@ -95,4 +98,6 @@ struct olsr_ip_prefix {
   olsr_u8_t prefix_len;
 };
 
+typedef olsr_u32_t olsr_linkcost;
+
 #endif
index e85dce1..24bb1cb 100644 (file)
@@ -48,6 +48,7 @@
 #include "neighbor_table.h"
 #include "build_msg.h"
 #include "net_olsr.h"
+#include "lq_plugin.h"
 
 static olsr_bool sending_tc = OLSR_FALSE;
 
@@ -89,7 +90,6 @@ olsr_build_hello_packet(struct hello_message *message, struct interface *outif)
   struct hello_neighbor   *message_neighbor, *tmp_neigh;
   struct link_entry       *links;
   struct neighbor_entry   *neighbor;
-  int                     idx;
 
 #ifdef DEBUG
   OLSR_PRINTF(3, "\tBuilding HELLO on interface \"%s\"\n", outif->int_name ? outif->int_name : "<null>");
@@ -116,190 +116,168 @@ olsr_build_hello_packet(struct hello_message *message, struct interface *outif)
   OLSR_PRINTF(5, "On link:\n");
 #endif
 
-  /* Get the links of this interface */
-  links = get_link_set();
-
-  while(links != NULL)
-    {      
+  /* Walk all links of this interface */
+  OLSR_FOR_ALL_LINK_ENTRIES(links) {
 #if !defined(NODEBUG) && defined(DEBUG)
-      struct ipaddr_str buf;
+    struct ipaddr_str buf;
 #endif
-      int lnk = lookup_link_status(links);
-      /* Update the status */
-      
-      /* Check if this link tuple is registered on the outgoing interface */
-      if(!ipequal(&links->local_iface_addr, &outif->ip_addr))
-       {
-         links = links->next;
-         continue;
-       }
-
-      message_neighbor = olsr_malloc(sizeof(struct hello_neighbor), "Build HELLO");
+    int lnk = lookup_link_status(links);
+    /* Update the status */
       
+    /* Check if this link tuple is registered on the outgoing interface */
+    if (!ipequal(&links->local_iface_addr, &outif->ip_addr)) {
+      continue;
+    }
 
-      /* Find the link status */
-      message_neighbor->link = lnk;
+    message_neighbor = olsr_malloc_hello_neighbor("Build HELLO");
+      
+    /* Find the link status */
+    message_neighbor->link = lnk;
+
+    /*
+     * Calculate neighbor status
+     */
+    /* 
+     * 2.1  If the main address, corresponding to
+     *      L_neighbor_iface_addr, is included in the MPR set:
+     *
+     *            Neighbor Type = MPR_NEIGH
+     */
+    if (links->neighbor->is_mpr) {
+      message_neighbor->status = MPR_NEIGH;
+    }
+    /*
+     *  2.2  Otherwise, if the main address, corresponding to
+     *       L_neighbor_iface_addr, is included in the neighbor set:
+     */
+      
+    /* NOTE:
+     * It is garanteed to be included when come this far
+     * due to the extentions made in the link sensing
+     * regarding main addresses.
+     */
+    else {
 
       /*
-       * Calculate neighbor status
-       */
-      /* 
-       * 2.1  If the main address, corresponding to
-       *      L_neighbor_iface_addr, is included in the MPR set:
+       *   2.2.1
+       *        if N_status == SYM
        *
-       *            Neighbor Type = MPR_NEIGH
+       *             Neighbor Type = SYM_NEIGH
        */
-      if(links->neighbor->is_mpr)
-       {
-         message_neighbor->status = MPR_NEIGH;
-       }
+      if (links->neighbor->status == SYM) {
+        message_neighbor->status = SYM_NEIGH;
+      }
+
       /*
-       *  2.2  Otherwise, if the main address, corresponding to
-       *       L_neighbor_iface_addr, is included in the neighbor set:
-       */
-      
-      /* NOTE:
-       * It is garanteed to be included when come this far
-       * due to the extentions made in the link sensing
-       * regarding main addresses.
+       *   2.2.2
+       *        Otherwise, if N_status == NOT_SYM
+       *             Neighbor Type = NOT_NEIGH
        */
-      else
-       {
-         /*
-          *   2.2.1
-          *        if N_status == SYM
-          *
-          *             Neighbor Type = SYM_NEIGH
-          */
-         if(links->neighbor->status == SYM)
-           {
-             message_neighbor->status = SYM_NEIGH;
-           }
-         /*
-          *   2.2.2
-          *        Otherwise, if N_status == NOT_SYM
-          *             Neighbor Type = NOT_NEIGH
-          */
-         else
-           if(links->neighbor->status == NOT_SYM)
-             {
-               message_neighbor->status = NOT_NEIGH;
-             }
-       }
+      else if (links->neighbor->status == NOT_SYM) {
+          message_neighbor->status = NOT_NEIGH;
+        }
+    }
   
-      /* Set the remote interface address */
-      message_neighbor->address = links->neighbor_iface_addr;
+    /* Set the remote interface address */
+    message_neighbor->address = links->neighbor_iface_addr;
       
-      /* Set the main address */
-      message_neighbor->main_address = links->neighbor->neighbor_main_addr;
+    /* Set the main address */
+    message_neighbor->main_address = links->neighbor->neighbor_main_addr;
 #ifdef DEBUG
-      OLSR_PRINTF(5, "Added: %s -  status %d\n", olsr_ip_to_string(&buf, &message_neighbor->address), message_neighbor->status);
+    OLSR_PRINTF(5, "Added: %s -  status %d\n", olsr_ip_to_string(&buf, &message_neighbor->address), message_neighbor->status);
 #endif
-      message_neighbor->next=message->neighbors;
-      message->neighbors=message_neighbor;         
+    message_neighbor->next=message->neighbors;
+    message->neighbors=message_neighbor;           
       
-      links = links->next;
-    }
+  } OLSR_FOR_ALL_LINK_ENTRIES_END(links);
   
   /* Add the links */
 
-
-
 #ifdef DEBUG
     OLSR_PRINTF(5, "Not on link:\n");
 #endif
 
   /* Add the rest of the neighbors if running on multiple interfaces */
   
-  if(ifnet != NULL && ifnet->int_next != NULL)
-    for(idx=0;idx<HASHSIZE;idx++)
-      {       
-       for(neighbor = neighbortable[idx].next;
-           neighbor != &neighbortable[idx];
-           neighbor=neighbor->next)
-         {
+  if (ifnet != NULL && ifnet->int_next != NULL)
+    OLSR_FOR_ALL_NBR_ENTRIES(neighbor) {
+
 #if !defined(NODEBUG) && defined(DEBUG)
-            struct ipaddr_str buf;
+    struct ipaddr_str buf;
 #endif
-           /* Check that the neighbor is not added yet */
-           tmp_neigh = message->neighbors;
-           //printf("Checking that the neighbor is not yet added\n");
-           while(tmp_neigh)
-             {
-               if(ipequal(&tmp_neigh->main_address, &neighbor->neighbor_main_addr))
-                 {
-                   //printf("Not adding duplicate neighbor %s\n", olsr_ip_to_string(&neighbor->neighbor_main_addr));
-                   break;
-                 }
-               tmp_neigh = tmp_neigh->next;
-             }
-
-           if(tmp_neigh)
-             continue;
-           
-           message_neighbor = olsr_malloc(sizeof(struct hello_neighbor), "Build HELLO 2");
+    /* Check that the neighbor is not added yet */
+    tmp_neigh = message->neighbors;
+    //printf("Checking that the neighbor is not yet added\n");
+    while (tmp_neigh) {
+      if (ipequal(&tmp_neigh->main_address, &neighbor->neighbor_main_addr)) {
+        //printf("Not adding duplicate neighbor %s\n", olsr_ip_to_string(&neighbor->neighbor_main_addr));
+        break;
+      }
+      tmp_neigh = tmp_neigh->next;
+    }
+
+    if (tmp_neigh) {
+      continue;
+    }
            
-           message_neighbor->link = UNSPEC_LINK;
+         message_neighbor = olsr_malloc_hello_neighbor("Build HELLO 2");
            
-           /*
-            * Calculate neighbor status
-            */
-           /* 
-            * 2.1  If the main address, corresponding to
-            *      L_neighbor_iface_addr, is included in the MPR set:
-            *
-            *            Neighbor Type = MPR_NEIGH
-            */
-           if(neighbor->is_mpr)
-             {
-               message_neighbor->status = MPR_NEIGH;
-             }
-           /*
-            *  2.2  Otherwise, if the main address, corresponding to
-            *       L_neighbor_iface_addr, is included in the neighbor set:
-            */
+    message_neighbor->link = UNSPEC_LINK;
            
-           /* NOTE:
-            * It is garanteed to be included when come this far
-            * due to the extentions made in the link sensing
-            * regarding main addresses.
-            */
-           else
-             {
-               /*
-                *   2.2.1
-                *        if N_status == SYM
-                *
-                *             Neighbor Type = SYM_NEIGH
-                */
-               if(neighbor->status == SYM)
-                 {
-                   message_neighbor->status = SYM_NEIGH;
-                 }
-               /*
-                *   2.2.2
-                *        Otherwise, if N_status == NOT_SYM
-                *             Neighbor Type = NOT_NEIGH
-                */
-               else
-                 if(neighbor->status == NOT_SYM)
-                   {
-                     message_neighbor->status = NOT_NEIGH;                   
-                   }
-             }
+    /*
+     * Calculate neighbor status
+     */
+    /* 
+     * 2.1  If the main address, corresponding to
+     *      L_neighbor_iface_addr, is included in the MPR set:
+     *
+     *            Neighbor Type = MPR_NEIGH
+     */
+    if (neighbor->is_mpr) {
+      message_neighbor->status = MPR_NEIGH;
+    }
+    /*
+     *  2.2  Otherwise, if the main address, corresponding to
+     *       L_neighbor_iface_addr, is included in the neighbor set:
+     */
            
+    /* NOTE:
+     * It is garanteed to be included when come this far
+     * due to the extentions made in the link sensing
+     * regarding main addresses.
+     */
+    else {
+
+      /*
+       *   2.2.1
+       *        if N_status == SYM
+       *
+       *             Neighbor Type = SYM_NEIGH
+       */
+      if (neighbor->status == SYM) {
+        message_neighbor->status = SYM_NEIGH;
+      }
 
-           message_neighbor->address = neighbor->neighbor_main_addr;
+      /*
+       *   2.2.2
+       *        Otherwise, if N_status == NOT_SYM
+       *             Neighbor Type = NOT_NEIGH
+       */
+      else if (neighbor->status == NOT_SYM) {
+        message_neighbor->status = NOT_NEIGH;                
+      }
+    }
+           
 
-           message_neighbor->main_address = neighbor->neighbor_main_addr;
+    message_neighbor->address = neighbor->neighbor_main_addr;
+    message_neighbor->main_address = neighbor->neighbor_main_addr;
 #ifdef DEBUG
-           OLSR_PRINTF(5, "Added: %s -  status  %d\n", olsr_ip_to_string(&buf, &message_neighbor->address), message_neighbor->status);
+    OLSR_PRINTF(5, "Added: %s -  status  %d\n", olsr_ip_to_string(&buf, &message_neighbor->address), message_neighbor->status);
 #endif
-           message_neighbor->next=message->neighbors;
-           message->neighbors=message_neighbor;            
-         }
-      }
-  
+    message_neighbor->next=message->neighbors;
+    message->neighbors=message_neighbor;       
+    
+  } OLSR_FOR_ALL_NBR_ENTRIES_END(neighbor);
 
   return 0;
 }
@@ -339,10 +317,7 @@ int
 olsr_build_tc_packet(struct tc_message *message)
 {
   struct tc_mpr_addr     *message_mpr;
-  //struct mpr_selector       *mprs;
-  int                     idx;
   struct neighbor_entry  *entry;
-  //struct mpr_selector_hash  *mprs_hash;
   olsr_bool entry_added = OLSR_FALSE;
 
   message->multipoint_relay_selector_address=NULL;
@@ -357,82 +332,67 @@ olsr_build_tc_packet(struct tc_message *message)
   
 
   /* Loop trough all neighbors */  
-  for(idx=0;idx<HASHSIZE;idx++)
+  OLSR_FOR_ALL_NBR_ENTRIES(entry) {
+    if (entry->status != SYM) {
+      continue;
+    }
+
+    switch (olsr_cnf->tc_redundancy) {
+    case(2):
     {
-      for(entry = neighbortable[idx].next;
-         entry != &neighbortable[idx];
-         entry = entry->next)
-       {
-         if(entry->status != SYM)
-           continue;
-
-         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(sizeof(struct 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;
-               message->multipoint_relay_selector_address = message_mpr;
-               entry_added = OLSR_TRUE;
-               
-               break;
-             }
-           case(1):
-             {
-               /* 1 = Add all MPR selectors and selected MPRs */
-               if((entry->is_mpr) ||
-                  (olsr_lookup_mprs_set(&entry->neighbor_main_addr) != NULL))
-                 {
-                   //printf("\t%s\n", olsr_ip_to_string(&mprs->mpr_selector_addr));
-                   message_mpr = olsr_malloc(sizeof(struct tc_mpr_addr), "Build TC 2");
-                   
-                   message_mpr->address = entry->neighbor_main_addr;
-                   message_mpr->next = message->multipoint_relay_selector_address;
-                   message->multipoint_relay_selector_address = message_mpr;
-                   entry_added = OLSR_TRUE;
-                 }
-               break;
-             }
-           default:
-             {
-               /* 0 = Add only MPR selectors(default) */
-               if(olsr_lookup_mprs_set(&entry->neighbor_main_addr) != NULL)
-                 {
-                   //printf("\t%s\n", olsr_ip_to_string(&mprs->mpr_selector_addr));
-                   message_mpr = olsr_malloc(sizeof(struct tc_mpr_addr), "Build TC 3");
-                   
-                   message_mpr->address = entry->neighbor_main_addr;
-                   message_mpr->next = message->multipoint_relay_selector_address;
-                   message->multipoint_relay_selector_address = message_mpr;
-                   entry_added = OLSR_TRUE;
-                 }
-               break;
-             }         
-         
-           } /* Switch */
-       } /* For */
-    } /* For idx */
-
-  if(entry_added)
+      message_mpr->address = entry->neighbor_main_addr;
+      message_mpr->next = message->multipoint_relay_selector_address;
+      message->multipoint_relay_selector_address = message_mpr;
+      entry_added = OLSR_TRUE;         
+      break;
+    }
+    case(1):
     {
-      sending_tc = OLSR_TRUE;
+      /* 1 = Add all MPR selectors and selected MPRs */
+      if ((entry->is_mpr) ||
+          (olsr_lookup_mprs_set(&entry->neighbor_main_addr) != NULL)) {
+        //printf("\t%s\n", olsr_ip_to_string(&mprs->mpr_selector_addr));
+        message_mpr = olsr_malloc_tc_mpr_addr("Build TC 2");
+                   
+        message_mpr->address = entry->neighbor_main_addr;
+        message_mpr->next = message->multipoint_relay_selector_address;
+        message->multipoint_relay_selector_address = message_mpr;
+        entry_added = OLSR_TRUE;
+      }
+      break;
     }
-  else
+    default:
     {
-      if(sending_tc)
-       {
-         /* Send empty TC */
-         OLSR_PRINTF(3, "No more MPR selectors - will send empty TCs\n");
-         set_empty_tc_timer(GET_TIMESTAMP((olsr_cnf->max_tc_vtime*3)*1000));
-
-         sending_tc = OLSR_FALSE;
-       }
+      /* 0 = Add only MPR selectors(default) */
+      if (olsr_lookup_mprs_set(&entry->neighbor_main_addr) != NULL) {
+        //printf("\t%s\n", olsr_ip_to_string(&mprs->mpr_selector_addr));
+        message_mpr = olsr_malloc_tc_mpr_addr("Build TC 3");
+                   
+        message_mpr->address = entry->neighbor_main_addr;
+        message_mpr->next = message->multipoint_relay_selector_address;
+        message->multipoint_relay_selector_address = message_mpr;
+        entry_added = OLSR_TRUE;
+      }
+      break;
+    }          
+         
+    } /* Switch */
+  } OLSR_FOR_ALL_NBR_ENTRIES_END(entry);
+
+  if (entry_added) {
+    sending_tc = OLSR_TRUE;
+  } else {
+    if (sending_tc) {
+      /* Send empty TC */
+      OLSR_PRINTF(3, "No more MPR selectors - will send empty TCs\n");
+      set_empty_tc_timer(GET_TIMESTAMP((olsr_cnf->max_tc_vtime*3)*1000));
+      sending_tc = OLSR_FALSE;
     }
-
+  }
 
   return 0;
 }
@@ -459,3 +419,9 @@ olsr_free_mid_packet(struct mid_message *message)
       free(tmp_adr2);
     }
 }
+
+/*
+ * Local Variables:
+ * c-basic-offset: 2
+ * End:
+ */
index c8d5cc0..9cce21b 100644 (file)
 
 #include "olsr_protocol.h"
 #include "interfaces.h"
-#include "fpm.h"
 
 struct hello_neighbor
 {
   olsr_u8_t             status;
   olsr_u8_t             link;
-#ifdef USE_FPM
-  fpm                   link_quality;
-  fpm                   neigh_link_quality;
-#else
-  double                link_quality;
-  double                neigh_link_quality;
-#endif
   union olsr_ip_addr    main_address;
   union olsr_ip_addr    address;
   struct hello_neighbor *next;
+  olsr_linkcost         cost;
+  char                  linkquality[0];
 };
 
 struct hello_message
@@ -76,15 +70,9 @@ struct hello_message
 
 struct tc_mpr_addr
 {
-#ifdef USE_FPM
-  fpm                link_quality;
-  fpm                neigh_link_quality;
-#else
-  double             link_quality;
-  double             neigh_link_quality;
-#endif
   union olsr_ip_addr address;
   struct tc_mpr_addr *next;
+  char                  linkquality[0];
 };
 
 struct tc_message
index 3094416..16785e8 100644 (file)
@@ -277,12 +277,6 @@ parse_packet(struct olsr *olsr, int size, struct interface *in_if, union olsr_ip
        }
     }
 
-  if (olsr_cnf->lq_level > 0)
-    {
-      olsr_update_packet_loss(from_addr, in_if,
-                              ntohs(olsr->olsr_seqno));
-    }
-  
   for ( ; count > 0; m = (union olsr_message *)((char *)m + (msgsize)))
     {
 
@@ -372,6 +366,19 @@ parse_packet(struct olsr *olsr, int size, struct interface *in_if, union olsr_ip
           continue;
         }
 
+      /* check for message duplicates */
+      if (olsr_cnf->ip_version == AF_INET) {
+        /* IPv4 */
+        if (olsr_shall_process_message(&m->v4.originator, ntohs(m->v4.seqno)) == 0) {
+          continue;
+        }
+      }
+      else {
+        /* IPv6 */
+        if (olsr_shall_process_message(&m->v6.originator, ntohs(m->v6.seqno)) == 0) {
+          continue;
+        }
+      }
 
       //printf("MESSAGETYPE: %d\n", m->v4.olsr_msgtype);
 
@@ -410,11 +417,7 @@ parse_packet(struct olsr *olsr, int size, struct interface *in_if, union olsr_ip
          if(!ipequal(&unkpacket.originator, &olsr_cnf->main_addr))
            {         
              /* Forward */
-             olsr_forward_message(m, 
-                                  &unkpacket.originator, 
-                                  unkpacket.seqno, 
-                                  in_if,
-                                  from_addr);
+             olsr_forward_message(m, from_addr);
            }
 
           /* Cancel loop here, otherwise olsrd just hangs forever at this point */
@@ -422,8 +425,6 @@ parse_packet(struct olsr *olsr, int size, struct interface *in_if, union olsr_ip
        }
 
     } /* for olsr_msg */ 
-
-
 }
 
 
index 2f922e9..7c7f860 100644 (file)
@@ -53,6 +53,7 @@
 #include "rebuild_packet.h"
 #include "scheduler.h"
 #include "net_olsr.h"
+#include "lq_plugin.h"
 
 #include <stddef.h>
 
@@ -114,7 +115,10 @@ process_message_neighbors(struct neighbor_entry *neighbor, const struct hello_me
           if (two_hop_neighbor_yet != NULL)
             {
               /* Updating the holding time for this neighbor */
-              two_hop_neighbor_yet->neighbor_2_timer = GET_TIMESTAMP(message->vtime*1000);
+              olsr_set_timer(&two_hop_neighbor_yet->nbr2_list_timer,
+                             message->vtime * MSEC_PER_SEC, OLSR_NBR2_LIST_JITTER,
+                             OLSR_TIMER_ONESHOT, &olsr_expire_nbr2_list,
+                             two_hop_neighbor_yet, 0);
               two_hop_neighbor = two_hop_neighbor_yet->neighbor_2;
 
               // For link quality OLSR, reset the path link quality here.
@@ -137,11 +141,7 @@ process_message_neighbors(struct neighbor_entry *neighbor, const struct hello_me
 
                       if (walker->neighbor == neighbor)
                         {
-#ifdef USE_FPM
-                          walker->path_link_quality = itofpm(0);
-#else
-                          walker->path_link_quality = 0.0;
-#endif
+                          walker->path_linkcost = LINK_COST_BROKEN;
                         }
                     }
                 }
@@ -191,16 +191,20 @@ process_message_neighbors(struct neighbor_entry *neighbor, const struct hello_me
         }
     }
 
-  // Separate, second and third pass for link quality OLSR
+  // Separate, second pass for link quality OLSR
 
   if (olsr_cnf->lq_level > 0)
     {
+         olsr_linkcost first_hop_pathcost;
       struct link_entry *lnk =
         get_best_link_to_neighbor(&neighbor->neighbor_main_addr);
 
       if(!lnk)
        return;
 
+      // calculate first hop path quality
+      first_hop_pathcost = lnk->linkcost;
+      
       // Second pass for link quality OLSR: calculate the best 2-hop
       // path costs to all the 2-hop neighbors indicated in the
       // HELLO message. Since the same 2-hop neighbor may be listed
@@ -240,138 +244,39 @@ process_message_neighbors(struct neighbor_entry *neighbor, const struct hello_me
 
                   if (walker->neighbor == neighbor)
                     {
-#ifdef USE_FPM
-                      fpm new_second_hop_link_quality, new_path_link_quality;
-#else
-                      double new_second_hop_link_quality, new_path_link_quality;
-#endif
-
-                      // path link quality = link quality between us
-                      // and our one-hop neighbor x link quality between
-                      // our one-hop neighbor and the two-hop neighbor
-
-                      // let's compare this to ETX:
-
-                      // 1 / LQ1 + 1 / LQ2 < 1 / LQ3 + 1 / LQ4 <=>
-                      // LQ1 * LQ2 > LQ3 * LQ4
+                      olsr_linkcost new_second_hop_linkcost, new_path_linkcost;
 
-                      // so comparing path link quality values with ">" is
-                      // equivalent to comparing ETX values with "<"
-
-                      // the link quality between the 1-hop neighbour and the
+                      // the link cost between the 1-hop neighbour and the
                       // 2-hop neighbour
 
-#ifdef USE_FPM
-                      new_second_hop_link_quality = 
-                        fpmmul(message_neighbors->link_quality,
-                               message_neighbors->neigh_link_quality);
-#else
-                      new_second_hop_link_quality = 
-                        message_neighbors->link_quality *
-                        message_neighbors->neigh_link_quality;
-#endif
+                      new_second_hop_linkcost = message_neighbors->cost;
 
-                      // the total quality for the route
+                      // the total cost for the route
                       // "us --- 1-hop --- 2-hop"
 
-#ifdef USE_FPM
-                      new_path_link_quality =
-                        fpmmul(new_second_hop_link_quality,
-                        fpmmul(lnk->loss_link_quality, lnk->neigh_link_quality));
-#else
-                      new_path_link_quality =
-                        new_second_hop_link_quality *
-                        lnk->loss_link_quality * lnk->neigh_link_quality;
-#endif
+                      new_path_linkcost =
+                        first_hop_pathcost + new_second_hop_linkcost;
 
                       // Only copy the link quality if it is better than what we have
                       // for this 2-hop neighbor
-                      if (new_path_link_quality > walker->path_link_quality)
-                        {
-                          walker->second_hop_link_quality = new_second_hop_link_quality;
-                          walker->path_link_quality = new_path_link_quality;
-                        }
-                    }
-                }
-            }
-        }
-
-      // Third pass for link quality OLSR: check if the 2-hop path qualities have
-      // actually changed. If so, signal this through the 'changes_neighborhood'
-      // and 'changes_topology' booleans. Keep a 'saved_path_link_quality' for
-      // later reference.
-      for(message_neighbors = message->neighbors;
-          message_neighbors != NULL;
-          message_neighbors = message_neighbors->next)
-        {
-          if(if_ifwithaddr(&message_neighbors->address) != NULL)
-            continue;
-
-          if(((message_neighbors->status == SYM_NEIGH) ||
-              (message_neighbors->status == MPR_NEIGH)))
-            {
-              struct neighbor_list_entry *walker;
-              struct neighbor_2_entry *two_hop_neighbor;
-              struct neighbor_2_list_entry *two_hop_neighbor_yet =
-                olsr_lookup_my_neighbors(neighbor, &message_neighbors->address);
-
-              if(!two_hop_neighbor_yet)
-                continue;
-
-              two_hop_neighbor = two_hop_neighbor_yet->neighbor_2;
-
-              // loop through the one-hop neighbors that see this
-              // 'two_hop_neighbor'
-
-              for (walker = two_hop_neighbor->neighbor_2_nblist.next;
-                   walker != &two_hop_neighbor->neighbor_2_nblist;
-                   walker = walker->next)
-                {
-                  // have we found the one-hop neighbor that sent the
-                  // HELLO message that we're current processing?
-
-                  if (walker->neighbor == neighbor)
-                    {
-#ifdef USE_FPM
-                      fpm saved_lq, rel_lq;
-#else
-                      double saved_lq, rel_lq;
-#endif
-
-                      // saved previous total link quality
-
-                      saved_lq = walker->saved_path_link_quality;
-
-#ifdef USE_FPM
-                      if (saved_lq == itofpm(0))
-                        saved_lq = itofpm(-1);
-#else
-                      if (saved_lq == 0.0)
-                        saved_lq = -1.0;
-#endif
-
-                      // if the link cost has changed by more than 10
-                      // percent, signal
-
-#ifdef USE_FPM
-                      rel_lq = fpmdiv(walker->path_link_quality, saved_lq);
-#else
-                      rel_lq = walker->path_link_quality / saved_lq;
-#endif
-
-                      if (rel_lq > CEIL_LQDIFF || rel_lq < FLOOR_LQDIFF)
+                      if (new_path_linkcost < walker->path_linkcost)
                         {
-                          walker->saved_path_link_quality =
-                            walker->path_link_quality;
-
-                          if (olsr_cnf->lq_dlimit > 0)
-                          {
-                            changes_neighborhood = OLSR_TRUE;
-                            changes_topology = OLSR_TRUE;
-                          }
-
-                          else
-                            OLSR_PRINTF(3, "Skipping Dijkstra (3)\n");
+                          walker->second_hop_linkcost = new_second_hop_linkcost;
+                          walker->path_linkcost = new_path_linkcost;
+                          
+                          if (olsr_is_relevant_costchange(new_path_linkcost, walker->saved_path_linkcost))
+                            {
+                              walker->saved_path_linkcost = new_path_linkcost;
+
+                              if (olsr_cnf->lq_dlimit > 0)
+                              {
+                                changes_neighborhood = OLSR_TRUE;
+                                changes_topology = OLSR_TRUE;
+                              }
+
+                              else
+                                OLSR_PRINTF(3, "Skipping Dijkstra (3)\n");
+                            }
                         }
                     }
                 }
@@ -395,15 +300,9 @@ linking_this_2_entries(struct neighbor_entry *neighbor, struct neighbor_2_entry
 
   list_of_1_neighbors->neighbor = neighbor;
 
-#ifdef USE_FPM
-  list_of_1_neighbors->path_link_quality = itofpm(0);
-  list_of_1_neighbors->saved_path_link_quality = itofpm(0);
-  list_of_1_neighbors->second_hop_link_quality = itofpm(0);
-#else
-  list_of_1_neighbors->path_link_quality = 0.0;
-  list_of_1_neighbors->saved_path_link_quality = 0.0;
-  list_of_1_neighbors->second_hop_link_quality = 0.0;
-#endif
+  list_of_1_neighbors->path_linkcost = LINK_COST_BROKEN;
+  list_of_1_neighbors->saved_path_linkcost = LINK_COST_BROKEN;
+  list_of_1_neighbors->second_hop_linkcost = LINK_COST_BROKEN;
 
   /* Queue */
   two_hop_neighbor->neighbor_2_nblist.next->prev = list_of_1_neighbors;
@@ -412,8 +311,10 @@ linking_this_2_entries(struct neighbor_entry *neighbor, struct neighbor_2_entry
   two_hop_neighbor->neighbor_2_nblist.next = list_of_1_neighbors;
   list_of_1_neighbors->prev = &two_hop_neighbor->neighbor_2_nblist;
   list_of_2_neighbors->neighbor_2 = two_hop_neighbor;
+  list_of_2_neighbors->nbr2_nbr = neighbor; /* XXX refcount */
   
-  list_of_2_neighbors->neighbor_2_timer = GET_TIMESTAMP(vtime*1000);
+  olsr_change_timer(list_of_2_neighbors->nbr2_list_timer, vtime * MSEC_PER_SEC,
+                    OLSR_NBR2_LIST_JITTER, OLSR_TIMER_ONESHOT);
 
   /* Queue */
   neighbor->neighbor_2_list.next->prev = list_of_2_neighbors;
@@ -485,13 +386,11 @@ static int deserialize_hello(struct hello_message *hello, const void *ser) {
                
                curr = (const unsigned char *)(info_head + 1);
                while (curr < limit2) {
-                       struct hello_neighbor *neigh = olsr_malloc(sizeof(struct hello_neighbor), "HELLO deserialization");
+                       struct hello_neighbor *neigh = olsr_malloc_hello_neighbor("HELLO deserialization");
                        pkt_get_ipaddress(&curr, &neigh->address);
                        
                        if (type == LQ_HELLO_MESSAGE) {
-                               pkt_get_lq(&curr, &neigh->link_quality);
-                               pkt_get_lq(&curr, &neigh->neigh_link_quality);
-                               pkt_ignore_u16(&curr);
+                               olsr_deserialize_hello_lq_pair(&curr, neigh);
                        }
                        neigh->link = EXTRACT_LINK(info_head->link_code);
                        neigh->status = EXTRACT_STATUS(info_head->link_code);
@@ -550,77 +449,21 @@ olsr_hello_tap(struct hello_message *message,
 
   if (olsr_cnf->lq_level > 0)
     {
-#ifdef USE_FPM
-      fpm saved_lq;
-      fpm rel_lq;
-#else
-      double saved_lq;
-      double rel_lq;
-#endif
       struct hello_neighbor *walker;
       // just in case our neighbor has changed its HELLO interval
       olsr_update_packet_loss_hello_int(lnk, message->htime);
 
       // find the input interface in the list of neighbor interfaces
-
       for (walker = message->neighbors; walker != NULL; walker = walker->next)
         if (ipequal(&walker->address, &in_if->ip_addr))
           break;
 
-      // the current reference link quality
-
-      saved_lq = lnk->saved_neigh_link_quality;
-
-#ifdef USE_FPM
-      if (saved_lq == itofpm(0))
-        saved_lq = itofpm(-1);
-#else
-      if (saved_lq == 0.0)
-        saved_lq = -1.0;
-#endif
-
       // memorize our neighbour's idea of the link quality, so that we
       // know the link quality in both directions
+      olsr_memorize_foreign_hello_lq(lnk, walker);
 
-      if (walker != NULL)
-        lnk->neigh_link_quality = walker->link_quality;
-
-      else
-#ifdef USE_FPM
-        lnk->neigh_link_quality = itofpm(0);
-#else
-        lnk->neigh_link_quality = 0.0;
-#endif
-
-      // if the link quality has changed by more than 10 percent,
-      // print the new link quality table
-
-#ifdef USE_FPM
-      rel_lq = fpmdiv(lnk->neigh_link_quality, saved_lq);
-#else
-      rel_lq = lnk->neigh_link_quality / saved_lq;
-#endif
-
-      if (rel_lq > CEIL_LQDIFF || rel_lq < FLOOR_LQDIFF)
-        {
-          lnk->saved_neigh_link_quality = lnk->neigh_link_quality;
-
-          if (olsr_cnf->lq_dlimit > 0)
-          {
-            changes_neighborhood = OLSR_TRUE;
-            changes_topology = OLSR_TRUE;
-          }
-
-          else
-            OLSR_PRINTF(3, "Skipping Dijkstra (2)\n");
-
-          // create a new ANSN
-
-          // XXX - we should check whether we actually
-          // announce this neighbour
-
-         signal_link_changes(OLSR_TRUE);
-        }
+      // update packet loss for link quality calculation
+      olsr_update_packet_loss(lnk);
     }
   
   neighbor = lnk->neighbor;
@@ -700,9 +543,6 @@ olsr_process_received_mid(union olsr_message *m,
     return;
   }
 
-  if (olsr_check_dup_table_proc(&message.mid_origaddr, 
-                                message.mid_seqno)) {
-
 #ifdef DEBUG
     OLSR_PRINTF(5, "Processing MID from %s...\n", olsr_ip_to_string(&buf, &message.mid_origaddr));
 #endif
@@ -739,13 +579,8 @@ olsr_process_received_mid(union olsr_message *m,
     } 
   
     olsr_prune_aliases(&message.mid_origaddr, message.mid_addr);
-  }
 
-  olsr_forward_message(m, 
-                      &message.mid_origaddr, 
-                      message.mid_seqno, 
-                      in_if,
-                      from_addr);
+  olsr_forward_message(m, from_addr);
   olsr_free_mid_packet(&message);
 }
 
@@ -821,7 +656,6 @@ olsr_process_received_hna(union olsr_message *m,
   /* seqno */
   pkt_get_u16(&curr, &packet_seq_number);
 
-  if (olsr_check_dup_table_proc(&originator, packet_seq_number)) {
     /*
      *      If the sender interface (NB: not originator) of this message
      *      is not in the symmetric 1-hop neighborhood of this node, the
@@ -846,20 +680,17 @@ olsr_process_received_hna(union olsr_message *m,
       if (entry == NULL) {
         /* only update if it's not from us */
         olsr_update_hna_entry(&originator, &net, prefixlen, vtime);
+      }
+    }
 #else
     while (hna_tmp) {
       /* Don't add an HNA entry that we are advertising ourselves. */
       if (!ip_prefix_list_find(olsr_cnf->hna_entries, &hna_tmp->net, hna_tmp->prefixlen)) {
         olsr_update_hna_entry(&message.originator, &hna_tmp->net, hna_tmp->prefixlen, message.vtime);
-#endif
       }
     }
-  }
-  olsr_forward_message(m, 
-                       &originator, 
-                       packet_seq_number, 
-                       in_if,
-                       from_addr);
+#endif
+  olsr_forward_me