Massive refactoring of topology handling.
authorHenning Rogge <hrogge@googlemail.com>
Sun, 13 Jun 2010 14:31:10 +0000 (16:31 +0200)
committerHenning Rogge <hrogge@googlemail.com>
Sun, 13 Jun 2010 14:31:10 +0000 (16:31 +0200)
No more valgrind errors from tc_set.
Removed some useless functions from lq_plugins.
Cleaned up Hello contribution to topology.

27 files changed:
lib/bmf/src/Bmf.c
lib/bmf/src/NetworkInterfaces.c
lib/dot_draw/src/olsrd_dot_draw.c
lib/lq_etx_ff/src/lq_plugin_etx_ff.c
lib/lq_etx_float/src/lq_plugin_etx_float.c
lib/lq_etx_fpm/src/lq_plugin_etx_fpm.c
lib/lq_rfc/src/lq_plugin_rfc.c
lib/txtinfo/src/olsrd_txtinfo.c
src/common/avl.c
src/hna_set.c
src/link_set.c
src/link_set.h
src/lq_mpr.c
src/lq_plugin.c
src/lq_plugin.h
src/main.c
src/mid_set.c
src/neighbor_table.c
src/neighbor_table.h
src/olsr_comport.c
src/olsr_spf.c
src/process_package.c
src/routing_table.c
src/scheduler.c
src/tc_set.c
src/tc_set.h
src/unix/ifnet.c

index d75f3ec..e6f9758 100644 (file)
@@ -311,7 +311,7 @@ BmfPacketCaptured(struct TBmfInterface *intf, unsigned char sllPkttype, unsigned
    * TODO2: get_best_link_to_neighbor() may be very CPU-expensive, a simpler call
    * would do here (something like 'get_any_link_to_neighbor()'). */
   isFromOlsrNeighbor = (isFromOlsrIntf  /* The frame is captured on an OLSR interface... */
-                        && get_best_link_to_neighbor(origIp) != NULL);  /* ...from an OLSR neighbor */
+                        && get_best_link_to_neighbor_ip(origIp) != NULL);  /* ...from an OLSR neighbor */
 
   /* Check with OLSR if I am MPR for that neighbor */
   /* TODO: olsr_lookup_mprs_set() is not thread-safe! */
index ee98089..469916a 100644 (file)
@@ -402,7 +402,7 @@ FindNeighbors(struct TBestNeighbors *neighbors,
 
   if (forwardedBy != NULL) {
     /* Retrieve the cost of the link from 'forwardedBy' to myself */
-    struct link_entry *bestLinkFromForwarder = get_best_link_to_neighbor(forwardedBy);
+    struct link_entry *bestLinkFromForwarder = get_best_link_to_neighbor_ip(forwardedBy);
     if (bestLinkFromForwarder != NULL) {
       previousLinkEtx = bestLinkFromForwarder->linkcost;
     }
@@ -473,7 +473,7 @@ FindNeighbors(struct TBestNeighbors *neighbors,
      * the candidate neighbor; the candidate neighbor has been / will be selected via that
      * other interface.
      */
-    bestLinkToNeighbor = get_best_link_to_neighbor(&walker->neighbor_iface_addr);
+    bestLinkToNeighbor = get_best_link_to_neighbor_ip(&walker->neighbor_iface_addr);
 
     if (walker != bestLinkToNeighbor) {
       if (bestLinkToNeighbor == NULL) {
index b2a3e09..3d28bc1 100644 (file)
@@ -152,7 +152,7 @@ ipc_print_neigh_link(int ipc_connection, const struct nbr_entry *neighbor)
   if (neighbor->is_sym == 0) {  /* non SYM */
     style = "dashed";
   } else {
-    const struct link_entry *lnk = get_best_link_to_neighbor(&neighbor->nbr_addr);
+    const struct link_entry *lnk = get_best_link_to_neighbor_ip(&neighbor->nbr_addr);
     if (lnk) {
       etx = lnk->linkcost;
     }
index 5c82379..1eaa43c 100644 (file)
@@ -51,6 +51,7 @@
 #include "scheduler.h"
 #include "olsr_logging.h"
 #include "common/string.h"
+#include "neighbor_table.h"
 
 #define PLUGIN_DESCR "Freifunk ETX metric based on the original design of Elektra and Thomas Lopatic"
 #define PLUGIN_AUTHOR "Henning Rogge"
@@ -70,14 +71,13 @@ static olsr_linkcost lq_etxff_calc_link_entry_cost(struct link_entry *);
 static olsr_linkcost lq_etxff_calc_lq_hello_neighbor_cost(struct lq_hello_neighbor *);
 static olsr_linkcost lq_etxff_calc_tc_edge_entry_cost(struct tc_edge_entry *);
 
-static bool lq_etxff_is_relevant_costchange(olsr_linkcost c1, olsr_linkcost c2);
-
-static olsr_linkcost lq_etxff_packet_loss_handler(struct link_entry *, bool);
+static void lq_etxff_hello_handler(struct link_entry *, bool);
 
 static void lq_etxff_memorize_foreign_hello(struct link_entry *, struct lq_hello_neighbor *);
 static void lq_etxff_copy_link_entry_lq_into_tc_edge_entry(struct tc_edge_entry *target, struct link_entry *source);
 
 static void lq_etxff_clear_link_entry(struct link_entry *);
+static void lq_etxff_clear_tc_edge_entry(struct tc_edge_entry *);
 
 static void lq_etxff_serialize_hello_lq(uint8_t **curr, struct link_entry *link);
 static void lq_etxff_serialize_tc_lq(uint8_t **curr, struct link_entry *link);
@@ -114,16 +114,14 @@ struct lq_handler lq_etxff_handler = {
   &lq_etxff_calc_lq_hello_neighbor_cost,
   &lq_etxff_calc_tc_edge_entry_cost,
 
-  &lq_etxff_is_relevant_costchange,
-
-  &lq_etxff_packet_loss_handler,
+  &lq_etxff_hello_handler,
 
   &lq_etxff_memorize_foreign_hello,
   &lq_etxff_copy_link_entry_lq_into_tc_edge_entry,
 
   &lq_etxff_clear_link_entry,
   NULL,
-  NULL,
+  &lq_etxff_clear_tc_edge_entry,
 
   &lq_etxff_serialize_hello_lq,
   &lq_etxff_serialize_tc_lq,
@@ -198,6 +196,8 @@ static void
 lq_etxff_timer(void __attribute__ ((unused)) * context)
 {
   struct link_entry *link;
+  struct nbr_entry *nbr;
+
   OLSR_FOR_ALL_LINK_ENTRIES(link) {
     struct lq_etxff_link_entry *lq_link;
     uint32_t ratio;
@@ -252,8 +252,15 @@ lq_etxff_timer(void __attribute__ ((unused)) * context)
     lq_link->lost[lq_link->activePtr] = 0;
     lq_link->received[lq_link->activePtr] = 0;
     lq_link->missed_seconds++;
+
+    /* update linkcost */
+    link->linkcost = lq_etxff_calc_link_entry_cost(link);
   }
   OLSR_FOR_ALL_LINK_ENTRIES_END(link);
+
+  OLSR_FOR_ALL_NBR_ENTRIES(nbr) {
+    olsr_neighbor_cost_may_changed(nbr);
+  } OLSR_FOR_ALL_NBR_ENTRIES_END()
 }
 
 static struct timer_entry *lq_etxff_timer_struct = NULL;
@@ -316,19 +323,9 @@ lq_etxff_calc_tc_edge_entry_cost(struct tc_edge_entry *edge)
   return lq_etxff_calc_linkcost(&lq_edge->lq);
 }
 
-static bool
-lq_etxff_is_relevant_costchange(olsr_linkcost c1, olsr_linkcost c2)
-{
-  if (c1 > c2) {
-    return c2 - c1 > LQ_PLUGIN_RELEVANT_COSTCHANGE_FF;
-  }
-  return c1 - c2 > LQ_PLUGIN_RELEVANT_COSTCHANGE_FF;
-}
-
-static olsr_linkcost
-lq_etxff_packet_loss_handler(struct link_entry *link, bool loss __attribute__ ((unused)))
+static void
+lq_etxff_hello_handler(struct link_entry *link __attribute__ ((unused)), bool loss __attribute__ ((unused)))
 {
-  return lq_etxff_calc_link_entry_cost(link);
 }
 
 static void
@@ -367,6 +364,13 @@ lq_etxff_clear_link_entry(struct link_entry *link)
 }
 
 static void
+lq_etxff_clear_tc_edge_entry(struct tc_edge_entry *edge) {
+  struct lq_etxff_tc_edge *lq_edge = (struct lq_etxff_tc_edge *)edge;
+
+  memset (&lq_edge->lq, 0, sizeof(lq_edge->lq));
+}
+
+static void
 lq_etxff_serialize_hello_lq(uint8_t **curr, struct link_entry *link)
 {
   struct lq_etxff_link_entry *lq_link = (struct lq_etxff_link_entry *)link;
index b9b86dc..275d273 100644 (file)
@@ -63,9 +63,7 @@ static olsr_linkcost lq_etxfloat_calc_link_entry_cost(struct link_entry *);
 static olsr_linkcost lq_etxfloat_calc_lq_hello_neighbor_cost(struct lq_hello_neighbor *);
 static olsr_linkcost lq_etxfloat_calc_tc_edge_entry_cost(struct tc_edge_entry *);
 
-static bool lq_etxfloat_is_relevant_costchange(olsr_linkcost c1, olsr_linkcost c2);
-
-static olsr_linkcost lq_etxfloat_packet_loss_handler(struct link_entry *, bool);
+static void lq_etxfloat_hello_handler(struct link_entry *, bool);
 
 static void lq_etxfloat_memorize_foreign_hello(struct link_entry *, struct lq_hello_neighbor *);
 static void lq_etxfloat_copy_link_entry_lq_into_tc_edge_entry(struct tc_edge_entry *target, struct link_entry *source);
@@ -96,9 +94,7 @@ struct lq_handler lq_etxfloat_handler = {
   &lq_etxfloat_calc_lq_hello_neighbor_cost,
   &lq_etxfloat_calc_tc_edge_entry_cost,
 
-  &lq_etxfloat_is_relevant_costchange,
-
-  &lq_etxfloat_packet_loss_handler,
+  &lq_etxfloat_hello_handler,
 
   &lq_etxfloat_memorize_foreign_hello,
   &lq_etxfloat_copy_link_entry_lq_into_tc_edge_entry,
@@ -202,17 +198,8 @@ lq_etxfloat_calc_tc_edge_entry_cost(struct tc_edge_entry *edge)
   return lq_etxfloat_calc_linkcost(&lq_edge->lq);
 }
 
-static bool
-lq_etxfloat_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;
-}
-
-static olsr_linkcost
-lq_etxfloat_packet_loss_handler(struct link_entry *link, bool loss)
+static void
+lq_etxfloat_hello_handler(struct link_entry *link, bool loss)
 {
   struct lq_etxfloat_link_entry *lq_link = (struct lq_etxfloat_link_entry *)link;
 
@@ -228,7 +215,8 @@ lq_etxfloat_packet_loss_handler(struct link_entry *link, bool loss)
   if (!loss) {
     lq_link->lq.valueLq += (alpha * link->loss_link_multiplier / 65536);
   }
-  return lq_etxfloat_calc_linkcost(&lq_link->lq);
+  link->linkcost = lq_etxfloat_calc_linkcost(&lq_link->lq);
+  olsr_neighbor_cost_may_changed(link->neighbor);
 }
 
 static void
index 88c2605..c20d84e 100644 (file)
@@ -65,9 +65,7 @@ static olsr_linkcost lq_etxfpm_calc_link_entry_cost(struct link_entry *);
 static olsr_linkcost lq_etxfpm_calc_lq_hello_neighbor_cost(struct lq_hello_neighbor *);
 static olsr_linkcost lq_etxfpm_calc_tc_edge_entry_cost(struct tc_edge_entry *);
 
-static bool lq_etxfpm_is_relevant_costchange(olsr_linkcost c1, olsr_linkcost c2);
-
-static olsr_linkcost lq_etxfpm_packet_loss_handler(struct link_entry *, bool);
+static void lq_etxfpm_hello_handler(struct link_entry *, bool);
 
 static void lq_etxfpm_memorize_foreign_hello(struct link_entry *, struct lq_hello_neighbor *);
 static void lq_etxfpm_copy_link_entry_lq_into_tc_edge_entry(struct tc_edge_entry *target, struct link_entry *source);
@@ -98,9 +96,7 @@ struct lq_handler lq_etxfpm_handler = {
   &lq_etxfpm_calc_lq_hello_neighbor_cost,
   &lq_etxfpm_calc_tc_edge_entry_cost,
 
-  &lq_etxfpm_is_relevant_costchange,
-
-  &lq_etxfpm_packet_loss_handler,
+  &lq_etxfpm_hello_handler,
 
   &lq_etxfpm_memorize_foreign_hello,
   &lq_etxfpm_copy_link_entry_lq_into_tc_edge_entry,
@@ -223,17 +219,8 @@ lq_etxfpm_calc_tc_edge_entry_cost(struct tc_edge_entry *edge)
   return lq_etxfpm_calc_linkcost(&lq_edge->lq);
 }
 
-static bool
-lq_etxfpm_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;
-}
-
-static olsr_linkcost
-lq_etxfpm_packet_loss_handler(struct link_entry *link, bool loss)
+static void
+lq_etxfpm_hello_handler(struct link_entry *link, bool loss)
 {
   struct lq_etxfpm_link_entry *lq_link = (struct lq_etxfpm_link_entry *)link;
 
@@ -241,7 +228,6 @@ lq_etxfpm_packet_loss_handler(struct link_entry *link, bool loss)
   uint32_t alpha_new = aging_factor_new;
 
   uint32_t value;
-  // fpm link_loss_factor = fpmidiv(itofpm(link->loss_link_multiplier), 65536);
 
   if (lq_link->quickstart < LQ_QUICKSTART_STEPS) {
     alpha_new = aging_quickstart_new;
@@ -261,7 +247,8 @@ lq_etxfpm_packet_loss_handler(struct link_entry *link, bool loss)
   }
   lq_link->lq.valueLq = (value * 255 + LQ_FPM_INTERNAL_MULTIPLIER - 1) / LQ_FPM_INTERNAL_MULTIPLIER;
 
-  return lq_etxfpm_calc_linkcost(&lq_link->lq);
+  link->linkcost = lq_etxfpm_calc_linkcost(&lq_link->lq);
+  olsr_neighbor_cost_may_changed(link->neighbor);
 }
 
 static void
index 50b9cda..0ca9c01 100644 (file)
@@ -65,9 +65,7 @@ static olsr_linkcost lq_rfc_calc_link_entry_cost(struct link_entry *);
 static olsr_linkcost lq_rfc_calc_lq_hello_neighbor_cost(struct lq_hello_neighbor *);
 static olsr_linkcost lq_rfc_calc_tc_edge_entry_cost(struct tc_edge_entry *);
 
-static bool lq_rfc_is_relevant_costchange(olsr_linkcost c1, olsr_linkcost c2);
-
-static olsr_linkcost lq_rfc_packet_loss_handler(struct link_entry *, bool);
+static void lq_rfc_packet_loss_handler(struct link_entry *, bool);
 
 static void lq_rfc_memorize_foreign_hello(struct link_entry *, struct lq_hello_neighbor *);
 static void lq_rfc_copy_link_entry_lq_into_tc_edge_entry(struct tc_edge_entry *target, struct link_entry *source);
@@ -95,8 +93,6 @@ struct lq_handler lq_rfc_handler = {
   &lq_rfc_calc_lq_hello_neighbor_cost,
   &lq_rfc_calc_tc_edge_entry_cost,
 
-  &lq_rfc_is_relevant_costchange,
-
   &lq_rfc_packet_loss_handler,
 
   &lq_rfc_memorize_foreign_hello,
@@ -182,19 +178,16 @@ lq_rfc_calc_tc_edge_entry_cost(struct tc_edge_entry __attribute__ ((unused)) * e
   return 1;
 }
 
-static bool
-lq_rfc_is_relevant_costchange(olsr_linkcost c1, olsr_linkcost c2)
-{
-  return c1 != c2;
-}
-
-static olsr_linkcost
+static void
 lq_rfc_packet_loss_handler(struct link_entry *link, bool loss)
 {
   struct lq_rfc_link_entry *link_entry = (struct lq_rfc_link_entry *)link;
 
-  if (!use_hysteresis)
-    return 1;
+  if (!use_hysteresis) {
+    link->linkcost = loss ? LINK_COST_BROKEN : 1;
+    olsr_neighbor_cost_may_changed(link->neighbor);
+    return;
+  }
 
   link_entry->hysteresis *= (1 - scaling);
   if (!loss) {
@@ -207,7 +200,8 @@ lq_rfc_packet_loss_handler(struct link_entry *link, bool loss)
     link_entry->active = true;
   }
 
-  return link_entry->active ? 1 : LINK_COST_BROKEN;
+  link->linkcost = link_entry->active ? 1 : LINK_COST_BROKEN;
+  olsr_neighbor_cost_may_changed(link->neighbor);
 }
 
 static void
index f889f6b..fab2447 100644 (file)
@@ -135,8 +135,6 @@ static const char KEY_WILLINGNESS[] = "will";
 static const char KEY_2HOP[] = "2hop";
 static const char KEY_LINKCOST[] = "linkcost";
 static const char KEY_RAWLINKCOST[] = "rawlinkcost";
-static const char KEY_COMMONCOST[] = "commoncost";
-static const char KEY_RAWCOMMONCOST[] = "rawcommoncost";
 static const char KEY_HOPCOUNT[] = "hopcount";
 static const char KEY_INTERFACE[] = "interface";
 static const char KEY_VTIME[] = "vtime";
@@ -146,8 +144,8 @@ struct ipprefix_str buf_destprefix;
 static char buf_sym[6], buf_mrp[4], buf_mprs[4], buf_virtual[4];
 static char buf_willingness[7];
 static char buf_2hop[6];
-static char buf_rawlinkcost[11], buf_rawcommoncost[11];
-static char buf_linkcost[LQTEXT_MAXLENGTH], buf_commoncost[LQTEXT_MAXLENGTH];
+static char buf_rawlinkcost[11];
+static char buf_linkcost[LQTEXT_MAXLENGTH];
 static char buf_hopcount[4];
 static char buf_interface[IF_NAMESIZE];
 struct millitxt_buf buf_vtime;
@@ -186,14 +184,14 @@ static char *values_routes[] = {
   buf_interface, buf_rawlinkcost, buf_linkcost
 };
 
-static const char *tmpl_topology = "%neighip%\t%localip%\t%isvirtual%\t%linkcost%\t%commoncost%\n";
+static const char *tmpl_topology = "%neighip%\t%localip%\t%isvirtual%\t%linkcost%\n";
 static const char *keys_topology[] = {
   KEY_LOCALIP, KEY_NEIGHIP, KEY_VIRTUAL, KEY_VTIME,
-  KEY_RAWLINKCOST, KEY_LINKCOST, KEY_RAWCOMMONCOST, KEY_COMMONCOST
+  KEY_RAWLINKCOST, KEY_LINKCOST
 };
 static char *values_topology[] = {
   buf_localip.buf, buf_neighip.buf, buf_virtual, buf_vtime.buf,
-  buf_rawlinkcost, buf_linkcost, buf_rawcommoncost, buf_commoncost
+  buf_rawlinkcost, buf_linkcost
 };
 
 static const char *tmpl_hna = "%destprefix%\t%localip%\t%vtime%\n";
@@ -514,8 +512,8 @@ txtinfo_topology(struct comport_connection *con,
 
     OLSR_FOR_ALL_TC_EDGE_ENTRIES(tc, tc_edge) {
       olsr_ip_to_string(&buf_neighip, &tc_edge->T_dest_addr);
-      strscpy(buf_virtual, tc_edge->is_virtual ? OLSR_YES : OLSR_NO, sizeof(buf_virtual));
-      if (tc_edge->is_virtual) {
+      strscpy(buf_virtual, tc_edge->virtual ? OLSR_YES : OLSR_NO, sizeof(buf_virtual));
+      if (tc_edge->virtual) {
         buf_linkcost[0] = 0;
         buf_rawlinkcost[0] = '0';
         buf_rawlinkcost[1] = 0;
@@ -525,9 +523,6 @@ txtinfo_topology(struct comport_connection *con,
         olsr_get_linkcost_text(tc_edge->cost, false, buf_linkcost, sizeof(buf_linkcost));
       }
 
-      snprintf(buf_rawcommoncost, sizeof(buf_rawcommoncost), "%ud", tc_edge->common_cost);
-      olsr_get_linkcost_text(tc_edge->common_cost, false, buf_commoncost, sizeof(buf_commoncost));
-
       if (abuf_templatef(&con->out, template, values_topology, tmpl_indices, indexLength) < 0) {
           return ABUF_ERROR;
       }
index e0b6ad4..5599d64 100644 (file)
@@ -620,6 +620,8 @@ avl_delete_worker(struct avl_tree *tree, struct avl_node *node)
   parent->right = min;
 }
 
+#include "valgrind/valgrind.h"
+
 void
 avl_delete(struct avl_tree *tree, struct avl_node *node)
 {
@@ -629,6 +631,9 @@ avl_delete(struct avl_tree *tree, struct avl_node *node)
   struct avl_node *right;
 
   /* sanity check */
+  if (tree->count == 0) {
+    VALGRIND_PRINTF_BACKTRACE("Error, trying to remove element from empty tree\n");
+  }
   assert(tree->count > 0);
 
   if (node->leader != 0) {
index f0bbc56..1362a27 100644 (file)
@@ -102,7 +102,6 @@ olsr_add_hna_net(struct tc_entry *tc, const struct olsr_ip_prefix *prefix)
 
   /* Set backpointer */
   new_net->hna_tc = tc;
-  olsr_lock_tc_entry(tc);
 
   /*
    * Insert into the per-tc hna subtree.
@@ -140,7 +139,6 @@ olsr_delete_hna_net(struct hna_net *hna_net)
   /*
    * Unlock and free.
    */
-  olsr_unlock_tc_entry(tc);
   olsr_cookie_free(hna_net_mem_cookie, hna_net);
 }
 
index a99afca..dc30908 100644 (file)
@@ -56,6 +56,8 @@
 #include "common/string.h"
 #include "olsr_logging.h"
 
+#include <assert.h>
+
 /* head node for all link sets */
 struct list_node link_entry_head;
 
@@ -76,7 +78,6 @@ static int check_link_status(const struct lq_hello_message *message, const struc
 static struct link_entry *add_link_entry(const union olsr_ip_addr *,
                                          const union olsr_ip_addr *,
                                          union olsr_ip_addr *, uint32_t, uint32_t, struct interface *);
-static bool get_neighbor_status(const union olsr_ip_addr *);
 
 void
 olsr_init_link_set(void)
@@ -103,14 +104,10 @@ olsr_init_link_set(void)
 int
 lookup_link_status(const struct link_entry *entry)
 {
-
   if (entry == NULL || list_is_empty(&link_entry_head)) {
     return UNSPEC_LINK;
   }
 
-  /*
-   * Hysteresis
-   */
   if (entry->link_sym_timer) {
     return SYM_LINK;
   }
@@ -122,103 +119,44 @@ lookup_link_status(const struct link_entry *entry)
   return LOST_LINK;
 }
 
-
 /**
- * Find the "best" link status to a neighbor
- *
- * @param address the address to check for
- * @return true if a symmetric link exists false if not
+ * Find best link to a neighbor
  */
-static bool
-get_neighbor_status(const union olsr_ip_addr *address)
+struct link_entry *
+get_best_link_to_neighbor_ip(const union olsr_ip_addr *remote)
 {
-  const union olsr_ip_addr *main_addr;
-  struct interface *ifs;
-  struct tc_entry *tc;
-
-  /* Find main address */
-  if (!(main_addr = olsr_lookup_main_addr_by_alias(address)))
-    main_addr = address;
-
-  /*
-   * Locate the hookup point.
-   */
-  tc = olsr_locate_tc_entry(main_addr);
-
-  /* Loop trough local interfaces to check all possebilities */
-  OLSR_FOR_ALL_INTERFACES(ifs) {
+  struct nbr_entry *nbr;
 
-    struct mid_entry *aliases;
-    struct link_entry *lnk = lookup_link_entry(main_addr, NULL, ifs);
-
-    if (lnk != NULL) {
-      if (lookup_link_status(lnk) == SYM_LINK)
-        return true;
-    }
-
-    /* Walk the aliases */
-    OLSR_FOR_ALL_TC_MID_ENTRIES(tc, aliases) {
-
-      lnk = lookup_link_entry(&aliases->mid_alias_addr, NULL, ifs);
-      if (lnk && (lookup_link_status(lnk) == SYM_LINK)) {
-        return true;
-      }
-    }
-    OLSR_FOR_ALL_TC_MID_ENTRIES_END(tc, aliases);
-  }
-  OLSR_FOR_ALL_INTERFACES_END(ifs);
-
-  return false;
+  nbr = olsr_lookup_nbr_entry(remote, true);
+  return get_best_link_to_neighbor(nbr);
 }
 
 /**
  * Find best link to a neighbor
  */
 struct link_entry *
-get_best_link_to_neighbor(const union olsr_ip_addr *remote)
+get_best_link_to_neighbor(struct nbr_entry *nbr)
 {
-  const union olsr_ip_addr *main_addr;
-  struct link_entry *walker, *good_link, *backup_link;
+  struct link_entry *walker, *good_link;
   olsr_linkcost curr_lcost = LINK_COST_BROKEN;
-  olsr_linkcost tmp_lc;
-
-  /* main address lookup */
-  main_addr = olsr_lookup_main_addr_by_alias(remote);
-
-  /* "remote" *already is* the main address */
-  if (!main_addr) {
-    main_addr = remote;
-  }
 
   /* we haven't selected any links, yet */
   good_link = NULL;
-  backup_link = NULL;
 
   /* loop through all links that we have */
   OLSR_FOR_ALL_LINK_ENTRIES(walker) {
 
     /* if this is not a link to the neighour in question, skip */
-    if (olsr_ipcmp(&walker->neighbor->nbr_addr, main_addr) != 0)
+    if (walker->neighbor != nbr || lookup_link_status(walker) != SYM_LINK)
       continue;
 
-    /* get the link cost */
-    tmp_lc = walker->linkcost;
-
     /*
      * is this link better than anything we had before ?
-     * use the requested remote interface address as a tie-breaker.
      */
-    if ((tmp_lc < curr_lcost) || ((tmp_lc == curr_lcost) && olsr_ipcmp(&walker->local_iface_addr, remote) == 0)) {
-
+    if (walker->linkcost < curr_lcost) {
       /* memorize the link quality */
-      curr_lcost = tmp_lc;
-
-      /* prefer symmetric links over asymmetric links */
-      if (lookup_link_status(walker) == SYM_LINK) {
-        good_link = walker;
-      } else {
-        backup_link = walker;
-      }
+      curr_lcost = walker->linkcost;
+      good_link = walker;
     }
   }
   OLSR_FOR_ALL_LINK_ENTRIES_END(walker);
@@ -226,7 +164,7 @@ get_best_link_to_neighbor(const union olsr_ip_addr *remote)
   /*
    * if we haven't found any symmetric links, try to return an asymmetric link.
    */
-  return good_link ? good_link : backup_link;
+  return good_link;
 }
 
 static void
@@ -273,41 +211,30 @@ set_loss_link_multiplier(struct link_entry *entry)
 static void
 olsr_delete_link_entry(struct link_entry *link)
 {
-
-  /*
-   * Delete the corresponding tc-edge for that link.
-   */
-  if (link->link_tc_edge) {
-    /* remove backpointer in tc edge */
-    link->link_tc_edge->link = NULL;
-    olsr_delete_tc_edge_entry(link->link_tc_edge);
-    link->link_tc_edge = NULL;
-
-    changes_topology = true;
-  }
-
   /*
    * Delete the rt_path for the link-end.
    */
   olsr_delete_routing_table(&link->neighbor_iface_addr, 8 * olsr_cnf->ipsize,
                             &link->neighbor->nbr_addr, OLSR_RT_ORIGIN_LINK);
 
-  /* Delete neighbor entry */
-  if (link->neighbor->linkcount == 1) {
-    olsr_delete_nbr_entry(link->neighbor);
-  } else {
-    link->neighbor->linkcount--;
+  /* update neighbor statistics */
+  link->neighbor->linkcount--;
+  if (link->is_mprs) {
+    link->neighbor->mprs_count --;
+  }
 
-    if (link->is_mprs) {
-      link->neighbor->mprs_count --;
-    }
+  /* Delete neighbor entry if no links left */
+  if (link->neighbor->linkcount == 0) {
+    olsr_delete_nbr_entry(link->neighbor);
   }
 
   /* 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_loss_timer);
   link->link_loss_timer = NULL;
 
@@ -355,7 +282,7 @@ olsr_expire_link_loss_timer(void *context)
   link = (struct link_entry *)context;
 
   /* count the lost packet */
-  olsr_update_packet_loss_worker(link, true);
+  olsr_lq_hello_handler(link, true);
 
   /* next timeout in 1.0 x htime */
   olsr_change_timer(link->link_loss_timer, link->loss_helloint, OLSR_LINK_LOSS_JITTER, OLSR_TIMER_PERIODIC);
@@ -377,7 +304,7 @@ olsr_expire_link_sym_timer(void *context)
   }
 
   link->status = lookup_link_status(link);
-  olsr_update_nbr_status(link->neighbor, get_neighbor_status(&link->neighbor_iface_addr));
+  olsr_update_nbr_status(link->neighbor);
   changes_neighborhood = true;
 }
 
@@ -392,7 +319,7 @@ olsr_expire_link_hello_timer(void *context)
   link = (struct link_entry *)context;
 
   /* update neighbor status */
-  olsr_update_nbr_status(link->neighbor, get_neighbor_status(&link->neighbor_iface_addr));
+  olsr_update_nbr_status(link->neighbor);
 }
 
 /**
@@ -444,11 +371,6 @@ add_link_entry(const union olsr_ip_addr *local,
 
   link = lookup_link_entry(remote, remote_main, local_if);
   if (link) {
-    /*
-     * Link exists. Update tc_edge LQ and exit.
-     */
-    olsr_copylq_link_entry_2_tc_edge_entry(link->link_tc_edge, link);
-    changes_neighborhood = olsr_calc_tc_edge_entry_etx(link->link_tc_edge);
     return link;
   }
 
@@ -514,23 +436,12 @@ add_link_entry(const union olsr_ip_addr *local,
     neighbor = olsr_add_nbr_entry(remote_main);
   }
 
+  assert(neighbor->tc_edge);
+
   neighbor->linkcount++;
   link->neighbor = neighbor;
 
   /*
-   * Now create a tc-edge for that link.
-   */
-  olsr_change_myself_tc();
-
-  link->link_tc_edge = olsr_lookup_tc_edge(tc_myself, remote_main);
-  if (link->link_tc_edge == NULL) {
-    link->link_tc_edge = olsr_add_tc_edge_entry(tc_myself, remote_main, 0);
-  }
-
-  /* set backpointer */
-  link->link_tc_edge->link = link;
-
-  /*
    * Add the rt_path for the link-end. This is an optimization
    * that lets us install > 1 hop routes prior to receiving
    * the MID entry for the 1 hop neighbor.
@@ -647,7 +558,7 @@ update_link_entry(const union olsr_ip_addr *local,
   }
 
   /* Update neighbor */
-  olsr_update_nbr_status(entry->neighbor, get_neighbor_status(remote));
+  olsr_update_nbr_status(entry->neighbor);
 
   return entry;
 }
@@ -811,7 +722,7 @@ olsr_update_packet_loss_hello_int(struct link_entry *entry, uint32_t loss_hello_
 void
 olsr_update_packet_loss(struct link_entry *entry)
 {
-  olsr_update_packet_loss_worker(entry, false);
+  olsr_lq_hello_handler(entry, false);
 
   /* timeout for the first lost packet is 1.5 x htime */
   olsr_set_timer(&entry->link_loss_timer, entry->loss_helloint + entry->loss_helloint / 2,
index 88650dc..433b4e7 100644 (file)
@@ -84,7 +84,6 @@ struct link_entry {
   /* cost of this link */
   olsr_linkcost linkcost;
 
-  struct tc_edge_entry *link_tc_edge;  /* shortcut to corresponding tc-edge */
   struct list_node link_list;          /* double linked list of all link entries */
 };
 
@@ -116,11 +115,13 @@ extern bool link_changes;
 void olsr_init_link_set(void);
 void olsr_delete_link_entry_by_if(const struct interface *);
 void olsr_expire_link_hello_timer(void *);
-void olsr_update_packet_loss_worker(struct link_entry *, bool);
+void olsr_lq_hello_handler(struct link_entry *, bool);
 void signal_link_changes(bool);        /* XXX ugly */
 
 
-struct link_entry *EXPORT(get_best_link_to_neighbor) (const union olsr_ip_addr *);
+struct link_entry *EXPORT(get_best_link_to_neighbor)(struct nbr_entry *nbr);
+
+struct link_entry *EXPORT(get_best_link_to_neighbor_ip) (const union olsr_ip_addr *);
 
 struct link_entry *EXPORT(lookup_link_entry) (const union olsr_ip_addr *,
                                               const union olsr_ip_addr * remote_main, const struct interface *);
index ee6410d..a909333 100644 (file)
@@ -95,7 +95,7 @@ olsr_calculate_lq_mpr(void)
        */
 
       /* determine the link quality of the direct link */
-      lnk = get_best_link_to_neighbor(&neigh->nbr_addr);
+      lnk = get_best_link_to_neighbor_ip(&neigh->nbr_addr);
       if (!lnk) {
         continue;
       }
index 4614d30..e20548d 100644 (file)
@@ -49,6 +49,7 @@
 #include "common/avl.h"
 #include "common/string.h"
 #include "olsr_logging.h"
+#include "neighbor_table.h"
 
 #include "assert.h"
 
@@ -108,22 +109,6 @@ olsr_calc_tc_cost(struct tc_edge_entry *tc_edge)
 }
 
 /*
- * 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
- */
-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
@@ -184,7 +169,7 @@ olsr_deserialize_tc_lq_pair(const uint8_t ** curr, struct tc_edge_entry *edge)
 }
 
 /*
- * olsr_update_packet_loss_worker
+ * olsr_lq_hello_handler
  *
  * 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
@@ -194,24 +179,49 @@ olsr_deserialize_tc_lq_pair(const uint8_t ** curr, struct tc_edge_entry *edge)
  * @param true if hello package was lost
  */
 void
-olsr_update_packet_loss_worker(struct link_entry *entry, bool lost)
+olsr_lq_hello_handler(struct link_entry *entry, bool lost)
 {
-  olsr_linkcost lq;
-  lq = active_lq_handler->packet_loss_handler(entry, lost);
+  active_lq_handler->hello_handler(entry, lost);
+}
+
+static void
+internal_clear_tc_edge_lq(struct tc_edge_entry *edge) {
+
+  if (active_lq_handler->clear_tc_edge_entry)  {
+    active_lq_handler->clear_tc_edge_entry(edge);
+  }
+  else {
+    uint8_t *ptr = (uint8_t *) edge;
+
+    memset (ptr + sizeof(*edge), 0, active_lq_handler->size_tc_edge - sizeof(*edge));
+  }
+}
+
+void
+olsr_neighbor_cost_may_changed(struct nbr_entry *nbr) {
+  struct link_entry *link;
+  struct tc_edge_entry *edge;
+  olsr_linkcost cost = LINK_COST_BROKEN;
 
-  if (olsr_is_relevant_costchange(lq, entry->linkcost)) {
-    entry->linkcost = lq;
+  link = get_best_link_to_neighbor(nbr);
+  edge = nbr->tc_edge;
+
+  if (link) {
+    cost = link->linkcost;
+    active_lq_handler->copy_link_entry_lq_into_tc_edge_entry(edge, link);
+  }
+  else {
+    internal_clear_tc_edge_lq(edge);
+  }
+
+  if (edge->cost != cost) {
+    edge->cost = cost;
 
     if (olsr_cnf->lq_dlimit > 0) {
       changes_neighborhood = true;
       changes_topology = true;
+      signal_link_changes(true);
     }
-
-    else
-      OLSR_DEBUG(LOG_LQ_PLUGINS, "Skipping Dijkstra (1)\n");
-
-    /* XXX - we should check whether we actually announce this neighbour */
-    signal_link_changes(true);
   }
 }
 
@@ -365,21 +375,6 @@ enum lq_linkdata_quality olsr_get_linkdata_quality (struct link_entry *link, int
 }
 
 /*
- * 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_entry_lq_into_tc_edge_entry(target, source);
-}
-
-/*
  * olsr_malloc_tc_edge_entry
  *
  * this function allocates memory for an tc_mpr_addr inclusive
index 76bbddb..2e19d14 100644 (file)
@@ -44,6 +44,7 @@
 
 #include "tc_set.h"
 #include "link_set.h"
+#include "neighbor_table.h"
 #include "olsr_spf.h"
 #include "lq_packet.h"
 #include "common/avl.h"
@@ -81,9 +82,7 @@ struct lq_handler {
   olsr_linkcost(*calc_lq_hello_neighbor_cost) (struct lq_hello_neighbor *);
   olsr_linkcost(*calc_tc_edge_entry_cost) (struct tc_edge_entry *);
 
-  bool(*is_relevant_costchange) (olsr_linkcost c1, olsr_linkcost c2);
-
-  olsr_linkcost(*packet_loss_handler) (struct link_entry *, bool);
+  void (*hello_handler) (struct link_entry *, bool);
 
   void (*memorize_foreign_hello) (struct link_entry *, struct lq_hello_neighbor *);
   void (*copy_link_entry_lq_into_tc_edge_entry) (struct tc_edge_entry *, struct link_entry *);
@@ -120,14 +119,13 @@ void init_lq_handler(void);
 void deinit_lq_handler(void);
 
 olsr_linkcost olsr_calc_tc_cost(struct tc_edge_entry *);
-bool olsr_is_relevant_costchange(olsr_linkcost c1, olsr_linkcost c2);
 
 void olsr_serialize_hello_lq_pair(uint8_t **, struct link_entry *);
 void olsr_deserialize_hello_lq_pair(const uint8_t **, struct lq_hello_neighbor *);
 void olsr_serialize_tc_lq(uint8_t **curr, struct link_entry *lnk);
 void olsr_deserialize_tc_lq_pair(const uint8_t **, struct tc_edge_entry *);
 
-void olsr_update_packet_loss_worker(struct link_entry *, bool);
+void olsr_lq_hello_handler(struct link_entry *, bool);
 void olsr_memorize_foreign_hello_lq(struct link_entry *, struct lq_hello_neighbor *);
 
 const char *EXPORT(olsr_get_linkcost_text) (olsr_linkcost, bool, char *, size_t);
@@ -137,7 +135,7 @@ size_t EXPORT(olsr_get_linklabel_maxlength) (int);
 size_t EXPORT(olsr_get_linklabel_count) (void);
 enum lq_linkdata_quality EXPORT(olsr_get_linkdata_quality) (struct link_entry *, int);
 
-void olsr_copylq_link_entry_2_tc_edge_entry(struct tc_edge_entry *, struct link_entry *);
+void olsr_neighbor_cost_may_changed(struct nbr_entry *);
 
 struct tc_edge_entry *olsr_malloc_tc_edge_entry(void);
 struct lq_hello_neighbor *olsr_malloc_lq_hello_neighbor(void);
index df8ed7c..5650b8d 100644 (file)
@@ -62,6 +62,7 @@
 #include "duplicate_set.h"
 #include "kernel_routes.h"
 #include "olsr_comport.h"
+#include "neighbor_table.h"
 
 #if defined linux
 #include <linux/types.h>
@@ -418,13 +419,17 @@ main(int argc, char *argv[])
   olsr_plugins_enable(PLUGIN_TYPE_DEFAULT, true);
 
   /* Starting scheduler */
-
   app_state = STATE_RUNNING;
   olsr_scheduler();
 
   olsr_stop_timer(tc_gen_timer);
+  tc_gen_timer = NULL;
+
   olsr_stop_timer(mid_gen_timer);
+  mid_gen_timer = NULL;
+
   olsr_stop_timer(hna_gen_timer);
+  hna_gen_timer = NULL;
 
   exitcode = olsr_cnf->exit_value;
   switch (app_state) {
@@ -524,13 +529,14 @@ olsr_shutdown(void)
 
   olsr_delete_all_kernel_routes();
 
-  olsr_delete_all_tc_entries();
-
   /* Flush MID database */
   OLSR_FOR_ALL_MID_ENTRIES(mid) {
     olsr_delete_mid_entry(mid);
   } OLSR_FOR_ALL_MID_ENTRIES_END();
 
+  /* Flush TC database */
+  olsr_delete_all_tc_entries();
+
   OLSR_INFO(LOG_MAIN, "Closing sockets...\n");
 
   /* kill http/telnet server */
index da709bb..a99b752 100644 (file)
@@ -96,7 +96,6 @@ olsr_expire_mid_entries(void *context)
 
   OLSR_DEBUG(LOG_MID, "MID aliases for %s timed out\n", olsr_ip_to_string(&buf, &mid->mid_alias_addr));
 
-  olsr_unlock_tc_entry(mid->mid_tc);
   olsr_delete_mid_entry(mid);
 }
 
@@ -115,7 +114,6 @@ olsr_set_mid_timer(struct mid_entry *mid, uint32_t rel_timer)
   else {
     mid->mid_timer = olsr_start_timer(rel_timer, OLSR_MID_JITTER, OLSR_TIMER_ONESHOT,
         &olsr_expire_mid_entries, mid, mid_validity_timer_cookie);
-    olsr_lock_tc_entry(mid->mid_tc);
   }
 }
 
@@ -253,7 +251,6 @@ olsr_insert_mid_entry(const union olsr_ip_addr *main_addr,
   alias = olsr_cookie_malloc(mid_address_mem_cookie);
   alias->mid_alias_addr = *alias_addr;
   alias->mid_tc = tc;
-  olsr_lock_tc_entry(tc);
 
   /*
    * Insert into the per-tc mid subtree.
@@ -381,7 +378,7 @@ olsr_delete_mid_entry(struct mid_entry *alias)
 
   /* kill timer */
   olsr_stop_timer(alias->mid_timer);
-  olsr_unlock_tc_entry(tc);
+  alias->mid_timer = NULL;
 
   /*
    * Delete the rt_path for the alias.
@@ -398,8 +395,6 @@ olsr_delete_mid_entry(struct mid_entry *alias)
    */
   avl_delete(&mid_tree, &alias->mid_node);
 
-  olsr_unlock_tc_entry(tc);
-
   olsr_cookie_free(mid_address_mem_cookie, alias);
 }
 
index 56b9e69..8f13ffd 100644 (file)
@@ -49,6 +49,7 @@
 #include "net_olsr.h"
 #include "olsr_logging.h"
 
+#include <assert.h>
 #include <stdlib.h>
 
 /* Root of the one hop and two hop neighbor trees */
@@ -63,6 +64,7 @@ struct olsr_cookie_info *nbr_connector_mem_cookie = NULL;
 struct olsr_cookie_info *nbr_connector_timer_cookie = NULL;
 
 static void olsr_expire_nbr_con(void *);
+static void internal_delete_nbr_con(struct nbr_con *connector);
 
 /*
  * Init neighbor tables.
@@ -123,6 +125,16 @@ olsr_add_nbr_entry(const union olsr_ip_addr *addr)
   nbr->is_mpr = false;
   nbr->was_mpr = false;
 
+  /* add tc_edge if necessary */
+  assert(tc_myself);
+  nbr->tc_edge = olsr_lookup_tc_edge(tc_myself, addr);
+  if (nbr->tc_edge == NULL) {
+    nbr->tc_edge = olsr_add_tc_edge_entry(tc_myself, addr, 0);
+  }
+
+  /* and connect it to this neighbor */
+  nbr->tc_edge->neighbor = nbr;
+
   /* Add to the global neighbor tree */
   nbr->nbr_node.key = &nbr->nbr_addr;
   avl_insert(&nbr_tree, &nbr->nbr_node, false);
@@ -140,7 +152,6 @@ void
 olsr_delete_nbr_entry(struct nbr_entry *nbr)
 {
   struct nbr_con *connector;
-  struct nbr2_entry *nbr2;
 
 #if !defined REMOVE_LOG_DEBUG
   struct ipaddr_str buf;
@@ -152,20 +163,25 @@ olsr_delete_nbr_entry(struct nbr_entry *nbr)
    * Remove all references pointing to this neighbor.
    */
   OLSR_FOR_ALL_NBR_CON_ENTRIES(nbr, connector) {
-    nbr2 = connector->nbr2;
-
     olsr_delete_nbr_con(connector);
-    if (nbr2->con_tree.count == 0) {
-      olsr_delete_nbr2_entry(nbr2);
-    }
   } OLSR_FOR_ALL_NBR_CON_ENTRIES_END()
 
+  /* remove corresponding tc_edge if not already removed by olsr_delete_all_tc_entries() */
+  if (nbr->tc_edge) {
+    /* first clear the connection to this neighbor */
+    nbr->tc_edge->neighbor = NULL;
+
+    /* now try to kill the edge */
+    olsr_delete_tc_edge_entry(nbr->tc_edge);
+  }
+
   /* Remove from global neighbor tree */
   avl_delete(&nbr_tree, &nbr->nbr_node);
 
   olsr_cookie_free(nbr_mem_cookie, nbr);
 
   changes_neighborhood = true;
+  changes_topology = true;
 }
 
 /**
@@ -200,15 +216,19 @@ olsr_lookup_nbr_entry(const union olsr_ip_addr *addr, bool lookupalias)
   return NULL;
 }
 
-int olsr_update_nbr_status(struct nbr_entry *entry, bool sym) {
+void olsr_update_nbr_status(struct nbr_entry *entry) {
 #if !defined REMOVE_LOG_DEBUG
   struct ipaddr_str buf;
 #endif
+  struct link_entry *link;
+
+  /* look for best symmetric link */
+  link = get_best_link_to_neighbor(entry);
+
   /*
    * Update neighbor entry
    */
-
-  if (sym) {
+  if (link && lookup_link_status(link) == SYM_LINK) {
     /* N_status is set to SYM */
     if (!entry->is_sym) {
       struct nbr2_entry *two_hop_neighbor;
@@ -220,25 +240,25 @@ int olsr_update_nbr_status(struct nbr_entry *entry, bool sym) {
 
       changes_neighborhood = true;
       changes_topology = true;
-      if (olsr_cnf->tc_redundancy > 1)
+      if (olsr_cnf->tc_redundancy > 1 || entry->is_mpr) {
         signal_link_changes(true);
+      }
     }
     entry->is_sym = true;
     OLSR_DEBUG(LOG_NEIGHTABLE, "Neighbor %s is now symmetric\n", olsr_ip_to_string(&buf, &entry->nbr_addr));
   } else {
     if (entry->is_sym) {
       changes_neighborhood = true;
-      changes_topology = true;
-      if (olsr_cnf->tc_redundancy > 1)
+      if (olsr_cnf->tc_redundancy > 1 || entry->is_mpr) {
         signal_link_changes(true);
+        changes_topology = true;
+      }
     }
     /* else N_status is set to NOT_SYM */
     entry->is_sym = false;
 
     OLSR_DEBUG(LOG_NEIGHTABLE, "Neighbor %s is now non-symmetric\n", olsr_ip_to_string(&buf, &entry->nbr_addr));
   }
-
-  return entry->is_sym;
 }
 
 /**
@@ -297,7 +317,7 @@ olsr_delete_nbr2_entry(struct nbr2_entry *nbr2) {
    * Remove all references pointing to this two hop neighbor.
    */
   OLSR_FOR_ALL_NBR2_CON_ENTRIES(nbr2, connector) {
-    olsr_delete_nbr_con(connector);
+    internal_delete_nbr_con(connector);
   } OLSR_FOR_ALL_NBR2_CON_ENTRIES_END();
 
   /* Remove from global neighbor tree */
@@ -374,13 +394,11 @@ olsr_link_nbr_nbr2(struct nbr_entry *nbr, const union olsr_ip_addr *nbr2_addr, u
 }
 
 /**
- * Unlinks an one-hop and a 2-hop neighbor.
- * Does NOT free the two-hop neighbor
- *
- * @param connector the connector between the neighbors
+ * Deletes a nbr-connector without deleting the 2-hop neighbor
+ * @param connector the connector between neighbors
  */
-void
-olsr_delete_nbr_con(struct nbr_con *connector) {
+static void
+internal_delete_nbr_con(struct nbr_con *connector) {
   olsr_stop_timer(connector->nbr2_con_timer);
   connector->nbr2_con_timer = NULL;
 
@@ -391,6 +409,24 @@ olsr_delete_nbr_con(struct nbr_con *connector) {
 }
 
 /**
+ * Unlinks an one-hop and a 2-hop neighbor.
+ *
+ * @param connector the connector between the neighbors
+ */
+void
+olsr_delete_nbr_con(struct nbr_con *connector) {
+  struct nbr2_entry *nbr2;
+
+  nbr2 = connector->nbr2;
+
+  internal_delete_nbr_con(connector);
+
+  if (nbr2->con_tree.count == 0) {
+    olsr_delete_nbr2_entry(nbr2);
+  }
+}
+
+/**
  * Looks up the connection object of an one-hop neighbor to a
  * 2-hop neighbor ip address.
  *
@@ -467,7 +503,7 @@ olsr_print_neighbor_table(void)
 
   OLSR_FOR_ALL_NBR_ENTRIES(nbr) {
 
-    lnk = get_best_link_to_neighbor(&nbr->nbr_addr);
+    lnk = get_best_link_to_neighbor_ip(&nbr->nbr_addr);
     if (!lnk) {
       continue;
     }
index e7ff7de..60b4398 100644 (file)
@@ -47,6 +47,7 @@
 #include "olsr_time.h"
 #include "olsr_types.h"
 #include "common/avl.h"
+#include "tc_set.h"
 
 #define NB2S_COVERED  0x1     /* node has been covered by a MPR */
 
@@ -64,7 +65,6 @@ struct nbr_con {
 
   olsr_linkcost second_hop_linkcost;
   olsr_linkcost path_linkcost;
-  olsr_linkcost saved_path_linkcost;
 };
 
 
@@ -73,6 +73,7 @@ struct nbr_con {
 struct nbr_entry {
   struct avl_node nbr_node;            /* nbr keyed by ip address */
   union olsr_ip_addr nbr_addr;
+  struct tc_edge_entry *tc_edge;
   unsigned int willingness:3;
   unsigned int is_sym:1;
   unsigned int is_mpr:1;
@@ -139,7 +140,7 @@ struct nbr_entry *olsr_add_nbr_entry(const union olsr_ip_addr *);
 void olsr_delete_nbr_entry(struct nbr_entry *);
 struct nbr_entry *EXPORT(olsr_lookup_nbr_entry) (const union olsr_ip_addr *, bool aliaslookup);
 
-int olsr_update_nbr_status(struct nbr_entry *, bool);
+void olsr_update_nbr_status(struct nbr_entry *);
 
 /* work with 2-hop neighbors */
 struct nbr2_entry *olsr_add_nbr2_entry(const union olsr_ip_addr *);
index 6fcdc60..371edd0 100644 (file)
@@ -390,6 +390,7 @@ static void olsr_com_parse_connection(int fd, void *data, unsigned int flags) {
     OLSR_DEBUG(LOG_COMPORT, "  cleanup\n");
     /* clean up connection by calling timeout directly */
     olsr_stop_timer(con->timeout);
+    con->timeout = NULL;
     olsr_com_cleanup_session(con);
   }
   return;
index e570d45..1d1b7c2 100644 (file)
@@ -39,6 +39,8 @@
  *
  */
 
+#include <assert.h>
+
 #include "olsr_spf.h"
 #include "tc_set.h"
 #include "neighbor_table.h"
@@ -141,9 +143,7 @@ olsr_spf_add_path_list(struct list_node *head, int *path_count, struct tc_entry
 static struct tc_entry *
 olsr_spf_extract_best(struct avl_tree *tree)
 {
-  struct avl_node *node = avl_walk_first(tree);
-
-  return (node ? cand_tree2tc(node) : NULL);
+  return (tree->count > 0 ? cand_tree2tc(avl_walk_first(tree)) : NULL);
 }
 
 
@@ -176,22 +176,19 @@ olsr_spf_relax(struct avl_tree *cand_tree, struct tc_entry *tc)
     struct tc_entry *new_tc;
     struct tc_edge_entry *tc_edge = edge_tree2tc_edge(edge_node);
 
-    /*
-     * We are not interested in dead-end edges.
-     */
-    if (!tc_edge->edge_inv) {
-      OLSR_DEBUG(LOG_ROUTING, "SPF:   ignoring edge %s\n", olsr_ip_to_string(&buf, &tc_edge->T_dest_addr));
-      if (!tc_edge->edge_inv) {
-        OLSR_DEBUG(LOG_ROUTING, "SPF:     no inverse edge\n");
-      }
-      continue;
-    }
+    assert (tc_edge->edge_inv);
 
     /*
      * total quality of the path through this vertex
      * to the destination of this edge
      */
-    new_cost = tc->path_cost + tc_edge->common_cost;
+    // TODO: asymmetric links ? Max(c1,c2) is not really good.
+    if (tc_edge->cost > tc_edge->edge_inv->cost) {
+      new_cost = tc->path_cost + tc_edge->cost;
+    }
+    else {
+      new_cost = tc->path_cost + tc_edge->edge_inv->cost;
+    }
 
     OLSR_DEBUG(LOG_ROUTING, "SPF:   exploring edge %s, cost %s\n",
                olsr_ip_to_string(&buf, &tc_edge->T_dest_addr),
@@ -248,7 +245,6 @@ olsr_spf_run_full(struct avl_tree *cand_tree, struct list_node *path_list, int *
   *path_count = 0;
 
   while ((tc = olsr_spf_extract_best(cand_tree))) {
-
     olsr_spf_relax(cand_tree, tc);
 
     /*
@@ -339,18 +335,17 @@ olsr_calculate_routing_table(void)
   /*
    * Set the next-hops of our neighbor link.
    */
-  OLSR_FOR_ALL_LINK_ENTRIES(link) {
-
-    neigh = link->neighbor;
-    tc_edge = link->link_tc_edge;
+  OLSR_FOR_ALL_NBR_ENTRIES(neigh) {
+    tc_edge = neigh->tc_edge;
 
     if (neigh->is_sym) {
-      if (tc_edge->edge_inv) {
-        tc_edge->edge_inv->tc->next_hop = link;
-      }
+      /* edges are always symmetric */
+      assert(tc_edge->edge_inv);
+
+      tc_edge->edge_inv->tc->next_hop = get_best_link_to_neighbor(neigh);
     }
   }
-  OLSR_FOR_ALL_LINK_ENTRIES_END(link);
+  OLSR_FOR_ALL_NBR_ENTRIES_END()
 
 #ifdef SPF_PROFILING
   gettimeofday(&t2, NULL);
index 11d94f2..570c466 100644 (file)
@@ -103,7 +103,7 @@ process_message_neighbors(struct nbr_entry *neighbor, const struct lq_hello_mess
   }
 
   /* Second pass */
-  lnk = get_best_link_to_neighbor(&neighbor->nbr_addr);
+  lnk = get_best_link_to_neighbor_ip(&neighbor->nbr_addr);
 
   if (!lnk) {
     return;
@@ -143,13 +143,8 @@ process_message_neighbors(struct nbr_entry *neighbor, const struct lq_hello_mess
         connector->second_hop_linkcost = new_second_hop_linkcost;
         connector->path_linkcost = new_path_linkcost;
 
-        if (olsr_is_relevant_costchange(new_path_linkcost, connector->saved_path_linkcost)) {
-          connector->saved_path_linkcost = new_path_linkcost;
-
-          if (olsr_cnf->lq_dlimit > 0) {
-            changes_neighborhood = true;
-            changes_topology = true;
-          }
+        if (olsr_cnf->lq_dlimit > 0) {
+          changes_neighborhood = true;
         }
       }
     }
index 7fd95d5..9521c26 100644 (file)
@@ -373,7 +373,6 @@ olsr_alloc_rt_path(struct tc_entry *tc, struct olsr_ip_prefix *prefix, uint8_t o
 
   /* insert to the tc prefix tree */
   avl_insert(&tc->prefix_tree, &rtp->rtp_prefix_tree_node, false);
-  olsr_lock_tc_entry(tc);
 
   /* backlink to the owning tc entry */
   rtp->rtp_tc = tc;
@@ -475,7 +474,6 @@ olsr_delete_rt_path(struct rt_path *rtp)
   /* remove from the tc prefix tree */
   if (rtp->rtp_tc) {
     avl_delete(&rtp->rtp_tc->prefix_tree, &rtp->rtp_prefix_tree_node);
-    olsr_unlock_tc_entry(rtp->rtp_tc);
     rtp->rtp_tc = NULL;
   }
 
index a4379fc..997cb1c 100644 (file)
@@ -809,11 +809,12 @@ void
 olsr_stop_timer(struct timer_entry *timer)
 {
   /* It's okay to get a NULL here */
-  if (!timer) {
+  if (timer == NULL) {
     return;
   }
 
   assert(timer->timer_cookie);     /* we want timer cookies everywhere */
+  assert(timer->timer_list.next != NULL && timer->timer_list.prev != NULL);
 
   OLSR_DEBUG(LOG_SCHEDULER, "TIMER: stop %s timer %p, ctx %p\n",
              timer->timer_cookie->ci_name, timer, timer->timer_cb_context);
index 5911b72..09a2c43 100644 (file)
@@ -68,8 +68,6 @@ static int ttl_index = -32;
 
 static uint16_t local_ansn_number = 0;
 
-static void olsr_cleanup_tc_entry(struct tc_entry *tc);
-
 /**
  * Add a new tc_entry to the tc tree
  *
@@ -109,7 +107,6 @@ olsr_add_tc_entry(const union olsr_ip_addr *adr)
    * Insert into the global tc tree.
    */
   avl_insert(&tc_tree, &tc->vertex_node, false);
-  olsr_lock_tc_entry(tc);
 
   /*
    * Initialize subtrees for edges, prefixes, HNAs and MIDs.
@@ -156,7 +153,7 @@ olsr_init_tc(void)
 void
 olsr_change_myself_tc(void)
 {
-  struct link_entry *entry;
+  struct nbr_entry *entry;
   bool main_ip_change = false;
 
   if (tc_myself) {
@@ -169,14 +166,14 @@ olsr_change_myself_tc(void)
     }
 
     /* flush local edges */
-    OLSR_FOR_ALL_LINK_ENTRIES(entry) {
-      if (entry->link_tc_edge) {
+    OLSR_FOR_ALL_NBR_ENTRIES(entry) {
+      if (entry->tc_edge) {
         /* clean up local edges if necessary */
-        entry->link_tc_edge->link = NULL;
-        olsr_delete_tc_edge_entry(entry->link_tc_edge);
-        entry->link_tc_edge = NULL;
+        entry->tc_edge->neighbor = NULL;
+        olsr_delete_tc_edge_entry(entry->tc_edge);
+        entry->tc_edge = NULL;
       }
-    } OLSR_FOR_ALL_LINK_ENTRIES_END(link)
+    } OLSR_FOR_ALL_NBR_ENTRIES_END()
 
     /*
      * Flush our own tc_entry.
@@ -186,7 +183,6 @@ olsr_change_myself_tc(void)
     /*
      * Clear the reference.
      */
-    olsr_unlock_tc_entry(tc_myself);
     tc_myself = NULL;
 
     main_ip_change = true;
@@ -196,17 +192,15 @@ olsr_change_myself_tc(void)
    * The old entry for ourselves is gone, generate a new one and trigger SPF.
    */
   tc_myself = olsr_add_tc_entry(&olsr_cnf->router_id);
-  olsr_lock_tc_entry(tc_myself);
 
   if (main_ip_change) {
-    OLSR_FOR_ALL_LINK_ENTRIES(entry) {
-      /**
-       * check if a main ip change destroyed our TC entries
-       */
-      if (entry->link_tc_edge == NULL) {
-        struct nbr_entry *ne = entry->neighbor;
-        entry->link_tc_edge = olsr_add_tc_edge_entry(tc_myself, &ne->nbr_addr, 0);
-        entry->link_tc_edge->link = entry;
+    OLSR_FOR_ALL_NBR_ENTRIES(entry) {
+    /**
+     * check if a main ip change destroyed our TC entries
+     */
+    if (entry->tc_edge == NULL) {
+        entry->tc_edge = olsr_add_tc_edge_entry(tc_myself, &entry->nbr_addr, 0);
+        entry->tc_edge->neighbor = entry;
       }
     } OLSR_FOR_ALL_LINK_ENTRIES_END(link);
   }
@@ -224,40 +218,31 @@ void
 olsr_delete_tc_entry(struct tc_entry *tc)
 {
   struct tc_edge_entry *tc_edge;
+  struct rt_path *rtp;
 
 #if !defined REMOVE_LOG_DEBUG
   struct ipaddr_str buf;
 #endif
-  OLSR_DEBUG(LOG_TC, "TC: del entry %s %u %s\n", olsr_ip_to_string(&buf, &tc->addr),
-      tc->edge_tree.count, tc->is_virtual ? "true" : "false");
+  OLSR_DEBUG(LOG_TC, "TC: del entry %s\n", olsr_ip_to_string(&buf, &tc->addr));
 
-  /* we don't want to keep this node */
-  tc->is_virtual = true;
-
-  if (tc->edge_tree.count == 0) {
-    olsr_cleanup_tc_entry(tc);
-    return;
-  }
-  /* The delete all non-virtual edges, the last one will clean up the tc if possible */
+  /* The delete all non-virtual edges */
   OLSR_FOR_ALL_TC_EDGE_ENTRIES(tc, tc_edge) {
-    /* we don't need this edge for the tc, so let's try to remove it */
     olsr_delete_tc_edge_entry(tc_edge);
   } OLSR_FOR_ALL_TC_EDGE_ENTRIES_END();
-}
 
-/**
- * Delete a tc entry after all edges have been cleared.
- *
- * @param entry the TC entry to delete
- */
-static void
-olsr_cleanup_tc_entry(struct tc_entry *tc) {
-  struct rt_path *rtp;
-#if !defined(REMOVE_LOG_DEBUG)
-  struct ipaddr_str buf;
-#endif
-  OLSR_DEBUG(LOG_TC, "TC: del entry %s %u\n", olsr_ip_to_string(&buf, &tc->addr), tc->refcount);
-  assert (tc->edge_tree.count == 0);
+  /* Stop running timers */
+  olsr_stop_timer(tc->validity_timer);
+  tc->validity_timer = NULL;
+
+  olsr_stop_timer(tc->edge_gc_timer);
+  tc->edge_gc_timer = NULL;
+
+  /* still virtual edges left, node has to stay in database */
+  if (tc->edge_tree.count > 0) {
+    tc->virtual = true;
+    tc->ansn = 0;
+    return;
+  }
 
   OLSR_FOR_ALL_PREFIX_ENTRIES(tc, rtp) {
     olsr_delete_rt_path(rtp);
@@ -269,14 +254,8 @@ olsr_cleanup_tc_entry(struct tc_entry *tc) {
   /* Flush all HNA Networks and kill its timers */
   olsr_flush_hna_nets(tc);
 
-  /* Stop running timers */
-  olsr_stop_timer(tc->edge_gc_timer);
-  tc->edge_gc_timer = NULL;
-  olsr_stop_timer(tc->validity_timer);
-  tc->validity_timer = NULL;
-
   avl_delete(&tc_tree, &tc->vertex_node);
-  olsr_unlock_tc_entry(tc);
+  olsr_cookie_free(tc_mem_cookie, tc);
 }
 
 /**
@@ -337,12 +316,13 @@ olsr_expire_tc_entry(void *context)
   struct ipaddr_str buf;
 #endif
   struct tc_entry *tc = context;
-  tc->validity_timer = NULL;
 
-  OLSR_DEBUG(LOG_TC, "TC: expire node entry %s\n",
-             olsr_ip_to_string(&buf, &tc->addr));
+  OLSR_DEBUG(LOG_TC, "TC: expire node entry %s (%zx)\n",
+             olsr_ip_to_string(&buf, &tc->addr), (size_t)context);
 
   olsr_delete_tc_entry(tc);
+
+  tc->validity_timer = NULL;
   changes_topology = true;
 }
 
@@ -358,36 +338,16 @@ olsr_expire_tc_edge_gc(void *context)
   struct ipaddr_str buf;
 #endif
   struct tc_entry *tc = context;
+  tc->edge_gc_timer = NULL;
 
   OLSR_DEBUG(LOG_TC, "TC: expire edge GC for %s\n",
              olsr_ip_to_string(&buf, &tc->addr));
 
-  tc->edge_gc_timer = NULL;
-
   if (delete_outdated_tc_edges(tc)) {
     changes_topology = true;
   }
 }
 
-/*
- * If the edge does not have a minimum acceptable link quality
- * set the etx cost to infinity such that it gets ignored during
- * SPF calculation.
- *
- * @return 1 if the change of the etx value was relevant
- */
-bool
-olsr_calc_tc_edge_entry_etx(struct tc_edge_entry *tc_edge)
-{
-  olsr_linkcost old = tc_edge->cost;
-  tc_edge->cost = olsr_calc_tc_cost(tc_edge);
-  tc_edge->common_cost = tc_edge->cost;
-  if (tc_edge->edge_inv) {
-    tc_edge->edge_inv->common_cost = tc_edge->cost;
-  }
-  return olsr_is_relevant_costchange(old, tc_edge->cost);
-}
-
 /**
  * Add a new tc_edge_entry to the tc_edge_tree
  *
@@ -395,7 +355,7 @@ olsr_calc_tc_edge_entry_etx(struct tc_edge_entry *tc_edge)
  * @return a pointer to the created entry
  */
 struct tc_edge_entry *
-olsr_add_tc_edge_entry(struct tc_entry *tc, union olsr_ip_addr *addr, uint16_t ansn)
+olsr_add_tc_edge_entry(struct tc_entry *tc, const union olsr_ip_addr *addr, uint16_t ansn)
 {
   struct tc_entry *tc_neighbor;
   struct tc_edge_entry *tc_edge;
@@ -420,7 +380,6 @@ olsr_add_tc_edge_entry(struct tc_entry *tc, union olsr_ip_addr *addr, uint16_t a
    * parallel links where we add one tc_edge per link_entry.
    */
   avl_insert(&tc->edge_tree, &tc_edge->edge_node, true);
-  olsr_lock_tc_entry(tc);
 
   /*
    * Connect backpointer.
@@ -435,17 +394,17 @@ olsr_add_tc_edge_entry(struct tc_entry *tc, union olsr_ip_addr *addr, uint16_t a
   if (tc_neighbor == NULL) {
     OLSR_DEBUG(LOG_TC, "TC:   creating neighbor tc_entry %s\n", olsr_ip_to_string(&buf, &tc_edge->T_dest_addr));
     tc_neighbor = olsr_add_tc_entry(&tc_edge->T_dest_addr);
-    tc_neighbor->is_virtual = true;
   }
 
   /* don't create an inverse edge for a tc pointing to us ! */
-  if (1 && tc_neighbor != tc_myself) {
+  if (tc_neighbor != tc_myself) {
     tc_edge_inv = olsr_lookup_tc_edge(tc_neighbor, &tc->addr);
-    if (!tc_edge_inv ) {
+    if (tc_edge_inv == NULL) {
       OLSR_DEBUG(LOG_TC, "TC:   creating inverse edge for %s\n", olsr_ip_to_string(&buf, &tc->addr));
       tc_edge_inv = olsr_add_tc_edge_entry(tc_neighbor, &tc->addr, 0);
 
-      tc_edge_inv->is_virtual = 1;
+      /* mark edge as virtual */
+      tc_edge_inv->virtual = true;
     }
 
     /*
@@ -455,16 +414,33 @@ olsr_add_tc_edge_entry(struct tc_entry *tc, union olsr_ip_addr *addr, uint16_t a
     tc_edge->edge_inv = tc_edge_inv;
   }
 
+  /* this is a real edge */
+  tc_edge->virtual = false;
+
   /*
    * Update the etx.
    */
-  olsr_calc_tc_edge_entry_etx(tc_edge);
+  tc_edge->cost = olsr_calc_tc_cost(tc_edge);
 
   OLSR_DEBUG(LOG_TC, "TC: add edge entry %s\n", olsr_tc_edge_to_string(tc_edge));
 
   return tc_edge;
 }
 
+static void
+internal_delete_tc_edge_entry(struct tc_edge_entry *tc_edge) {
+  struct tc_entry *tc = tc_edge->tc;
+#if !defined REMOVE_LOG_DEBUG
+  struct ipaddr_str buf;
+#endif
+  assert (tc_edge->edge_inv == NULL);
+
+  avl_delete(&tc->edge_tree, &tc_edge->edge_node);
+  OLSR_DEBUG(LOG_TC, "TC: %s down to %d edges\n", olsr_ip_to_string(&buf, &tc->addr), tc->edge_tree.count);
+
+  olsr_free_tc_edge_entry(tc_edge);
+}
+
 /**
  * Delete a TC edge entry.
  *
@@ -475,54 +451,50 @@ olsr_add_tc_edge_entry(struct tc_entry *tc, union olsr_ip_addr *addr, uint16_t a
 void
 olsr_delete_tc_edge_entry(struct tc_edge_entry *tc_edge)
 {
-  struct tc_entry *tc;
+  struct tc_entry *tc, *tc_inv;
   struct tc_edge_entry *tc_edge_inv;
-#if !defined REMOVE_LOG_DEBUG
-  struct ipaddr_str buf;
-#endif
+  bool was_real = false;
 
-  if (tc_edge->link) {
+  if (tc_edge->neighbor) {
     /* don't remove tc_edge for link entry */
     return;
   }
 
-  tc_edge->is_virtual = 1;
+  assert(tc_edge->edge_inv);
 
+  /* cache tc_entry pointer */
+  tc = tc_edge->tc;
+
+  /* get reverse edge */
   tc_edge_inv = tc_edge->edge_inv;
-  if (tc_edge_inv != NULL && tc_edge_inv->is_virtual == 0) {
-    OLSR_DEBUG(LOG_TC, "TC: mark edge entry %s\n", olsr_tc_edge_to_string(tc_edge));
+  tc_inv = tc_edge_inv->tc;
+
+  if (tc_edge_inv->virtual == false) {
+    /* mark this edge as virtual and correct tc_entry realedge_count */
+    if (!tc_edge->virtual) {
+      tc_edge->virtual = true;
+    }
+    OLSR_DEBUG(LOG_TC, "TC: mark edge entry %s as virtual\n", olsr_tc_edge_to_string(tc_edge));
     return;
   }
 
   OLSR_DEBUG(LOG_TC, "TC: del edge entry %s\n", olsr_tc_edge_to_string(tc_edge));
 
-  /*
-   * Clear the backpointer of our inverse edge.
-   */
-  if (tc_edge_inv) {
-    /* split the two edges */
-    tc_edge_inv->edge_inv = NULL;
-    tc_edge->edge_inv = NULL;
-
-    if (tc_edge_inv->is_virtual) {
-      /* remove the other side too because it's a virtual link */
-      olsr_delete_tc_edge_entry(tc_edge_inv);
-    }
-  }
+  /* mark topology as changed */
+  changes_topology = true;
 
-  tc = tc_edge->tc;
+  /* split the two edges */
+  tc_edge_inv->edge_inv = NULL;
+  tc_edge->edge_inv = NULL;
 
-  /* remove edge from tc FIRST */
-  avl_delete(&tc->edge_tree, &tc_edge->edge_node);
-  OLSR_DEBUG(LOG_TC, "TC: %s down to %d edges\n", olsr_ip_to_string(&buf, &tc->addr), tc->edge_tree.count);
+  /* remove both edges */
+  internal_delete_tc_edge_entry(tc_edge);
+  internal_delete_tc_edge_entry(tc_edge_inv);
 
-  /* now check if TC is virtual and has no edges left */
-  if (tc->is_virtual && tc->edge_tree.count == 0) {
-    /* cleanup virtual tc node */
-    olsr_cleanup_tc_entry(tc);
+  if (was_real && tc_inv != tc_myself && tc_inv->virtual) {
+    /* mark tc_entry to be gone in one ms */
+    olsr_set_timer(&tc_inv->validity_timer, 1, 0, false, &olsr_expire_tc_entry, tc, tc_validity_timer_cookie);
   }
-  olsr_unlock_tc_entry(tc);
-  olsr_free_tc_edge_entry(tc_edge);
 }
 
 /**
@@ -646,17 +618,16 @@ olsr_tc_update_edge(struct tc_entry *tc, uint16_t ansn, const unsigned char **cu
     /*
      * Update the etx.
      */
-    if (olsr_calc_tc_edge_entry_etx(tc_edge)) {
-      if (tc->msg_hops <= olsr_cnf->lq_dlimit) {
-        edge_change = 1;
-      }
-    }
-    if (edge_change) {
+    tc_edge->cost = olsr_calc_tc_cost(tc_edge);
+    if (tc->msg_hops <= olsr_cnf->lq_dlimit) {
+      edge_change = 1;
       OLSR_DEBUG(LOG_TC, "TC:   chg edge entry %s\n", olsr_tc_edge_to_string(tc_edge));
     }
   }
-  tc_edge->is_virtual = 0;
-  tc->is_virtual = false;
+
+  /* set edge and tc as non-virtual */
+  tc_edge->virtual = false;
+  tc->virtual = false;
 
   return edge_change;
 }
@@ -669,7 +640,7 @@ olsr_tc_update_edge(struct tc_entry *tc, uint16_t ansn, const unsigned char **cu
  * @return a pointer to the tc_edge found - or NULL
  */
 struct tc_edge_entry *
-olsr_lookup_tc_edge(struct tc_entry *tc, union olsr_ip_addr *edge_addr)
+olsr_lookup_tc_edge(struct tc_entry *tc, const union olsr_ip_addr *edge_addr)
 {
   struct avl_node *edge_node;
 
@@ -688,24 +659,33 @@ olsr_print_tc_table(void)
   /* The whole function makes no sense without it. */
   struct tc_entry *tc;
   const int ipwidth = olsr_cnf->ip_version == AF_INET ? 15 : 30;
+  static char NONE[] = "-";
 
   OLSR_INFO(LOG_TC, "\n--- %s ------------------------------------------------- TOPOLOGY\n\n", olsr_wallclock_string());
-  OLSR_INFO_NH(LOG_TC, "%-*s %-*s             %8s %8s\n", ipwidth,
-               "Source IP addr", ipwidth, "Dest IP addr", olsr_get_linklabel(0), "(common)");
+  OLSR_INFO_NH(LOG_TC, "%-*s %-*s %-7s      %8s %12s %5s\n", ipwidth,
+               "Source IP addr", ipwidth, "Dest IP addr", "", olsr_get_linklabel(0), "vtime", "ansn");
 
   OLSR_FOR_ALL_TC_ENTRIES(tc) {
     struct tc_edge_entry *tc_edge;
+    struct millitxt_buf tbuf;
+    char *vtime = NONE;
+
+    if (tc->validity_timer) {
+      olsr_milli_to_txt(&tbuf, olsr_getTimeDue(tc->validity_timer->timer_clock));
+      vtime = tbuf.buf;
+    }
+
     OLSR_FOR_ALL_TC_EDGE_ENTRIES(tc, tc_edge) {
       struct ipaddr_str addrbuf, dstaddrbuf;
-      char lqbuffer1[LQTEXT_MAXLENGTH], lqbuffer2[LQTEXT_MAXLENGTH];
+      char lqbuffer1[LQTEXT_MAXLENGTH];
 
-      OLSR_INFO_NH(LOG_TC, "%-*s %-*s %-7s      %8s %8s\n",
+      OLSR_INFO_NH(LOG_TC, "%-*s %-*s %-7s      %8s %12s %5u\n",
                    ipwidth, olsr_ip_to_string(&addrbuf, &tc->addr),
                    ipwidth, olsr_ip_to_string(&dstaddrbuf,
                                               &tc_edge->T_dest_addr),
-                   tc_edge->is_virtual ? "virtual" : "",
+                   tc_edge->virtual ? "virtual" : "",
                    olsr_get_linkcost_text(tc_edge->cost, false, lqbuffer1, sizeof(lqbuffer1)),
-                   olsr_get_linkcost_text(tc_edge->common_cost, false, lqbuffer2, sizeof(lqbuffer2)));
+                   vtime, tc_edge->ansn);
 
     } OLSR_FOR_ALL_TC_EDGE_ENTRIES_END();
   } OLSR_FOR_ALL_TC_ENTRIES_END();
@@ -809,7 +789,8 @@ olsr_input_tc(struct olsr_message * msg,
   tc = olsr_lookup_tc_entry(&msg->originator);
 
   /* TCs can be splitted, so we are looking for ANSNs equal or higher */
-  if (tc && status != RESET_SEQNO_OLSR_MESSAGE && tc->tc_seq != -1 && olsr_seqno_diff(ansn, tc->ansn) < 0) {
+  if (tc && status != RESET_SEQNO_OLSR_MESSAGE && tc->tc_seq != -1
+      && !tc->virtual && olsr_seqno_diff(ansn, tc->ansn) < 0) {
     /* this TC is too old, discard it */
     return;
   }
@@ -827,9 +808,6 @@ olsr_input_tc(struct olsr_message * msg,
   tc->msg_hops = msg->hopcnt;
   tc->tc_seq = msg->seqno;
   tc->ansn = ansn;
-  tc->ignored = 0;
-  tc->err_seq_valid = false;
-  tc->is_virtual = false;
 
   OLSR_DEBUG(LOG_TC, "Processing TC from %s, seq 0x%04x\n", olsr_ip_to_string(&buf, &msg->originator), tc->tc_seq);
 
@@ -896,31 +874,28 @@ getRelevantTcCount(void)
 void
 olsr_delete_all_tc_entries(void) {
   struct tc_entry *tc;
-  struct link_entry *link;
+  struct tc_edge_entry *edge;
 
-  /* then remove all tc entries */
+  /* delete tc_edges */
   OLSR_FOR_ALL_TC_ENTRIES(tc) {
-    tc->is_virtual = 0;
+    OLSR_FOR_ALL_TC_EDGE_ENTRIES(tc, edge) {
+      if (edge->neighbor) {
+        /* break connector with neighbor */
+        edge->neighbor->tc_edge = NULL;
+        edge->neighbor = NULL;
+      }
+      edge->edge_inv = NULL;
+      internal_delete_tc_edge_entry(edge);
+    } OLSR_FOR_ALL_TC_EDGE_ENTRIES_END()
   } OLSR_FOR_ALL_TC_ENTRIES_END(tc)
 
+  /* delete tc_entries */
   OLSR_FOR_ALL_TC_ENTRIES(tc) {
-    if (tc != tc_myself) {
-      olsr_delete_tc_entry(tc);
-    }
+    olsr_delete_tc_entry(tc);
   } OLSR_FOR_ALL_TC_ENTRIES_END(tc)
 
-  /* kill all references in link_set */
-  OLSR_FOR_ALL_LINK_ENTRIES(link) {
-    link->link_tc_edge = NULL;
-  } OLSR_FOR_ALL_LINK_ENTRIES_END(link)
-
-
   /* kill tc_myself */
-  if (tc_myself) {
-    olsr_delete_tc_entry(tc_myself);
-    olsr_unlock_tc_entry(tc_myself);
-    tc_myself = NULL;
-  }
+  tc_myself = NULL;
 }
 
 static uint8_t
@@ -1064,7 +1039,7 @@ olsr_output_lq_tc_internal(void *ctx  __attribute__ ((unused)), union olsr_ip_ad
     }
 
     /* Set the entry's link quality */
-    link = get_best_link_to_neighbor(&nbr->nbr_addr);
+    link = get_best_link_to_neighbor_ip(&nbr->nbr_addr);
     if (!link) {
       /* no link ? */
       continue;
index a382e2e..a4c2ad5 100644 (file)
@@ -62,10 +62,9 @@ struct tc_edge_entry {
   union olsr_ip_addr T_dest_addr;      /* edge_node key */
   struct tc_edge_entry *edge_inv;      /* shortcut, used during SPF calculation */
   struct tc_entry *tc;                 /* backpointer to owning tc entry */
-  struct link_entry *link;             /* back pointer for link edges */
+  struct nbr_entry *neighbor;          /* back pointer for edges to neighbor */
   olsr_linkcost cost;                  /* metric for tc received by this tc */
-  olsr_linkcost common_cost;           /* common metric of both edges used for SPF calculation */
-  unsigned int is_virtual:1;           /* 1 if this is a virtual edge created by the neighbors TC ? */
+  bool virtual;                        /* 1 if this is a virtual edge created by the neighbors TC ? */
   uint16_t ansn;                       /* ansn of this edge, used for multipart msgs */
 };
 
@@ -82,18 +81,13 @@ struct tc_entry {
   struct link_entry *next_hop;         /* SPF calculated link to the 1st hop neighbor */
   struct timer_entry *edge_gc_timer;   /* used for edge garbage collection */
   struct timer_entry *validity_timer;  /* tc validity time */
-  uint32_t refcount;                   /* reference counter */
-  bool is_virtual;                     /* true if tc is already timed out */
+  bool virtual;                        /* true if node is virtual */
   int tc_seq;                          /* sequence number of the tc message */
   int mid_seq;                         /* sequence number of the mid message */
   int hna_seq;                         /* sequence number of the hna message */
   uint8_t msg_hops;                    /* hopcount as per the tc message */
   uint8_t hops;                        /* SPF calculated hopcount */
   uint16_t ansn;                       /* ANSN number of the tc message */
-  uint16_t ignored;                    /* how many TC messages ignored in a sequence
-                                          (kindof emergency brake) */
-  uint16_t err_seq;                    /* sequence number of an unplausible TC */
-  bool err_seq_valid;                  /* do we have an error (unplauible seq/ansn) */
 };
 
 /*
@@ -143,31 +137,11 @@ void olsr_input_tc(struct olsr_message *, struct interface *, union olsr_ip_addr
 
 /* tc_entry manipulation */
 struct tc_entry *EXPORT(olsr_lookup_tc_entry) (const union olsr_ip_addr *);
-struct tc_entry *olsr_locate_tc_entry(const union olsr_ip_addr *);
-
-/*
- * Increment the reference counter.
- */
-static INLINE void
-olsr_lock_tc_entry(struct tc_entry *tc)
-{
-  tc->refcount++;
-}
-
-/*
- * Unlock and free a tc_entry once all references are gone.
- */
-static INLINE void
-olsr_unlock_tc_entry(struct tc_entry *tc)
-{
-  if (--tc->refcount == 0) {    /* All references are gone. */
-    olsr_cookie_free(tc_mem_cookie, tc);
-  }
-}
+struct tc_entry *EXPORT(olsr_locate_tc_entry)(const union olsr_ip_addr *);
 
 /* tc_edge_entry manipulation */
-struct tc_edge_entry *EXPORT(olsr_lookup_tc_edge) (struct tc_entry *, union olsr_ip_addr *);
-struct tc_edge_entry *olsr_add_tc_edge_entry(struct tc_entry *, union olsr_ip_addr *, uint16_t);
+struct tc_edge_entry *EXPORT(olsr_lookup_tc_edge) (struct tc_entry *, const union olsr_ip_addr *);
+struct tc_edge_entry *olsr_add_tc_edge_entry(struct tc_entry *, const union olsr_ip_addr *, uint16_t);
 void olsr_delete_tc_entry(struct tc_entry *);
 void olsr_delete_tc_edge_entry(struct tc_edge_entry *);
 bool olsr_calc_tc_edge_entry_etx(struct tc_edge_entry *);
index 267fe93..69f4a83 100644 (file)
@@ -575,6 +575,9 @@ chk_if_up(struct olsr_if_config *iface)
   if (olsr_ipcmp(&all_zero, &olsr_cnf->router_id) == 0) {
     olsr_cnf->router_id = ifp->ip_addr;
     OLSR_INFO(LOG_INTERFACE, "New main address: %s\n", olsr_ip_to_string(&buf, &olsr_cnf->router_id));
+
+    /* initialize representation of this node in tc_set */
+    olsr_change_myself_tc();
   }
 
   /*