MID refactoring phase #1
authorHannes Gredler <hannes@gredler.at>
Fri, 5 Sep 2008 15:21:51 +0000 (17:21 +0200)
committerHannes Gredler <hannes@gredler.at>
Fri, 5 Sep 2008 15:21:51 +0000 (17:21 +0200)
clean up the code towards a unified linkstate database where all the information
is organized in a nodal oriented database. we use the TC tree as a hook to hold various
information. A MID entry is inserted both in a global tree for alias lookup
and in a per-tc subtree for housekeeping like timeouts etc.
replace MID traversals with the appropriate macros in the plugins.

19 files changed:
lib/httpinfo/src/olsrd_httpinfo.c
lib/nameservice/src/mapwrite.c
lib/nameservice/src/nameservice.c
lib/tas/src/plugin.c
lib/txtinfo/src/olsrd_txtinfo.c
src/duplicate_set.c
src/link_set.c
src/lq_plugin_default_ff.c
src/mid_set.c
src/mid_set.h
src/neighbor_table.c
src/olsr.c
src/process_package.c
src/rebuild_packet.c
src/routing_table.c
src/routing_table.h
src/tc_set.c
src/tc_set.h
src/two_hop_neighbor_table.c

index 980f659..5aadad6 100644 (file)
@@ -1087,20 +1087,21 @@ static int build_mid_body(char *buf, olsr_u32_t bufsize)
 
   /* MID */
   for (idx = 0; idx < HASHSIZE; idx++) {
-    struct mid_entry *entry;
-    for (entry = mid_set[idx].next; entry != &mid_set[idx]; entry = entry->next) {
-      int mid_cnt;
-      struct mid_address *alias;
+    struct tc_entry *tc;
+    OLSR_FOR_ALL_TC_ENTRIES(tc) {
+      struct mid_entry *alias;
       size += snprintf(&buf[size], bufsize-size, "<tr>");
-      size += build_ipaddr_with_link(&buf[size], bufsize, &entry->main_addr, -1);
+      size += build_ipaddr_with_link(&buf[size], bufsize, &tc->addr, -1);
       size += snprintf(&buf[size], bufsize-size, "<td><select>\n<option>IP ADDRESS</option>\n");
 
-      for (mid_cnt = 0, alias = entry->aliases; alias != NULL; alias = alias->next_alias, mid_cnt++) {
+      OLSR_FOR_ALL_TC_MID_ENTRIES(tc, alias) {
         struct ipaddr_str strbuf;
-        size += snprintf(&buf[size], bufsize-size, "<option>%s</option>\n", olsr_ip_to_string(&strbuf, &alias->alias));
-      }
-      size += snprintf(&buf[size], bufsize-size, "</select> (%d)</td></tr>\n", mid_cnt);
-    }
+        size += snprintf(&buf[size], bufsize-size, "<option>%s</option>\n",
+                         olsr_ip_to_string(&strbuf, &alias->mid_alias_addr));
+      } OLSR_FOR_ALL_TC_MID_ENTRIES_END(tc, alias);
+      size += snprintf(&buf[size], bufsize-size, "</select> (%d)</td></tr>\n",
+                       tc->mid_tree.count);
+    } OLSR_FOR_ALL_TC_ENTRIES_END(tc);
   }
 
   size += snprintf(&buf[size], bufsize-size, "</table>\n");
index 8e90f71..d38c8f0 100644 (file)
@@ -119,25 +119,17 @@ void mapwrite_work(FILE* fmap)
     }
   }
 
-  for (hash = 0; hash < HASHSIZE; hash++) 
-  {
-    struct mid_entry *entry = mid_set[hash].next;
-    while(entry != &mid_set[hash])
-    {
-      struct mid_address *alias = entry->aliases;
-      while(alias)
-      {
-        if (0 > fprintf(fmap, "Mid('%s','%s');\n",
-          olsr_ip_to_string(&strbuf1, &entry->main_addr),
-          olsr_ip_to_string(&strbuf2, &alias->alias)))
-        {
-          return;
-        }
-        alias = alias->next_alias;
+  OLSR_FOR_ALL_TC_ENTRIES(tc) {
+    struct mid_entry *alias;
+    OLSR_FOR_ALL_TC_MID_ENTRIES(tc, alias) {
+      if (0 > fprintf(fmap, "Mid('%s','%s');\n",
+                      olsr_ip_to_string(&strbuf1, &tc->addr),
+                      olsr_ip_to_string(&strbuf2, &alias->mid_alias_addr))) {
+        return;
       }
-      entry = entry->next;
-    }
-  }
+    } OLSR_FOR_ALL_TC_MID_ENTRIES_END(tc, alias);
+  } OLSR_FOR_ALL_TC_ENTRIES_END(tc);
+
   lookup_defhna_latlon(&ip);
   sprintf(my_latlon_str, "%f,%f,%d", my_lat, my_lon, get_isdefhna_latlon());
   if (0 > fprintf(fmap, "Self('%s',%s,'%s','%s');\n",
@@ -284,9 +276,6 @@ void mapwrite_exit(void)
 
 /*
  * Local Variables:
- * mode: c
- * c-indent-tabs-mode: t
- * c-basic-offset: 4
- * tab-width: 4
+ * c-basic-offset: 2
  * End:
  */
index 1e9534c..fb9619f 100644 (file)
@@ -1062,7 +1062,8 @@ write_hosts_file(void)
        time_t currtime;
 
 #ifdef MID_ENTRIES
-       struct mid_address *alias;
+       struct mid_entry *alias;
+       struct tc_entry *tc;
 #endif
 
        if (!name_table_changed)
@@ -1127,13 +1128,11 @@ write_hosts_file(void)
 
 #ifdef MID_ENTRIES
                                // write mid entries
-                               if( ( alias = mid_lookup_aliases( &name->ip ) ) != NULL )
-                               {
+                               if (( tc = olsr_lookup_tc_entry( &name->ip ) ) != NULL ) {
                                        unsigned short mid_num = 1;
                                        char       mid_prefix[MID_MAXLEN];
 
-                                       while( alias != NULL )
-                                       {
+                                       OLSR_FOR_ALL_TC_MID_ENTRIES(tc, alias) {
                                                struct ipaddr_str midbuf;
 
                                                // generate mid prefix
@@ -1141,7 +1140,7 @@ write_hosts_file(void)
 
                                                OLSR_PRINTF(
                                                        6, "%s\t%s%s%s\t# %s (mid #%i)\n",
-                                                       olsr_ip_to_string( &midbuf, &alias->alias ),
+                                                       olsr_ip_to_string( &midbuf, &alias->mid_alias_addr ),
                                                        mid_prefix, name->name, my_suffix,
                                                        olsr_ip_to_string( &strbuf, &entry->originator ),
                                                        mid_num
@@ -1149,15 +1148,14 @@ write_hosts_file(void)
 
                                                fprintf(
                                                        hosts, "%s\t%s%s%s\t# %s (mid #%i)\n",
-                                                       olsr_ip_to_string( &midbuf, &alias->alias ),
+                                                       olsr_ip_to_string( &midbuf, &alias->mid_alias_addr ),
                                                        mid_prefix, name->name, my_suffix,
                                                        olsr_ip_to_string( &strbuf, &entry->originator ),
                                                        mid_num
                                                        );
 
-                                               alias = alias->next_alias;
                                                mid_num++;
-                                       }
+                                       } OLSR_FOR_ALL_TC_MID_ENTRIES_END(tc, alias);
                                }
 #endif
                        }
index 7c626a3..2606e81 100644 (file)
@@ -81,7 +81,6 @@ static union olsr_ip_addr *mainAddr;
 
 static struct interface *intTab = NULL;
 static struct neighbor_entry *neighTab = NULL;
-static struct mid_entry *midTab = NULL;
 static struct hna_entry *hnaTab = NULL;
 static struct olsrd_config *config = NULL;
 
@@ -461,7 +460,6 @@ int olsrd_plugin_init(void)
 
   intTab = ifnet;
   neighTab = neighbortable;
-  midTab = mid_set;
   hnaTab = hna_set;
   config = olsr_cnf;
 
index c38ead4..5ca7b13 100644 (file)
@@ -466,36 +466,27 @@ static void ipc_print_hna(void)
 
 static void ipc_print_mid(void)
 {
-    int index;
     unsigned short is_first;
-    struct mid_entry *entry;
-    struct mid_address *alias;
+    struct tc_entry *tc;
+    struct mid_entry *alias;
 
     ipc_sendf("Table: MID\nIP address\tAliases\n");
 
-    /* MID */
-    for(index = 0; index < HASHSIZE; index++) {
-        entry = mid_set[index].next;
-        
-        while( entry != &mid_set[index] ) {
-            struct ipaddr_str buf;
-            ipc_sendf( olsr_ip_to_string(&buf,  &entry->main_addr ) );
-            alias = entry->aliases;
-            is_first = 1;
-
-            while( alias ) {
-                ipc_sendf( "%s%s",
-                           ( is_first ? "\t" : ";" ),
-                           olsr_ip_to_string(&buf,  &alias->alias )
-                           );
-
-                alias = alias->next_alias;
-                is_first = 0;
-            }
-            entry = entry->next;
-            ipc_sendf("\n");
-        }
-    }
+    /* MID root is the TC entry */
+    OLSR_FOR_ALL_TC_ENTRIES(tc) {
+        struct ipaddr_str buf;
+        ipc_sendf( olsr_ip_to_string(&buf,  &tc->addr ) );
+        is_first = 1;
+
+        OLSR_FOR_ALL_TC_MID_ENTRIES(tc, alias) {
+            ipc_sendf( "%s%s",
+                       ( is_first ? "\t" : ";" ),
+                       olsr_ip_to_string(&buf, &alias->mid_alias_addr));
+
+            is_first = 0;
+        }  OLSR_FOR_ALL_TC_MID_ENTRIES_END(tc, alias);
+        ipc_sendf("\n");
+    } OLSR_FOR_ALL_TC_ENTRIES_END(tc);
     ipc_sendf("\n");
 }
 
index 6f91e2d..fbef379 100644 (file)
@@ -105,7 +105,7 @@ olsr_shall_process_message(void *ip, olsr_u16_t seqnr)
 
   struct ipaddr_str buf;
   // get main address
-  mainIp = mid_lookup_main_addr(ip);
+  mainIp = olsr_lookup_main_addr_by_alias(ip);
   if (mainIp == NULL) {
     mainIp = ip;
   }
index c4bc03a..c253b78 100644 (file)
@@ -158,14 +158,20 @@ get_neighbor_status(const union olsr_ip_addr *address)
 {
   const union olsr_ip_addr *main_addr;
   struct interface *ifs;
+  struct tc_entry *tc;
 
   /* Find main address */
-  if (!(main_addr = mid_lookup_main_addr(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 */
   for (ifs = ifnet; ifs != NULL; ifs = ifs->int_next) {
-    struct mid_address *aliases;
+    struct mid_entry *aliases;
     struct link_entry *lnk = lookup_link_entry(main_addr, NULL, ifs);
 
     if (lnk != NULL) {
@@ -173,15 +179,14 @@ get_neighbor_status(const union olsr_ip_addr *address)
        return SYM_LINK;
     }
 
-    /* Get aliases */
-    for (aliases = mid_lookup_aliases(main_addr);
-        aliases != NULL; aliases = aliases->next_alias) {
+    /* Walk the aliases */
+    OLSR_FOR_ALL_TC_MID_ENTRIES(tc, aliases) {
 
-      lnk = lookup_link_entry(&aliases->alias, NULL, ifs);
+      lnk = lookup_link_entry(&aliases->mid_alias_addr, NULL, ifs);
       if (lnk && (lookup_link_status(lnk) == SYM_LINK)) {
          return SYM_LINK;
       }
-    }
+    } OLSR_FOR_ALL_TC_MID_ENTRIES_END(tc, aliases);
   }
 
   return 0;
@@ -201,7 +206,7 @@ get_best_link_to_neighbor(const union olsr_ip_addr *remote)
   olsr_linkcost tmp_lc;
 
   /* main address lookup */
-  main_addr = mid_lookup_main_addr(remote);
+  main_addr = olsr_lookup_main_addr_by_alias(remote);
 
   /* "remote" *already is* the main address */
   if (!main_addr) {
index a756add..ecbf821 100644 (file)
@@ -85,7 +85,7 @@ static void default_lq_parser_ff(struct olsr *olsr, struct interface *in_if, uni
   olsr_u32_t seq_diff;
 
   /* Find main address */
-  main_addr = mid_lookup_main_addr(from_addr);
+  main_addr = olsr_lookup_main_addr_by_alias(from_addr);
 
   /* Loopup link entry */
   lnk = lookup_link_entry(from_addr, main_addr, in_if);
index 70b0dda..fc98284 100644 (file)
 #include "neighbor_table.h"
 #include "link_set.h"
 #include "tc_set.h"
-#include "packet.h"            /* struct mid_alias */
 #include "net_olsr.h"
+#include "olsr_cookie.h"
 
 #include <stdlib.h>
 
+/* Root of the MID tree */
+struct avl_tree mid_tree;
 
-struct mid_entry mid_set[HASHSIZE];
-struct mid_address reverse_mid_set[HASHSIZE];
-
-struct mid_entry *mid_lookup_entry_bymain(const union olsr_ip_addr *adr);
+/* Some cookies for stats keeping */
+struct olsr_cookie_info *mid_validity_timer_cookie = NULL;
+struct olsr_cookie_info *mid_address_mem_cookie = NULL;
 
 /**
  * Initialize the MID set
- *
  */
-int
+void
 olsr_init_mid_set(void)
 {
-  int idx;
-
   OLSR_PRINTF(5, "MID: init\n");
 
-  for (idx = 0; idx < HASHSIZE; idx++) {
-    mid_set[idx].next = &mid_set[idx];
-    mid_set[idx].prev = &mid_set[idx];
+  avl_init(&mid_tree, avl_comp_default);
 
-    reverse_mid_set[idx].next = &reverse_mid_set[idx];
-    reverse_mid_set[idx].prev = &reverse_mid_set[idx];
-  }
+  /*
+   * Get some cookies for getting stats to ease troubleshooting.
+   */
+  mid_validity_timer_cookie =
+    olsr_alloc_cookie("MID validity", OLSR_COOKIE_TYPE_TIMER);
 
-  return 1;
+  mid_address_mem_cookie =
+    olsr_alloc_cookie("MID address", OLSR_COOKIE_TYPE_MEMORY);
+  olsr_cookie_set_memory_size(mid_address_mem_cookie,
+                              sizeof(struct mid_entry));
 }
 
 /**
  * Wrapper for the timer callback.
  */
 static void
-olsr_expire_mid_entry(void *context)
+olsr_expire_mid_entries(void *context)
 {
 #ifdef DEBUG
   struct ipaddr_str buf;
 #endif
-  struct mid_entry *mid;
+  struct tc_entry *tc;
 
-  mid = (struct mid_entry *)context;
-  mid->mid_timer = NULL;
+  tc = (struct tc_entry *)context;
+  tc->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));
+  OLSR_PRINTF(1, "MID aliases for %s timed out\n",
+             olsr_ip_to_string(&buf, &tc->addr));
 #endif
 
-  olsr_delete_mid_entry(mid);
+  olsr_flush_mid_entries(tc);
 }
 
-
 /**
  * Set the mid set expiration timer.
  *
@@ -111,417 +111,353 @@ olsr_expire_mid_entry(void *context)
  * The timer param is a relative timer expressed in milliseconds.
  */
 static void
-olsr_set_mid_timer(struct mid_entry *mid, olsr_reltime rel_timer)
+olsr_set_mid_timer(struct tc_entry *tc, olsr_reltime rel_timer)
 {
-
-  olsr_set_timer(&mid->mid_timer, rel_timer, OLSR_MID_JITTER,
-                OLSR_TIMER_ONESHOT, &olsr_expire_mid_entry, mid, 0);
+  olsr_set_timer(&tc->mid_timer, rel_timer, OLSR_MID_JITTER,
+                OLSR_TIMER_ONESHOT, &olsr_expire_mid_entries, tc,
+                 mid_validity_timer_cookie->ci_id);
 }
 
-
 /**
- * Insert a new interface alias to the interface association set.
- * If the main interface of the association is not yet registered
- * in the set a new entry is created.
- *
- * @param m_addr the main address of the node
- * @param alias the alias address to insert
- * @return nada
+ * Delete possible duplicate entries in 2 hop set
+ * and delete duplicate neighbor entries. Redirect
+ * link entries to the correct neighbor entry.
+ * This optimization is not specified in rfc3626.
  */
-
-void
-insert_mid_tuple(union olsr_ip_addr *m_addr, struct mid_address *alias,
-                olsr_reltime vtime)
+static void
+olsr_flush_nbr2_duplicates(struct mid_entry *alias)
 {
-  struct mid_entry *tmp;
-  struct mid_address *tmp_adr;
-  olsr_u32_t hash, alias_hash;
-  union olsr_ip_addr *registered_m_addr;
-
-  hash = olsr_ip_hashing(m_addr);
-  alias_hash = olsr_ip_hashing(&alias->alias);
-
-  /* Check for registered entry */
-  for (tmp = mid_set[hash].next; tmp != &mid_set[hash]; tmp = tmp->next) {
-    if (ipequal(&tmp->main_addr, m_addr))
-      break;
-  }
-
-  /* Check if alias is already registered with m_addr */
-  registered_m_addr = mid_lookup_main_addr(&alias->alias);
-  if (registered_m_addr != NULL && ipequal(registered_m_addr, m_addr)) {
-
-    /* Alias is already registered with main address. Nothing to do here. */
-    return;
-  }
-
-  /*
-   * Add a rt_path for the alias.
-   */
-  olsr_insert_routing_table(&alias->alias, olsr_cnf->maxplen, m_addr,
-                           OLSR_RT_ORIGIN_MID);
-
-  /*If the address was registered */
-  if (tmp != &mid_set[hash]) {
-    tmp_adr = tmp->aliases;
-    tmp->aliases = alias;
-    alias->main_entry = tmp;
-    QUEUE_ELEM(reverse_mid_set[alias_hash], alias);
-    alias->next_alias = tmp_adr;
-    olsr_set_mid_timer(tmp, vtime);
-  } else {
-
-    /*Create new node */
-    tmp = olsr_malloc(sizeof(struct mid_entry), "MID new alias");
-
-    tmp->aliases = alias;
-    alias->main_entry = tmp;
-    QUEUE_ELEM(reverse_mid_set[alias_hash], alias);
-    tmp->main_addr = *m_addr;
-    olsr_set_mid_timer(tmp, vtime);
-
-    /* Queue */
-    QUEUE_ELEM(mid_set[hash], tmp);
-  }
-
-
-
-  /*
-   * Delete possible duplicate entries in 2 hop set
-   * and delete duplicate neighbor entries. Redirect
-   * link entries to the correct neighbor entry.
-   *
-   *THIS OPTIMIZATION IS NOT SPECIFIED IN RFC3626
-   */
+  struct tc_entry *tc;
+  struct neighbor_2_entry *nbr2;
+  struct ipaddr_str buf1, buf2;
 
-  tmp_adr = alias;
+  tc = alias->mid_tc;
 
-  while (tmp_adr) {
-    struct neighbor_2_entry *tmp_2_neighbor;
-    struct neighbor_entry *tmp_neigh, *real_neigh;
+  OLSR_FOR_ALL_TC_MID_ENTRIES(tc, alias) {
+    struct neighbor_entry *nbr, *real_nbr;
 
     /* Delete possible 2 hop neighbor */
-    if ((tmp_2_neighbor =
-        olsr_lookup_two_hop_neighbor_table_mid(&tmp_adr->alias)) != NULL) {
-      struct ipaddr_str buf;
-      OLSR_PRINTF(1, "Deleting 2 hop node from MID: %s to ",
-                 olsr_ip_to_string(&buf, &tmp_adr->alias));
-      OLSR_PRINTF(1, "%s\n", olsr_ip_to_string(&buf, m_addr));
+    if ((nbr2 = olsr_lookup_two_hop_neighbor_table_mid(&alias->mid_alias_addr))) {
 
-      olsr_delete_two_hop_neighbor_table(tmp_2_neighbor);
+      OLSR_PRINTF(1, "MID: Delete 2hop neighbor: %s to %s\n",
+                 olsr_ip_to_string(&buf1, &alias->mid_alias_addr),
+                  olsr_ip_to_string(&buf2, &tc->addr));
 
+      olsr_delete_two_hop_neighbor_table(nbr2);
       changes_neighborhood = OLSR_TRUE;
     }
 
     /* Delete a possible neighbor entry */
-    if (((tmp_neigh =
-         olsr_lookup_neighbor_table_alias(&tmp_adr->alias)) != NULL)
-       && ((real_neigh = olsr_lookup_neighbor_table_alias(m_addr)) != NULL))
-    {
-      struct ipaddr_str buf;
-      OLSR_PRINTF(1, "[MID]Deleting bogus neighbor entry %s real ",
-                 olsr_ip_to_string(&buf, &tmp_adr->alias));
-      OLSR_PRINTF(1, "%s\n", olsr_ip_to_string(&buf, m_addr));
+    if ((nbr = olsr_lookup_neighbor_table_alias(&alias->mid_alias_addr)) &&
+        (real_nbr = olsr_lookup_neighbor_table_alias(&tc->addr))) {
+
+      OLSR_PRINTF(1, "MID: Delete bogus neighbor entry %s (real %s)\n",
+                 olsr_ip_to_string(&buf1, &alias->mid_alias_addr),
+                  olsr_ip_to_string(&buf2, &tc->addr));
 
-      replace_neighbor_link_set(tmp_neigh, real_neigh);
+      replace_neighbor_link_set(nbr, real_nbr);
 
       /* Dequeue */
-      DEQUEUE_ELEM(tmp_neigh);
+      DEQUEUE_ELEM(nbr);
       /* Delete */
-      free(tmp_neigh);
+      free(nbr);
 
       changes_neighborhood = OLSR_TRUE;
     }
-    tmp_adr = tmp_adr->next_alias;
-  }
+  } OLSR_FOR_ALL_TC_MID_ENTRIES_END(tc, mid_alias);
 }
 
-
 /**
- * Insert an alias address for a node.
- * If the main address is not registered
- * then a new entry is created.
- *
- * @param main_add the main address of the node
- * @param alias the alias address to insert
- * @param seq the sequence number to register a new node with
- * @return nada
+ * If we have an entry for this alias in neighbortable, we better adjust it's
+ * main address, because otherwise a fatal inconsistency between
+ * neighbortable and link_set will be created by way of this mid entry.
  */
-void
-insert_mid_alias(union olsr_ip_addr *main_add, const union olsr_ip_addr *alias,
-                olsr_reltime vtime)
+static void
+olsr_fixup_mid_main_addr (union olsr_ip_addr *main_addr,
+                          const union olsr_ip_addr *alias_addr)
 {
-  struct neighbor_entry *ne_old, *ne_new;
-  struct mid_entry *me_old;
-  int ne_ref_rp_count;
+  struct neighbor_entry *nbr_old, *nbr_new;
+  struct mid_entry *mid_old;
   struct ipaddr_str buf1, buf2;
-  struct mid_address *adr;
-  if (!olsr_validate_address(alias))
-    return;
+  int ne_ref_rp_count;
 
-  OLSR_PRINTF(1, "Inserting alias %s for ", olsr_ip_to_string(&buf1, alias));
-  OLSR_PRINTF(1, "%s\n", olsr_ip_to_string(&buf1, main_add));
+  nbr_old = olsr_lookup_neighbor_table_alias(alias_addr);
 
-  adr = olsr_malloc(sizeof(struct mid_address), "Insert MID alias");
+  if (nbr_old) {
 
-  adr->alias = *alias;
-  adr->next_alias = NULL;
+    OLSR_PRINTF(2, "MID: Main address change %s -> %s detected.\n",
+               olsr_ip_to_string(&buf1, alias_addr),
+                olsr_ip_to_string(&buf2, main_addr));
 
-  /*
-   * If we have an entry for this alias in neighbortable, we better adjust it's
-   * main address, because otherwise a fatal inconsistency between
-   * neighbortable and link_set will be created by way of this mid entry.
-   */
-  ne_old = olsr_lookup_neighbor_table_alias(alias);
-  if (ne_old != NULL) {
-    OLSR_PRINTF(2,
-               "Remote main address change detected. Mangling neighbortable to replace %s with %s.\n",
-               olsr_ip_to_string(&buf1, alias), olsr_ip_to_string(&buf2,
-                                                                  main_add));
-    olsr_delete_neighbor_table(alias);
-    ne_new = olsr_insert_neighbor_table(main_add);
-    /* adjust pointers to neighbortable-entry in link_set */
-    ne_ref_rp_count = replace_neighbor_link_set(ne_old, ne_new);
+    olsr_delete_neighbor_table(alias_addr);
+    nbr_new = olsr_insert_neighbor_table(main_addr);
+
+    /* Adjust pointers to neighbortable-entry in link_set */
+    ne_ref_rp_count = replace_neighbor_link_set(nbr_old, nbr_new);
     if (ne_ref_rp_count > 0)
-      OLSR_PRINTF(2,
-                 "Performed %d neighbortable-pointer replacements (%p -> %p) in link_set.\n",
-                 ne_ref_rp_count, ne_old, ne_new);
 
-    me_old = mid_lookup_entry_bymain(alias);
-    if (me_old) {
+#ifdef DEBUG
+      OLSR_PRINTF(2, "MID: Performed %d neighbortable-pointer replacements "
+                  "(%p -> %p) in link_set.\n",
+                 ne_ref_rp_count, nbr_old, nbr_new);
+#endif
+
+    mid_old = olsr_lookup_mid_entry(alias_addr);
+    if (mid_old) {
 
       /* 
-       * we knew aliases to the previous main address;
-       * better forget about them now.
+       * We knew aliases to the previous main address.
+       * Better forget about them now.
        */
-      OLSR_PRINTF(2, "I already have an mid entry mapping addresses to this "
-                  "alias address. Removing existing mid entry to preserve consistency of mid_set.\n");
-      olsr_delete_mid_entry(me_old);
+      OLSR_PRINTF(2, "MID: Flush aliases for old main address.\n");
+      olsr_flush_mid_entries(mid_old->mid_tc);
     }
   }
+}
 
-  insert_mid_tuple(main_add, adr, vtime);
+/**
+ * Insert a fresh alias address for a node.
+ *
+ * @param main_add the main address of the node
+ * @param alias the alias address to insert
+ * @param vtime the validity time
+ * @param seq the sequence number to register a new node with
+ */
+static struct mid_entry *
+olsr_insert_mid_entry(union olsr_ip_addr *main_addr,
+                      const union olsr_ip_addr *alias_addr,
+                      olsr_reltime vtime, olsr_u16_t mid_seqno)
+{
+  struct tc_entry *tc;
+  struct ipaddr_str buf1, buf2;
+  struct mid_entry *alias;
+
+  OLSR_PRINTF(1, "MID: Inserting alias %s for %s\n",
+              olsr_ip_to_string(&buf1, alias_addr),
+              olsr_ip_to_string(&buf2, main_addr));
 
   /*
-   *Recalculate topology
+   * Locate first the hookup point
    */
-  changes_neighborhood = OLSR_TRUE;
-  changes_topology = OLSR_TRUE;
+  tc = olsr_locate_tc_entry(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.
+   */
+  alias->mid_tc_node.key = &alias->mid_alias_addr;
+  avl_insert(&tc->mid_tree, &alias->mid_tc_node, AVL_DUP_NO);
+
+  /*
+   * Insert into the global mid tree.
+   */
+  alias->mid_node.key = &alias->mid_alias_addr;
+  avl_insert(&mid_tree, &alias->mid_node, AVL_DUP_NO);
+
+  /*
+   * Add a rt_path for the alias.
+   */
+  olsr_insert_routing_table(&alias->mid_alias_addr, olsr_cnf->maxplen,
+                            main_addr, OLSR_RT_ORIGIN_MID);
+  /*
+   * Start the timer.
+   */
+  olsr_set_mid_timer(alias->mid_tc, vtime);
+
+  /* Set sequence number for alias purging */
+  alias->mid_seqno = mid_seqno;
+
+  return alias;
 }
 
 /**
- * Lookup the main address for a alias address
+ * Update an alias address for a node.
+ * If the main address is not registered
+ * then a new entry is created.
  *
- * @param adr the alias address to check
- * @return the main address registered on the alias
- * or NULL if not found
+ * @param main_add the main address of the node
+ * @param alias the alias address to insert
+ * @param vtime the validity time
+ * @param seq the sequence number to register a new node with
  */
-union olsr_ip_addr *
-mid_lookup_main_addr(const union olsr_ip_addr *adr)
+void
+olsr_update_mid_entry(union olsr_ip_addr *main_addr,
+                      const union olsr_ip_addr *alias_addr,
+                      olsr_reltime vtime, olsr_u16_t mid_seqno)
 {
-  olsr_u32_t hash;
-  struct mid_address *tmp_list;
+  struct ipaddr_str buf1, buf2;
+  struct mid_entry *alias;
 
-  hash = olsr_ip_hashing(adr);
+  if (!olsr_validate_address(alias_addr)) {
+    return;
+  }
+
+  /*
+   * Check first if the alias already exists.
+   */
+  alias = olsr_lookup_mid_entry(alias_addr);
+  if (alias) {
 
-  /*Traverse MID list */
-  for (tmp_list = reverse_mid_set[hash].next;
-       tmp_list != &reverse_mid_set[hash]; tmp_list = tmp_list->next) {
-    if (ipequal(&tmp_list->alias, adr))
-      return &tmp_list->main_entry->main_addr;
+    /* Update sequence number for alias purging */
+    alias->mid_seqno = mid_seqno;
+
+    /* XXX handle main IP address changes */
+
+    /* Refresh the timer. */
+    olsr_set_mid_timer(alias->mid_tc, vtime);
+    return;
   }
-  return NULL;
+  /*
+   * This is a fresh alias.
+   */
+  alias = olsr_insert_mid_entry(main_addr, alias_addr, vtime, mid_seqno);
 
+  /*
+   * Do the needful if one of our neighbors has changed its main address.
+   */
+  olsr_fixup_mid_main_addr(main_addr, alias_addr);
+  olsr_flush_nbr2_duplicates(alias);
+
+  /*
+   * Recalculate topology.
+   */
+  changes_neighborhood = OLSR_TRUE;
+  changes_topology = OLSR_TRUE;
 }
 
-/*
- * Find mid entry to an address.
+/**
+ * Lookup a MID alias hanging off a tc_entry by address
  *
- * @param adr the main address to search for
- * @return a linked list of address structs
+ * @param adr the alias address to check
+ * @return the MID address entry or NULL if not found
  */
 struct mid_entry *
-mid_lookup_entry_bymain(const union olsr_ip_addr *adr)
+olsr_lookup_tc_mid_entry(struct tc_entry *tc, const union olsr_ip_addr *adr)
 {
-  struct mid_entry *tmp_list;
-  olsr_u32_t hash;
-
-  hash = olsr_ip_hashing(adr);
+#if 0
+  OLSR_PRINTF(1, "MID: lookup main address\n");
+#endif
 
-  /* Check all registered nodes... */
-  for (tmp_list = mid_set[hash].next;
-       tmp_list != &mid_set[hash]; tmp_list = tmp_list->next) {
-    if (ipequal(&tmp_list->main_addr, adr))
-      return tmp_list;
-  }
-  return NULL;
+  return (alias_tree2mid(avl_find(&tc->mid_tree, adr)));
 }
 
-/*
- * Find all aliases for an address.
+/**
+ * Lookup an MID alias by address in the global tree.
  *
- * @param adr the main address to search for
- * @return a linked list of addresses structs
+ * @param adr the alias address to check
+ * @return the MID address entry or NULL if not found
  */
-struct mid_address *
-mid_lookup_aliases(const union olsr_ip_addr *adr)
+struct mid_entry *
+olsr_lookup_mid_entry(const union olsr_ip_addr *adr)
 {
-  struct mid_entry *tmp = mid_lookup_entry_bymain(adr);
-  return tmp ? tmp->aliases : NULL;
-}
+#if 0
+  OLSR_PRINTF(1, "MID: lookup main address\n");
+#endif
 
+  return (global_tree2mid(avl_find(&mid_tree, adr)));
+}
 
 /**
- * Update the timer for an MID entry
+ * Lookup the main address for an MID alias address
  *
- * @param adr the main address of the entry
- * @return 1 if the node was updated, 0 if not
+ * @param adr the alias address to check
+ * @return the main address registered on the alias
+ * or NULL if not found
  */
-int
-olsr_update_mid_table(const union olsr_ip_addr *adr, olsr_reltime vtime)
+union olsr_ip_addr *
+olsr_lookup_main_addr_by_alias(const union olsr_ip_addr *adr)
 {
-  olsr_u32_t hash;
-  struct ipaddr_str buf;
-  struct mid_entry *tmp_list = mid_set;
+  struct mid_entry *alias;
 
-  OLSR_PRINTF(3, "MID: update %s\n", olsr_ip_to_string(&buf, adr));
-  hash = olsr_ip_hashing(adr);
+#if 0
+  OLSR_PRINTF(1, "MID: lookup main address\n");
+#endif
 
-  /* Check all registered nodes... */
-  for (tmp_list = mid_set[hash].next;
-       tmp_list != &mid_set[hash]; tmp_list = tmp_list->next) {
-    /*find match */
-    if (ipequal(&tmp_list->main_addr, adr)) {
-      olsr_set_mid_timer(tmp_list, vtime);
+  alias = olsr_lookup_mid_entry(adr);
 
-      return 1;
-    }
-  }
-  return 0;
+  return (alias ? &alias->mid_tc->addr : NULL);
 }
 
-
 /**
- * Remove aliases from 'entry' which are not listed in 'declared_aliases'.
- *
- * @param entry the MID entry
- * @param declared_aliases the list of declared aliases for the MID entry
- * @return nada
+ * Delete a single MID alias.
+ * 
+ * @param alias the alias to delete.
  */
-void
-olsr_prune_aliases(const union olsr_ip_addr *m_addr,
-                  struct mid_alias *declared_aliases)
+static void
+olsr_delete_mid_entry(struct mid_entry *alias)
 {
-  struct mid_entry *entry;
-  olsr_u32_t hash;
-  struct mid_address *registered_aliases;
-  struct mid_address *previous_alias;
-  struct mid_alias *save_declared_aliases = declared_aliases;
-
-  hash = olsr_ip_hashing(m_addr);
-
-  /* Check for registered entry */
-  for (entry = mid_set[hash].next; entry != &mid_set[hash]; entry = entry->next) {
-    if (ipequal(&entry->main_addr, m_addr))
-      break;
-  }
-  if (entry == &mid_set[hash]) {
-    /* MID entry not found, nothing to prune here */
-    return;
-  }
+  struct tc_entry *tc;
 
-  registered_aliases = entry->aliases;
-  previous_alias = NULL;
+  tc = alias->mid_tc;
 
-  while (registered_aliases != NULL) {
-    struct mid_address *current_alias = registered_aliases;
-    registered_aliases = registered_aliases->next_alias;
-
-    declared_aliases = save_declared_aliases;
+  /*
+   * Delete the rt_path for the alias.
+   */
+  olsr_delete_routing_table(&alias->mid_alias_addr, olsr_cnf->maxplen,
+                            &tc->addr);
 
-    /* Go through the list of declared aliases to find the matching current alias */
-    while (declared_aliases != 0 &&
-          !ipequal(&current_alias->alias, &declared_aliases->alias_addr)) {
-      declared_aliases = declared_aliases->next;
-    }
+  /*
+   * Remove from the per-tc tree.
+   */
+  avl_delete(&tc->mid_tree, &alias->mid_tc_node);
 
-    if (declared_aliases == NULL) {
-      struct ipaddr_str buf;
-      /* Current alias not found in list of declared aliases: free current alias */
-      OLSR_PRINTF(1, "MID remove: (%s, ",
-                 olsr_ip_to_string(&buf, &entry->main_addr));
-      OLSR_PRINTF(1, "%s)\n", olsr_ip_to_string(&buf, &current_alias->alias));
-
-      /* Update linked list as seen by 'entry' */
-      if (previous_alias != NULL) {
-       previous_alias->next_alias = current_alias->next_alias;
-      } else {
-       entry->aliases = current_alias->next_alias;
-      }
-
-      /* Remove from hash table */
-      DEQUEUE_ELEM(current_alias);
-
-      /*
-       * Delete the rt_path for the alias.
-       */
-      olsr_delete_routing_table(&current_alias->alias, olsr_cnf->maxplen,
-                               &entry->main_addr);
+  /*
+   * Remove from the global tree.
+   */
+  avl_delete(&mid_tree, &alias->mid_node);
 
-      free(current_alias);
+  olsr_unlock_tc_entry(tc);
 
-      /*
-       *Recalculate topology
-       */
-      changes_neighborhood = OLSR_TRUE;
-      changes_topology = OLSR_TRUE;
-    } else {
-      previous_alias = current_alias;
-    }
-  }
+  olsr_cookie_free(mid_address_mem_cookie, alias);
 }
 
-
 /**
- * Delete a MID entry
+ * Delete all the MID aliases hanging off a tc entry.
  *
- * @param entry the entry to delete
+ * @param entry the tc entry holding the aliases.
  */
 void
-olsr_delete_mid_entry(struct mid_entry *mid)
+olsr_flush_mid_entries(struct tc_entry *tc)
 {
-  struct mid_address *aliases;
-
-  /* Free aliases */
-  aliases = mid->aliases;
-  while (aliases) {
-    struct mid_address *tmp_aliases = aliases;
-    aliases = aliases->next_alias;
-    DEQUEUE_ELEM(tmp_aliases);
-
-
-    /*
-     * Delete the rt_path for the alias.
-     */
-    olsr_delete_routing_table(&tmp_aliases->alias, olsr_cnf->maxplen,
-                             &mid->main_addr);
+  struct mid_entry *alias;
 
-    free(tmp_aliases);
-  }
+  OLSR_FOR_ALL_TC_MID_ENTRIES(tc, alias) {
+    olsr_delete_mid_entry(alias);
+  } OLSR_FOR_ALL_TC_MID_ENTRIES_END(tc, alias);
 
   /*
    * Kill any pending timers.
    */
-  if (mid->mid_timer) {
-    olsr_stop_timer(mid->mid_timer);
-    mid->mid_timer = NULL;
-  }
-
-  /* Dequeue */
-  DEQUEUE_ELEM(mid);
-  free(mid);
+  olsr_set_mid_timer(tc, 0);
 }
 
+/**
+ * Remove aliases from 'entry' which are not matching
+ * the most recent message sequence number. This gets
+ * called after receiving a MID message for garbage
+ * collection of the old entries.
+ *
+ * @param main_addr the root of MID entries.
+ * @param mid_seqno the most recent message sequence number
+ */
+void
+olsr_prune_mid_entries(const union olsr_ip_addr *main_addr, olsr_u16_t mid_seqno)
+{
+  struct tc_entry *tc;
+  struct mid_entry *alias;
+
+  tc = olsr_locate_tc_entry(main_addr);
+
+  OLSR_FOR_ALL_TC_MID_ENTRIES(tc, alias) {
+    if (alias->mid_seqno != mid_seqno) {
+      olsr_delete_mid_entry(alias);
+    }
+  } OLSR_FOR_ALL_TC_MID_ENTRIES_END(tc, alias);
+}
 
 /**
  * Print all MID entries
@@ -530,27 +466,21 @@ olsr_delete_mid_entry(struct mid_entry *mid)
 void
 olsr_print_mid_set(void)
 {
-  int idx;
+  struct tc_entry *tc;
+  struct mid_entry *alias;
+  struct ipaddr_str buf;
 
   OLSR_PRINTF(1,
              "\n--- %s ------------------------------------------------- MID\n\n",
              olsr_wallclock_string());
 
-  for (idx = 0; idx < HASHSIZE; idx++) {
-    struct mid_entry *tmp_list = mid_set[idx].next;
-    /*Traverse MID list */
-    for (tmp_list = mid_set[idx].next; tmp_list != &mid_set[idx];
-        tmp_list = tmp_list->next) {
-      struct mid_address *tmp_addr;
-      struct ipaddr_str buf;
-      OLSR_PRINTF(1, "%s: ", olsr_ip_to_string(&buf, &tmp_list->main_addr));
-      for (tmp_addr = tmp_list->aliases; tmp_addr;
-          tmp_addr = tmp_addr->next_alias) {
-       OLSR_PRINTF(1, " %s ", olsr_ip_to_string(&buf, &tmp_addr->alias));
-      }
-      OLSR_PRINTF(1, "\n");
-    }
-  }
+  OLSR_FOR_ALL_TC_ENTRIES(tc) {
+    OLSR_PRINTF(1, "%s: ", olsr_ip_to_string(&buf, &tc->addr));
+    OLSR_FOR_ALL_TC_MID_ENTRIES(tc, alias) {
+      OLSR_PRINTF(1, " %s ", olsr_ip_to_string(&buf, &alias->mid_alias_addr));
+    } OLSR_FOR_ALL_TC_MID_ENTRIES_END(tc, alias);
+    OLSR_PRINTF(1, "\n");
+  } OLSR_FOR_ALL_TC_ENTRIES_END(tc);
 }
 
 /*
index debacd9..c6dc29e 100644 (file)
 #define _OLSR_MID
 
 #include "olsr_types.h"
-#include "hashing.h"
-#include "mantissa.h"
+#include "common/avl.h"
 
-struct mid_address {
-  union olsr_ip_addr alias;
-  struct mid_entry *main_entry;
-  struct mid_address *next_alias;
-
-  /* These are for the reverse list */
-  struct mid_address *prev;
-  struct mid_address *next;
-};
-
-/*
- * Contains the main addr of a node and a list of aliases
- */
 struct mid_entry {
-  union olsr_ip_addr main_addr;
-  struct mid_address *aliases;
-  struct mid_entry *prev;
-  struct mid_entry *next;
-  struct timer_entry *mid_timer;
+  struct avl_node mid_tc_node;       /* node in the per-tc mid tree */
+  struct avl_node mid_node;             /* node in the global mid tree */
+  union olsr_ip_addr mid_alias_addr;    /* key for both trees */
+  struct tc_entry  *mid_tc;             /* backpointer to owning tc entry */
+  olsr_u16_t mid_seqno;                 /* msg seq number for change tracking */
 };
 
+AVLNODE2STRUCT(global_tree2mid, struct mid_entry, mid_node);
+AVLNODE2STRUCT(alias_tree2mid, struct mid_entry, mid_tc_node);
+
+#define OLSR_FOR_ALL_MID_ENTRIES(mid_alias) \
+{ \
+  struct avl_node *mid_alias_node, *next_mid_alias_node; \
+  for (mid_alias_node = avl_walk_first(&mid_tree); \
+    mid_alias_node; mid_alias_node = next_mid_alias_node) { \
+    next_mid_alias_node = avl_walk_next(mid_alias_node); \
+    mid_alias = reverse_tree2mid(mid_alias_node);
+#define OLSR_FOR_ALL_MID_ENTRIES_END(mid_alias) }}
+
+#define OLSR_FOR_ALL_TC_MID_ENTRIES(tc, mid_alias) \
+{ \
+  struct avl_node *mid_alias_node, *next_mid_alias_node; \
+  for (mid_alias_node = avl_walk_first(&tc->mid_tree); \
+    mid_alias_node; mid_alias_node = next_mid_alias_node) { \
+    next_mid_alias_node = avl_walk_next(mid_alias_node); \
+    mid_alias = alias_tree2mid(mid_alias_node);
+#define OLSR_FOR_ALL_TC_MID_ENTRIES_END(tc, mid_alias) }}
+
 #define OLSR_MID_JITTER 5      /* percent */
 
-extern struct mid_entry mid_set[HASHSIZE];
-extern struct mid_address reverse_mid_set[HASHSIZE];
+extern struct avl_tree mid_tree;
 
 struct mid_alias;
 
-int olsr_init_mid_set(void);
-void insert_mid_tuple(union olsr_ip_addr *, struct mid_address *, olsr_reltime);
-void insert_mid_alias(union olsr_ip_addr *, const union olsr_ip_addr *, olsr_reltime);
-union olsr_ip_addr *mid_lookup_main_addr(const union olsr_ip_addr *);
-struct mid_address *mid_lookup_aliases(const union olsr_ip_addr *);
-struct mid_entry *mid_lookup_entry_bymain(const union olsr_ip_addr *);
+void olsr_init_mid_set(void);
+void olsr_update_mid_entry(union olsr_ip_addr *, const union olsr_ip_addr *,
+                           olsr_reltime, olsr_u16_t);
+union olsr_ip_addr *olsr_lookup_main_addr_by_alias(const union olsr_ip_addr *);
+struct mid_entry *olsr_lookup_mid_entry(const union olsr_ip_addr *);
+struct mid_entry *olsr_lookup_tc_mid_entry(struct tc_entry *,
+                                               const union olsr_ip_addr *);
+void olsr_prune_mid_entries(const union olsr_ip_addr *, olsr_u16_t);
+void olsr_flush_mid_entries(struct tc_entry *);
 void olsr_print_mid_set(void);
-void olsr_prune_aliases(const union olsr_ip_addr *, struct mid_alias *);
-int olsr_update_mid_table(const union olsr_ip_addr *, olsr_reltime);
-void olsr_delete_mid_entry(struct mid_entry *);
 
 #endif
 
index 2c4c1cf..ef5b842 100644 (file)
@@ -284,7 +284,7 @@ olsr_lookup_neighbor_table(const union olsr_ip_addr *dst)
   /*
    *Find main address of node
    */
-  union olsr_ip_addr *tmp_ip = mid_lookup_main_addr(dst);
+  union olsr_ip_addr *tmp_ip = olsr_lookup_main_addr_by_alias(dst);
   if(tmp_ip != NULL)
     dst = tmp_ip;
   return olsr_lookup_neighbor_table_alias(dst);
index e9626c1..426beb0 100644 (file)
@@ -327,7 +327,7 @@ olsr_forward_message(union olsr_message *m,
   }
 
   /* Lookup sender address */
-  src = mid_lookup_main_addr(from_addr);
+  src = olsr_lookup_main_addr_by_alias(from_addr);
   if(!src)
     src = from_addr;
 
index 2367ea0..a1f6083 100644 (file)
@@ -98,7 +98,7 @@ process_message_neighbors(struct neighbor_entry *neighbor, const struct hello_me
         continue;
 
       /* Get the main address */
-      neigh_addr = mid_lookup_main_addr(&message_neighbors->address);
+      neigh_addr = olsr_lookup_main_addr_by_alias(&message_neighbors->address);
 
       if (neigh_addr != NULL) {
         message_neighbors->address = *neigh_addr;
@@ -554,37 +554,31 @@ olsr_process_received_mid(union olsr_message *m,
   }
 
 #ifdef DEBUG
-    OLSR_PRINTF(5, "Processing MID from %s...\n", olsr_ip_to_string(&buf, &message.mid_origaddr));
+  OLSR_PRINTF(5, "Processing MID from %s\n",
+              olsr_ip_to_string(&buf, &message.mid_origaddr));
 #endif
-    tmp_adr = message.mid_addr;
+  tmp_adr = message.mid_addr;
 
-    /*
-     *      If the sender interface (NB: not originator) of this message
-     *      is not in the symmetric 1-hop neighborhood of this node, the
-     *      message MUST be discarded.
-     */
-
-    if(check_neighbor_link(from_addr) != SYM_LINK) {
-      struct ipaddr_str buf;
-      OLSR_PRINTF(2, "Received MID from NON SYM neighbor %s\n", olsr_ip_to_string(&buf, from_addr));
-      olsr_free_mid_packet(&message);
-      return;
-    }
-
-    /* Update the timeout of the MID */
-    olsr_update_mid_table(&message.mid_origaddr, message.vtime);
+  /*
+   * If the sender interface (NB: not originator) of this message
+   * is not in the symmetric 1-hop neighborhood of this node, the
+   *  message MUST be discarded.
+   */
+  if (check_neighbor_link(from_addr) != SYM_LINK) {
+    struct ipaddr_str buf;
+    OLSR_PRINTF(2, "Received MID from NON SYM neighbor %s\n",
+                olsr_ip_to_string(&buf, from_addr));
+    olsr_free_mid_packet(&message);
+    return;
+  }
 
-    while (tmp_adr) {
-      if (!mid_lookup_main_addr(&tmp_adr->alias_addr)){
-        struct ipaddr_str buf;
-        OLSR_PRINTF(1, "MID new: (%s, ", olsr_ip_to_string(&buf, &message.mid_origaddr));
-        OLSR_PRINTF(1, "%s)\n", olsr_ip_to_string(&buf, &tmp_adr->alias_addr));
-        insert_mid_alias(&message.mid_origaddr, &tmp_adr->alias_addr, message.vtime);
-      }
-      tmp_adr = tmp_adr->next;
-    } 
+  while (tmp_adr) {
+    olsr_update_mid_entry(&message.mid_origaddr, &tmp_adr->alias_addr,
+                          message.vtime, message.mid_seqno);
+    tmp_adr = tmp_adr->next;
+  } 
   
-    olsr_prune_aliases(&message.mid_origaddr, message.mid_addr);
+  olsr_prune_mid_entries(&message.mid_origaddr, message.mid_seqno);
 
   olsr_forward_message(m, from_addr);
   olsr_free_mid_packet(&message);
index 5b6a327..ddfc8aa 100644 (file)
@@ -168,7 +168,6 @@ mid_chgestruct(struct mid_message *mmsg, const union olsr_message *m)
          OLSR_PRINTF(3, "\n");
        }
     }
-
 }
 
 
index 7aaad04..087089d 100644 (file)
@@ -521,8 +521,8 @@ olsr_rt_best(struct rt_entry *rt)
  *@return the new rt_path struct
  */
 struct rt_path *
-olsr_insert_routing_table(union olsr_ip_addr *dst, int plen,
-                          union olsr_ip_addr *originator, int origin)
+olsr_insert_routing_table(const union olsr_ip_addr *dst, int plen,
+                          const union olsr_ip_addr *originator, int origin)
 {
 #ifdef DEBUG
   struct ipaddr_str dstbuf, origbuf;
index 01d532e..448fe84 100644 (file)
@@ -226,7 +226,8 @@ void olsr_print_routing_table(struct avl_tree *);
 const struct rt_nexthop * olsr_get_nh(const struct rt_entry *);
 
 /* rt_path manipulation */
-struct rt_path *olsr_insert_routing_table(union olsr_ip_addr *, int, union olsr_ip_addr *, int);
+struct rt_path *olsr_insert_routing_table(const union olsr_ip_addr *, const int,
+                                          const union olsr_ip_addr *, const int);
 void olsr_delete_routing_table(union olsr_ip_addr *, int, union olsr_ip_addr *);
 void olsr_insert_rt_path(struct rt_path *, struct tc_entry *, struct link_entry *);
 void olsr_update_rt_path(struct rt_path *, struct tc_entry *, struct link_entry *);
index 1929993..4598795 100644 (file)
@@ -130,7 +130,7 @@ olsr_seq_inrange_high(int beg, int end, olsr_u16_t seq)
  * @return a pointer to the created entry
  */
 static struct tc_entry *
-olsr_add_tc_entry(union olsr_ip_addr *adr)
+olsr_add_tc_entry(const union olsr_ip_addr *adr)
 {
 #ifdef DEBUG
   struct ipaddr_str buf;
@@ -312,7 +312,7 @@ olsr_delete_tc_entry(struct tc_entry *tc)
  * @return the entry found or NULL
  */
 struct tc_entry *
-olsr_lookup_tc_entry(union olsr_ip_addr *adr)
+olsr_lookup_tc_entry(const union olsr_ip_addr *adr)
 {
   struct avl_node *node;
 
@@ -329,7 +329,7 @@ olsr_lookup_tc_entry(union olsr_ip_addr *adr)
  * Lookup a tc entry. Creates one if it does not exist yet.
  */
 struct tc_entry *
-olsr_locate_tc_entry(union olsr_ip_addr *adr)
+olsr_locate_tc_entry(const union olsr_ip_addr *adr)
 {
   struct tc_entry *tc;
 
index 34c1601..eb6b1aa 100644 (file)
@@ -76,6 +76,8 @@ struct tc_entry {
   struct list_node path_list_node;     /* SPF result list */
   struct avl_tree edge_tree;          /* subtree for edges */
   struct avl_tree prefix_tree;        /* subtree for prefixes */
+  struct avl_tree mid_tree;            /* subtree for MID entries */
+  struct timer_entry *mid_timer;       /* aging timer for MID advertisements */
   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 */
@@ -152,8 +154,8 @@ void olsr_input_tc(union olsr_message *, struct interface *,
                   union olsr_ip_addr *from);
 
 /* tc_entry manipulation */
-struct tc_entry *olsr_lookup_tc_entry(union olsr_ip_addr *);
-struct tc_entry *olsr_locate_tc_entry(union olsr_ip_addr *);
+struct tc_entry *olsr_lookup_tc_entry(const union olsr_ip_addr *);
+struct tc_entry *olsr_locate_tc_entry(const union olsr_ip_addr *);
 void olsr_lock_tc_entry(struct tc_entry *);
 void olsr_unlock_tc_entry(struct tc_entry *);
 
index 9cddc04..c26350d 100644 (file)
@@ -168,6 +168,7 @@ struct neighbor_2_entry *
 olsr_lookup_two_hop_neighbor_table(const union olsr_ip_addr *dest)
 {
 
+  struct tc_entry *tc;
   struct neighbor_2_entry  *neighbor_2;
   olsr_u32_t               hash = olsr_ip_hashing(dest);
 
@@ -176,20 +177,18 @@ olsr_lookup_two_hop_neighbor_table(const union olsr_ip_addr *dest)
       neighbor_2 != &two_hop_neighbortable[hash];
       neighbor_2 = neighbor_2->next)
     {
-      struct mid_address *adr;
 
       /* printf("Checking %s\n", olsr_ip_to_string(&buf, dest)); */
       if (ipequal(&neighbor_2->neighbor_2_addr, dest))
        return neighbor_2;
 
-      adr = mid_lookup_aliases(&neighbor_2->neighbor_2_addr);
-
-      while(adr)
-       {
-         if(ipequal(&adr->alias, dest))
-           return neighbor_2;
-         adr = adr->next_alias;
-       } 
+      /*
+       * Locate the hookup point and check if this is a registered alias.
+       */
+      tc = olsr_locate_tc_entry(&neighbor_2->neighbor_2_addr);
+      if (olsr_lookup_tc_mid_entry(tc, dest)) {
+        return neighbor_2;
+      }
     }
 
   return NULL;
@@ -272,3 +271,9 @@ olsr_print_two_hop_neighbor_table(void)
   }
 #endif
 }
+
+/*
+ * Local Variables:
+ * c-basic-offset: 2
+ * End:
+ */