* added the rest if the olsrd-fixes-eric patch from Sven-Ola
authorBernd Petrovitsch <bernd@firmix.at>
Sat, 10 Feb 2007 19:27:33 +0000 (19:27 +0000)
committerBernd Petrovitsch <bernd@firmix.at>
Sat, 10 Feb 2007 19:27:33 +0000 (19:27 +0000)
14 files changed:
files/olsrd.conf.default.lq
files/olsrd.conf.default.lq-fisheye
files/olsrd.conf.default.rfc
src/hysteresis.c
src/link_set.c
src/link_set.h
src/local_hna_set.c
src/local_hna_set.h
src/lq_mpr.c
src/mid_set.c
src/mid_set.h
src/process_package.c
src/routing_table.c
src/unix/ifnet.c

index 2116ec6..0dbdca7 100644 (file)
@@ -272,6 +272,7 @@ Interface "XXX" "YYY"
     # HNA validity time
     HnaValidityTime    30.0
 
+
     # When multiple links exist between hosts
     # the weight of interface is used to determine
     # the link to use. Normally the weight is
@@ -279,9 +280,29 @@ Interface "XXX" "YYY"
     # on the characteristics of the interface,
     # but here you can specify a fixed value.
     # Olsrd will choose links with the lowest value.
-
+    # Note:
+    # Interface weight is used only when LinkQualityLevel is 0.
+    # For any other value of LinkQualityLevel, the interface ETX
+    # value is used instead.
     # Weight 0
 
 
+    # If a certain route should be preferred 
+    # or ignored by the mesh, the Link Quality 
+    # value of a node can be multiplied with a factor 
+    # entered here. In the example the route 
+    # using 192.168.0.1 would rather be ignored.
+    # A multiplier of 0.5 will result in a small
+    # (bad) LinkQuality value and a high (bad)
+    # ETX value.
+    # Note:
+    # Link quality multiplier is used only when
+    # LinkQualityLevel is > 0.
+
+    # LinkQualityMult 192.168.0.1 0.5
+
+    # This multiplier applies to all other nodes 
+    # LinkQualityMult default 0.8
+
 }
 
index 1cfc249..4ab0ee2 100644 (file)
@@ -281,6 +281,7 @@ Interface "XXX" "YYY"
     # HNA validity time
     HnaValidityTime    100.0
 
+
     # When multiple links exist between hosts
     # the weight of interface is used to determine
     # the link to use. Normally the weight is
@@ -288,7 +289,10 @@ Interface "XXX" "YYY"
     # on the characteristics of the interface,
     # but here you can specify a fixed value.
     # Olsrd will choose links with the lowest value.
-
+    # Note:
+    # Interface weight is used only when LinkQualityLevel is set to 0.
+    # For any other value of LinkQualityLevel, the interface ETX
+    # value is used instead.
     # Weight 0
 
 
@@ -300,13 +304,14 @@ Interface "XXX" "YYY"
     # A multiplier of 0.5 will result in a small
     # (bad) LinkQuality value and a high (bad)
     # ETX value.
+    # Note:
+    # Link quality multiplier is used only when
+    # LinkQualityLevel is > 0.
 
     # LinkQualityMult 192.168.0.1 0.5
 
     # This multiplier applies to all other nodes 
     # LinkQualityMult default 0.8
-
 
 }
 
index 3fdbc73..469cd13 100644 (file)
@@ -267,6 +267,7 @@ Interface "XXX" "YYY"
     # HNA validity time
     # HnaValidityTime  15.0
 
+
     # When multiple links exist between hosts
     # the weight of interface is used to determine
     # the link to use. Normally the weight is
@@ -274,9 +275,29 @@ Interface "XXX" "YYY"
     # on the characteristics of the interface,
     # but here you can specify a fixed value.
     # Olsrd will choose links with the lowest value.
-
+    # Note:
+    # Interface weight is used only when LinkQualityLevel is set to 0.
+    # For any other value of LinkQualityLevel, the interface ETX
+    # value is used instead.
     # Weight 0
 
 
+    # If a certain route should be preferred 
+    # or ignored by the mesh, the Link Quality 
+    # value of a node can be multiplied with a factor 
+    # entered here. In the example the route 
+    # using 192.168.0.1 would rather be ignored.
+    # A multiplier of 0.5 will result in a small
+    # (bad) LinkQuality value and a high (bad)
+    # ETX value.
+    # Note:
+    # Link quality multiplier is used only when
+    # LinkQualityLevel is > 0.
+
+    # LinkQualityMult 192.168.0.1 0.5
+
+    # This multiplier applies to all other nodes 
+    # LinkQualityMult default 0.8
+
 }
 
index 974aaac..fb58570 100644 (file)
@@ -36,7 +36,7 @@
  * to the project. For more information see the website or contact
  * the copyright holders.
  *
- * $Id: hysteresis.c,v 1.17 2006/12/14 11:29:19 bernd67 Exp $
+ * $Id: hysteresis.c,v 1.18 2007/02/10 19:27:32 bernd67 Exp $
  */
 
 
@@ -166,7 +166,7 @@ update_hysteresis_incoming(union olsr_ip_addr *remote, struct interface *local,
 {
   struct link_entry *link;
 
-  link = lookup_link_entry(remote, local);
+  link = lookup_link_entry(remote, NULL, local);
 
   /* Calculate new quality */      
   if(link != NULL)
index 7a213d3..eb354f3 100644 (file)
@@ -36,7 +36,7 @@
  * to the project. For more information see the website or contact
  * the copyright holders.
  *
- * $Id: link_set.c,v 1.65 2007/01/31 12:36:50 bernd67 Exp $
+ * $Id: link_set.c,v 1.66 2007/02/10 19:27:32 bernd67 Exp $
  */
 
 
@@ -202,7 +202,7 @@ get_neighbor_status(union olsr_ip_addr *address)
 
       //printf("\tChecking %s->", olsr_ip_to_string(&ifs->ip_addr));
       //printf("%s : ", olsr_ip_to_string(main_addr)); 
-      if((link = lookup_link_entry(main_addr, ifs)) != NULL)
+      if((link = lookup_link_entry(main_addr, NULL, ifs)) != NULL)
        {
          //printf("%d\n", lookup_link_status(link));
          if(lookup_link_status(link) == SYM_LINK)
@@ -215,7 +215,7 @@ get_neighbor_status(union olsr_ip_addr *address)
        {
          //printf("\tChecking %s->", olsr_ip_to_string(&ifs->ip_addr));
          //printf("%s : ", olsr_ip_to_string(&aliases->address)); 
-         if((link = lookup_link_entry(&aliases->alias, ifs)) != NULL)
+            if((link = lookup_link_entry(&aliases->alias, NULL, ifs)) != NULL)
            {
              //printf("%d\n", lookup_link_status(link));
 
@@ -263,7 +263,7 @@ get_best_link_to_neighbor(union olsr_ip_addr *remote)
     if (!COMP_IP(&walker->neighbor->neighbor_main_addr, main_addr))
       continue;
 
-    // handle the non-LQ case
+    // handle the non-LQ, RFC-compliant case
 
     if (olsr_cnf->lq_level == 0)
     {
@@ -298,7 +298,7 @@ get_best_link_to_neighbor(union olsr_ip_addr *remote)
       }
     }
 
-    // handle the LQ case
+    // handle the LQ, non-RFC compliant case
 
     else
     {
@@ -450,7 +450,7 @@ del_if_link_entries(union olsr_ip_addr *int_addr)
  *
  *@param local the local IP address
  *@param remote the remote IP address
- *@param remote_main teh remote nodes main address
+ *@param remote_main the remote nodes main address
  *@param vtime the validity time of the entry
  *@param htime the HELLO interval of the remote node
  *@param local_if the local interface
@@ -462,7 +462,7 @@ add_new_entry(union olsr_ip_addr *local, union olsr_ip_addr *remote, union olsr_
   struct link_entry *tmp_link_set, *new_link;
   struct neighbor_entry *neighbor;
 
-  if((tmp_link_set = lookup_link_entry(remote, local_if))) return tmp_link_set;
+  if((tmp_link_set = lookup_link_entry(remote, remote_main, local_if))) return tmp_link_set;
 
   /*
    * if there exists no link tuple with
@@ -567,7 +567,12 @@ add_new_entry(union olsr_ip_addr *local, union olsr_ip_addr *remote, union olsr_
 
   /* Copy the main address - make sure this is done every time
    * as neighbors might change main address */
-  COPY_IP(&neighbor->neighbor_main_addr, remote_main);
+  /* Erik Tromp - OOPS! Don't do this! Neighbor entries are hashed through their
+   * neighbor_main_addr field, and when that field is changed, their position
+   * in the hash table is no longer correct, so that the function
+   * olsr_lookup_neighbor_table() can no longer find the neighbor
+   * entry. */
+  /*COPY_IP(&neighbor->neighbor_main_addr, remote_main);*/
 
   neighbor->linkcount++;
 
@@ -582,9 +587,14 @@ add_new_entry(union olsr_ip_addr *local, union olsr_ip_addr *remote, union olsr_
        * We'll go for one that is hopefully long
        * enough in most cases. 10 seconds
        */
-      OLSR_PRINTF(1, "Adding MID alias main %s ", olsr_ip_to_string(remote_main))
-      OLSR_PRINTF(1, "-> %s based on HELLO\n\n", olsr_ip_to_string(remote))
-      insert_mid_alias(remote_main, remote, MID_ALIAS_HACK_VTIME);
+    /* Erik Tromp - commented out. It is not RFC-compliant. Also, MID aliases
+     * that are not explicitly declared by a node will be removed as soon as
+     * the olsr_prune_aliases(...) function is called.
+     *
+     * OLSR_PRINTF(1, "Adding MID alias main %s ", olsr_ip_to_string(remote_main))
+     * OLSR_PRINTF(1, "-> %s based on HELLO\n\n", olsr_ip_to_string(remote))
+     * insert_mid_alias(remote_main, remote, MID_ALIAS_HACK_VTIME);
+     */
     }
 
   return link_set;
@@ -620,12 +630,13 @@ check_neighbor_link(union olsr_ip_addr *int_addr)
  *Lookup a link entry
  *
  *@param remote the remote interface address
+ *@param remote_main the remote nodes main address
  *@param local the local interface address
  *
  *@return the link entry if found, NULL if not
  */
 struct link_entry *
-lookup_link_entry(union olsr_ip_addr *remote, struct interface *local)
+lookup_link_entry(union olsr_ip_addr *remote, union olsr_ip_addr *remote_main, struct interface *local)
 {
   struct link_entry *tmp_link_set;
 
@@ -634,10 +645,13 @@ lookup_link_entry(union olsr_ip_addr *remote, struct interface *local)
   while(tmp_link_set)
     {
       if(COMP_IP(remote, &tmp_link_set->neighbor_iface_addr) &&
-        (tmp_link_set->if_name ?
-         !strcmp(tmp_link_set->if_name, local->int_name) :
-         COMP_IP(&local->ip_addr, &tmp_link_set->local_iface_addr)
-        ))
+        (tmp_link_set->if_name
+          ? !strcmp(tmp_link_set->if_name, local->int_name)
+          : COMP_IP(&local->ip_addr, &tmp_link_set->local_iface_addr)
+          ) &&
+         /* check the remote-main address only if there is one given */
+         (remote_main == NULL || COMP_IP(remote_main, &tmp_link_set->neighbor->neighbor_main_addr))
+         )
        return tmp_link_set;
       tmp_link_set = tmp_link_set->next;
     }
@@ -1072,7 +1086,7 @@ void olsr_update_packet_loss(union olsr_ip_addr *rem, struct interface *loc,
 
   // called for every OLSR packet
 
-  entry = lookup_link_entry(rem, loc);
+  entry = lookup_link_entry(rem, NULL, loc);
 
   // it's the very first LQ HELLO message - we do not yet have a link
 
index ac62544..76d1234 100644 (file)
@@ -36,7 +36,7 @@
  * to the project. For more information see the website or contact
  * the copyright holders.
  *
- * $Id: link_set.h,v 1.30 2007/01/31 12:36:50 bernd67 Exp $
+ * $Id: link_set.h,v 1.31 2007/02/10 19:27:32 bernd67 Exp $
  */
 
 
@@ -124,7 +124,7 @@ struct link_entry *
 get_best_link_to_neighbor(union olsr_ip_addr *);
 
 struct link_entry *
-lookup_link_entry(union olsr_ip_addr *, struct interface *);
+lookup_link_entry(union olsr_ip_addr *, union olsr_ip_addr *remote_main, struct interface *);
 
 struct link_entry *
 update_link_entry(union olsr_ip_addr *, union olsr_ip_addr *, struct hello_message *, struct interface *);
index b99672d..d227652 100644 (file)
@@ -36,7 +36,7 @@
  * to the project. For more information see the website or contact
  * the copyright holders.
  *
- * $Id: local_hna_set.c,v 1.11 2006/01/07 08:16:20 kattemat Exp $
+ * $Id: local_hna_set.c,v 1.12 2007/02/10 19:27:32 bernd67 Exp $
  */
 
 #include "defs.h"
@@ -129,6 +129,45 @@ remove_local_hna6_entry(union olsr_ip_addr *net, olsr_u16_t prefix_len)
   return 0;
 }
 
+struct hna4_entry *
+find_local_hna4_entry(union olsr_ip_addr *net, olsr_u32_t mask)
+{
+  struct hna4_entry *h4 = olsr_cnf->hna4_entries;
+
+  while(h4)
+    {
+      if((net->v4 == h4->net.v4) && 
+        (mask == h4->netmask.v4))
+       {
+         return h4;
+       }
+      h4 = h4->next;
+    }
+
+  return NULL;
+}
+
+
+
+struct hna6_entry *
+find_local_hna6_entry(union olsr_ip_addr *net, olsr_u16_t prefix_len)
+{
+  struct hna6_entry *h6 = olsr_cnf->hna6_entries;
+
+  while(h6)
+    {
+      if((memcmp(net, &h6->net, olsr_cnf->ipsize) == 0) && 
+        (prefix_len == h6->prefix_len))
+       {
+         return h6;
+       }
+      h6 = h6->next;
+    }
+
+  return NULL;
+}
+
+
 
 
 int
index a7c7b72..c79e0c7 100644 (file)
@@ -36,7 +36,7 @@
  * to the project. For more information see the website or contact
  * the copyright holders.
  *
- * $Id: local_hna_set.h,v 1.9 2005/02/20 18:52:18 kattemat Exp $
+ * $Id: local_hna_set.h,v 1.10 2007/02/10 19:27:32 bernd67 Exp $
  */
 
 
@@ -58,6 +58,12 @@ remove_local_hna4_entry(union olsr_ip_addr *, union olsr_ip_addr *);
 int
 remove_local_hna6_entry(union olsr_ip_addr *, olsr_u16_t);
 
+struct hna4_entry *
+find_local_hna4_entry(union olsr_ip_addr *net, olsr_u32_t mask);
+
+struct hna6_entry *
+find_local_hna6_entry(union olsr_ip_addr *net, olsr_u16_t prefix_len);
+
 int
 check_inet_gw(void);
 
index a4dadd7..8620fee 100644 (file)
@@ -36,7 +36,7 @@
  * to the project. For more information see the website or contact
  * the copyright holders.
  *
- * $Id: lq_mpr.c,v 1.11 2006/01/07 08:16:20 kattemat Exp $
+ * $Id: lq_mpr.c,v 1.12 2007/02/10 19:27:32 bernd67 Exp $
  */
 
 #include "defs.h"
@@ -52,7 +52,7 @@ void olsr_calculate_lq_mpr(void)
   struct neighbor_list_entry *walker;
   int i, k;
   struct neighbor_entry *neigh;
-  double best;
+  double best, best_1hop;
   olsr_bool mpr_changes = OLSR_FALSE;
   struct link_entry *link;
 
@@ -91,6 +91,8 @@ void olsr_calculate_lq_mpr(void)
            neigh2 != &two_hop_neighbortable[i];
            neigh2 = neigh2->next)
         {
+          best_1hop = -1.0;
+
           // check whether this 2-hop neighbour is also a neighbour
 
           neigh = olsr_lookup_neighbor_table(&neigh2->neighbor_2_addr);
@@ -111,14 +113,14 @@ void olsr_calculate_lq_mpr(void)
              if(!link)
                continue;
 
-              best = link->loss_link_quality * link->neigh_link_quality;
+              best_1hop = link->loss_link_quality * link->neigh_link_quality;
 
               // see wether we find a better route via an MPR
 
               for (walker = neigh2->neighbor_2_nblist.next;
                    walker != &neigh2->neighbor_2_nblist;
                    walker = walker->next)
-                if (walker->path_link_quality > best)
+                if (walker->path_link_quality > best_1hop)
                   break;
 
               // we've reached the end of the list, so we haven't found
@@ -158,7 +160,10 @@ void olsr_calculate_lq_mpr(void)
                     best = walker->path_link_quality;
                   }
 
-              if (neigh != NULL)
+              // Found a 1-hop neighbor that we haven't previously selected.
+              // Use it as MPR only when the 2-hop path through it is better than
+              // any existing 1-hop path.
+              if ((neigh != NULL) && (best > best_1hop))
                 {
                   neigh->is_mpr = OLSR_TRUE;
                   neigh->skip = OLSR_TRUE;
index af60caa..5ba3049 100644 (file)
@@ -36,7 +36,7 @@
  * to the project. For more information see the website or contact
  * the copyright holders.
  *
- * $Id: mid_set.c,v 1.16 2006/12/14 11:29:20 bernd67 Exp $
+ * $Id: mid_set.c,v 1.17 2007/02/10 19:27:32 bernd67 Exp $
  */
 
 #include "defs.h"
@@ -46,6 +46,7 @@
 #include "scheduler.h"
 #include "neighbor_table.h"
 #include "link_set.h"
+#include "packet.h" /* struct mid_alias */
 
 
 struct mid_entry mid_set[HASHSIZE];
@@ -100,6 +101,7 @@ insert_mid_tuple(union olsr_ip_addr *m_addr, struct mid_address *alias, float vt
   struct mid_entry *tmp;
   struct mid_address *tmp_adr;
   olsr_u32_t hash, alias_hash;
+  union olsr_ip_addr *registered_m_addr;
 
   hash = olsr_hashing(m_addr);
   alias_hash = olsr_hashing(&alias->alias);
@@ -111,8 +113,16 @@ insert_mid_tuple(union olsr_ip_addr *m_addr, struct mid_address *alias, float vt
     {
       if(COMP_IP(&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 && COMP_IP(registered_m_addr, m_addr))
+    {
+      /* Alias is already registered with main address. Nothing to do here. */
+      return;
     }
-        
+
   /*If the address was registered*/ 
   if(tmp != &mid_set[hash])
     {
@@ -349,7 +359,7 @@ olsr_update_mid_table(union olsr_ip_addr *adr, float vtime)
       /*find match*/
       if(COMP_IP(&tmp_list->main_addr, adr))
        {
-         //printf("Updating timer for node %s\n",ip_to_string(&tmp_list->main_addr));
+         // printf("MID: Updating timer for node %s\n", olsr_ip_to_string(&tmp_list->main_addr));
          tmp_list->ass_timer = GET_TIMESTAMP(vtime*1000);
 
          return 1;
@@ -359,6 +369,91 @@ olsr_update_mid_table(union olsr_ip_addr *adr, float vtime)
 }
 
 
+/**
+ *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
+ */
+void
+olsr_prune_aliases(union olsr_ip_addr *m_addr, struct mid_alias *declared_aliases)
+{
+  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_hashing(m_addr);
+
+  /* Check for registered entry */
+  for(entry = mid_set[hash].next;
+      entry != &mid_set[hash];
+      entry = entry->next)
+    {
+      if(COMP_IP(&entry->main_addr, m_addr))
+       break;
+    }
+  if(entry == &mid_set[hash])
+    {
+      /* MID entry not found, nothing to prune here */
+      return;
+    }
+
+  registered_aliases = entry->aliases;
+  previous_alias = NULL;
+
+  while(registered_aliases != 0)
+    {
+      struct mid_address *current_alias = registered_aliases;
+      registered_aliases = registered_aliases->next_alias;
+
+      declared_aliases = save_declared_aliases;
+
+      /* Go through the list of declared aliases to find the matching current alias */
+      while(declared_aliases != 0 &&
+            ! COMP_IP(&current_alias->alias, &declared_aliases->alias_addr))
+        {
+          declared_aliases = declared_aliases->next;
+        }
+
+      if (declared_aliases == 0)
+        {
+          /* Current alias not found in list of declared aliases: free current alias */
+          OLSR_PRINTF(1, "MID remove: (%s, ", olsr_ip_to_string(&entry->main_addr))
+          OLSR_PRINTF(1, "%s)\n", olsr_ip_to_string(&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);
+          free(current_alias);
+
+          /*
+           *Recalculate topology
+           */
+          changes_neighborhood = OLSR_TRUE;
+          changes_topology = OLSR_TRUE;
+        }
+      else
+        {
+          previous_alias = current_alias;
+        }
+    }
+}
+
+
 
 /**
  *Find timed out entries and delete them
index e9eef17..377dd55 100644 (file)
@@ -36,7 +36,7 @@
  * to the project. For more information see the website or contact
  * the copyright holders.
  *
- * $Id: mid_set.h,v 1.13 2005/05/29 12:47:45 br1 Exp $
+ * $Id: mid_set.h,v 1.14 2007/02/10 19:27:32 bernd67 Exp $
  */
 
 
@@ -73,6 +73,7 @@ struct mid_entry
 extern struct mid_entry mid_set[HASHSIZE];
 extern struct mid_address reverse_mid_set[HASHSIZE];
 
+struct mid_alias;
 
 int
 olsr_init_mid_set(void);
@@ -95,6 +96,9 @@ olsr_print_mid_set(void);
 void
 olsr_time_out_mid_set(void *);
 
+void
+olsr_prune_aliases(union olsr_ip_addr *m_addr, struct mid_alias *declared_aliases);
+
 int
 olsr_update_mid_table(union olsr_ip_addr *, float);
 
index d3e9c3c..2f07089 100644 (file)
@@ -36,7 +36,7 @@
  * to the project. For more information see the website or contact
  * the copyright holders.
  *
- * $Id: process_package.c,v 1.37 2006/01/07 08:16:20 kattemat Exp $
+ * $Id: process_package.c,v 1.38 2007/02/10 19:27:32 bernd67 Exp $
  */
 
 
@@ -53,6 +53,7 @@
 #include "duplicate_set.h"
 #include "rebuild_packet.h"
 #include "scheduler.h"
+#include "local_hna_set.h"
 
 
 /**
@@ -66,7 +67,6 @@ olsr_init_package_process()
       olsr_parser_add_function(&olsr_process_received_hello, HELLO_MESSAGE, 1);
       olsr_parser_add_function(&olsr_process_received_tc, TC_MESSAGE, 1);
     }
-
   else
     {
       olsr_parser_add_function(&olsr_input_lq_hello, LQ_HELLO_MESSAGE, 1);
@@ -407,6 +407,8 @@ olsr_process_received_mid(union olsr_message *m, struct interface *in_if, union
       tmp_adr = tmp_adr->next;
     } 
   
+  olsr_prune_aliases(&message.mid_origaddr, message.mid_addr);
+
  forward:  
   olsr_forward_message(m, 
                       &message.mid_origaddr, 
@@ -471,8 +473,13 @@ olsr_process_received_hna(union olsr_message *m, struct interface *in_if, union
 
   while(hna_tmp)
     {
-      olsr_update_hna_entry(&message.originator, &hna_tmp->net, &hna_tmp->netmask, (float)message.vtime); 
-      
+      /* Don't add an HNA entry that we are advertising ourselves. */
+      if (!find_local_hna4_entry(&hna_tmp->net, hna_tmp->netmask.v4) &&
+          !find_local_hna6_entry(&hna_tmp->net, hna_tmp->netmask.v6))
+        {
+          olsr_update_hna_entry(&message.originator, &hna_tmp->net, &hna_tmp->netmask, (float)message.vtime);
+        } 
+
       hna_tmp = hna_tmp->next;
     }
 
@@ -495,7 +502,7 @@ olsr_process_received_hna(union olsr_message *m, struct interface *in_if, union
 
 /**
  *Processes an list of neighbors from an incoming HELLO message.
- *@param neighbor the neighbor who sendt the message.
+ *@param neighbor the neighbor who sent the message.
  *@param message the HELLO message
  *@return nada
  */
@@ -540,6 +547,31 @@ olsr_process_message_neighbors(struct neighbor_entry *neighbor,
               /* Updating the holding time for this neighbor */
               two_hop_neighbor_yet->neighbor_2_timer = GET_TIMESTAMP(message->vtime*1000);
               two_hop_neighbor = two_hop_neighbor_yet->neighbor_2;
+
+              // For link quality OLSR, reset the path link quality here.
+              // The path link quality will be calculated in the second pass, below.
+              // Keep the saved_path_link_quality for reference.
+
+              if (olsr_cnf->lq_level > 0)
+                {
+                  // loop through the one-hop neighbors that see this
+                  // 'two_hop_neighbor'
+
+                  struct neighbor_list_entry *walker;
+
+                  for (walker = two_hop_neighbor->neighbor_2_nblist.next;
+                       walker != &two_hop_neighbor->neighbor_2_nblist;
+                       walker = walker->next)
+                    {
+                      // have we found the one-hop neighbor that sent the
+                      // HELLO message that we're current processing?
+
+                      if (walker->neighbor == neighbor)
+                        {
+                          walker->path_link_quality = 0.0;
+                        }
+                    }
+                }
             }
           else
             {
@@ -587,19 +619,48 @@ olsr_process_message_neighbors(struct neighbor_entry *neighbor,
                                               (float)message->vtime); 
                 }
             }
+        }
+    }
+
+  // Separate, second and third pass for link quality OLSR
+
+  if (olsr_cnf->lq_level > 0)
+    {
+      struct link_entry *link =
+        get_best_link_to_neighbor(&neighbor->neighbor_main_addr);
+
+      if(!link)
+       return;
+
+      // Second pass for link quality OLSR: calculate the best 2-hop
+      // path costs to all the 2-hop neighbors indicated in the
+      // HELLO message. Since the same 2-hop neighbor may be listed
+      // more than once in the same HELLO message (each at a possibly
+      // different quality) we want to select only the best one, not just
+      // the last one listed in the HELLO message.
+
+      for(message_neighbors = message->neighbors;
+          message_neighbors != NULL;
+          message_neighbors = message_neighbors->next)
+        {
+          if(if_ifwithaddr(&message_neighbors->address) != NULL)
+            continue;
 
-          if (olsr_cnf->lq_level > 0)
+          if(((message_neighbors->status == SYM_NEIGH) ||
+              (message_neighbors->status == MPR_NEIGH)))
             {
-             struct neighbor_list_entry *walker;
-             struct link_entry *link;
+              struct neighbor_list_entry *walker;
+              struct neighbor_2_entry *two_hop_neighbor;
+              struct neighbor_2_list_entry *two_hop_neighbor_yet =
+                olsr_lookup_my_neighbors(neighbor, &message_neighbors->address);
 
-              link = get_best_link_to_neighbor(&neighbor->neighbor_main_addr);
+              if(!two_hop_neighbor_yet)
+                continue;
 
-             if(!link)
-               continue;
+              two_hop_neighbor = two_hop_neighbor_yet->neighbor_2;
 
               // loop through the one-hop neighbors that see this
-              // two hop neighbour
+              // 'two_hop_neighbor'
 
               for (walker = two_hop_neighbor->neighbor_2_nblist.next;
                    walker != &two_hop_neighbor->neighbor_2_nblist;
@@ -610,14 +671,7 @@ olsr_process_message_neighbors(struct neighbor_entry *neighbor,
 
                   if (walker->neighbor == neighbor)
                     {
-                      double saved_lq, rel_lq;
-
-                      // saved previous total link quality
-
-                      saved_lq = walker->saved_path_link_quality;
-
-                      if (saved_lq == 0.0)
-                        saved_lq = -1.0;
+                      double new_second_hop_link_quality, new_path_link_quality;
 
                       // path link quality = link quality between us
                       // and our one-hop neighbor x link quality between
@@ -634,18 +688,75 @@ olsr_process_message_neighbors(struct neighbor_entry *neighbor,
                       // the link quality between the 1-hop neighbour and the
                       // 2-hop neighbour
 
-                      walker->second_hop_link_quality =
+                      new_second_hop_link_quality = 
                         message_neighbors->link_quality *
                         message_neighbors->neigh_link_quality;
 
                       // the total quality for the route
                       // "us --- 1-hop --- 2-hop"
 
-                      walker->path_link_quality =
-                        walker->second_hop_link_quality *
+                      new_path_link_quality =
+                        new_second_hop_link_quality *
                         link->loss_link_quality * link->neigh_link_quality;
 
-                      // if the link quality has changed by more than 10
+                      // Only copy the link quality if it is better than what we have
+                      // for this 2-hop neighbor
+                      if (new_path_link_quality > walker->path_link_quality)
+                        {
+                          walker->second_hop_link_quality = new_second_hop_link_quality;
+                          walker->path_link_quality = new_path_link_quality;
+                        }
+                    }
+                }
+            }
+        }
+
+      // Third pass for link quality OLSR: check if the 2-hop path qualities have
+      // actually changed. If so, signal this through the 'changes_neighborhood'
+      // and 'changes_topology' booleans. Keep a 'saved_path_link_quality' for
+      // later reference.
+      for(message_neighbors = message->neighbors;
+          message_neighbors != NULL;
+          message_neighbors = message_neighbors->next)
+        {
+          if(if_ifwithaddr(&message_neighbors->address) != NULL)
+            continue;
+
+          if(((message_neighbors->status == SYM_NEIGH) ||
+              (message_neighbors->status == MPR_NEIGH)))
+            {
+              struct neighbor_list_entry *walker;
+              struct neighbor_2_entry *two_hop_neighbor;
+              struct neighbor_2_list_entry *two_hop_neighbor_yet =
+                olsr_lookup_my_neighbors(neighbor, &message_neighbors->address);
+
+              if(!two_hop_neighbor_yet)
+                continue;
+
+              two_hop_neighbor = two_hop_neighbor_yet->neighbor_2;
+
+              // loop through the one-hop neighbors that see this
+              // 'two_hop_neighbor'
+
+              for (walker = two_hop_neighbor->neighbor_2_nblist.next;
+                   walker != &two_hop_neighbor->neighbor_2_nblist;
+                   walker = walker->next)
+                {
+                  // have we found the one-hop neighbor that sent the
+                  // HELLO message that we're current processing?
+
+                  if (walker->neighbor == neighbor)
+                    {
+                      double saved_lq, rel_lq;
+
+                      // saved previous total link quality
+
+                      saved_lq = walker->saved_path_link_quality;
+
+                      if (saved_lq == 0.0)
+                        saved_lq = -1.0;
+
+                      // if the link cost has changed by more than 10
                       // percent, signal
 
                       rel_lq = walker->path_link_quality / saved_lq;
index b1b0d49..b2c4ae8 100644 (file)
@@ -36,7 +36,7 @@
  * to the project. For more information see the website or contact
  * the copyright holders.
  *
- * $Id: routing_table.c,v 1.24 2006/12/14 11:29:20 bernd67 Exp $
+ * $Id: routing_table.c,v 1.25 2007/02/10 19:27:32 bernd67 Exp $
  */
 
 
@@ -65,10 +65,10 @@ static struct destination_n *
 olsr_fill_routing_table_with_two_hop_neighbors(void);
 
 static struct rt_entry *
-olsr_check_for_higher_hopcount(struct rt_entry *, struct hna_net *, olsr_u16_t);
+olsr_check_for_higher_quality(struct rt_entry *, struct hna_net *, float);
 
 struct rt_entry *
-olsr_check_for_lower_hopcount(struct rt_entry *, struct hna_net *, olsr_u16_t);
+olsr_check_for_lower_quality(struct rt_entry *, struct hna_net *, float);
 
 static olsr_bool
 two_hop_neighbor_reachable(struct neighbor_2_list_entry *);
@@ -212,7 +212,12 @@ olsr_insert_routing_table(union olsr_ip_addr *dst,
   new_route_entry->rt_if = iface;
 
   new_route_entry->rt_metric = metric;
-  new_route_entry->rt_etx = etx;
+  if (etx< 0.0)
+    /* non-LQ case */
+    new_route_entry->rt_etx = (float)metric;
+  else
+    /* LQ case */
+    new_route_entry->rt_etx = etx;
   
   if(COMP_IP(dst, router))
     /* Not GW */
@@ -290,7 +295,7 @@ olsr_fill_routing_table_with_neighbors()
                                                    &link->neighbor_iface_addr,
                                                    iface,
                                                    1,
-                                                   0);
+                                                   -1.0);
                        }
                    }
              
@@ -406,7 +411,7 @@ olsr_fill_routing_table_with_two_hop_neighbors()
                                                      &link->neighbor_iface_addr,
                                                      iface,
                                                      2,
-                                                     0);
+                                                     -1.0);
                          
                          if(new_route_entry != NULL)
                            {
@@ -503,7 +508,7 @@ olsr_calculate_routing_table()
                                                      &list_destination_n->destination->rt_router, 
                                                      list_destination_n->destination->rt_if,
                                                      list_destination_n->destination->rt_metric+1,
-                                                     0);
+                                                     -1.0);
                          if(destination_n_1->destination != NULL)
                            {
                              destination_n_1->next=list_destination_n_1;
@@ -551,17 +556,17 @@ olsr_calculate_routing_table()
 
 
 /**
- *Check for a entry with a higher hopcount than
+ *Check for an entry with a higher quality (lower etx) than
  *a given value in a routing table
  *
  *@param routes the routingtable to look in
  *@param net the network entry to look for
- *@param metric the metric to check for
+ *@param etx the metric to check for
  *
- *@return the localted entry if found. NULL if not
+ *@return the located entry if found. NULL if not
  */
 static struct rt_entry *
-olsr_check_for_higher_hopcount(struct rt_entry *routes, struct hna_net *net, olsr_u16_t metric)
+olsr_check_for_higher_quality(struct rt_entry *routes, struct hna_net *net, float etx)
 {
   int index;
 
@@ -576,8 +581,8 @@ olsr_check_for_higher_hopcount(struct rt_entry *routes, struct hna_net *net, ols
          if(COMP_IP(&tmp_routes->rt_dst, &net->A_network_addr) &&
             (memcmp(&tmp_routes->rt_mask, &net->A_netmask, netmask_size) == 0))
            {
-             /* Found a entry */
-             if(tmp_routes->rt_metric > metric)
+             /* Found an entry */
+             if(tmp_routes->rt_etx < etx)
                return tmp_routes;
              else
                return NULL;
@@ -591,17 +596,17 @@ olsr_check_for_higher_hopcount(struct rt_entry *routes, struct hna_net *net, ols
 
 
 /**
- *Check for a entry with a lower or equal hopcount than
+ *Check for an entry with a lower or equal quality (higher or equal etx) than
  *a given value in a routing table
  *
  *@param routes the routingtable to look in
  *@param net the network entry to look for
- *@param metric the metric to check for
+ *@param etx the metric to check for
  *
- *@return the localted entry if found. NULL if not
+ *@return the located entry if found. NULL if not
  */
 struct rt_entry *
-olsr_check_for_lower_hopcount(struct rt_entry *routes, struct hna_net *net, olsr_u16_t metric)
+olsr_check_for_lower_quality(struct rt_entry *routes, struct hna_net *net, float etx)
 {
   int index;
 
@@ -616,8 +621,8 @@ olsr_check_for_lower_hopcount(struct rt_entry *routes, struct hna_net *net, olsr
          if(COMP_IP(&tmp_routes->rt_dst, &net->A_network_addr) &&
             (memcmp(&tmp_routes->rt_mask, &net->A_netmask, netmask_size) == 0))
            {
-             /* Found a entry */
-             if(tmp_routes->rt_metric <= metric)
+             /* Found an entry */
+             if(tmp_routes->rt_etx >= etx)
                return tmp_routes;
              else
                return NULL;
@@ -674,13 +679,13 @@ olsr_calculate_hna_routes()
                }
 
              /* If there exists a better or equal entry - skip */
-             if(olsr_check_for_lower_hopcount(hna_routes, tmp_net, tmp_rt->rt_metric) != NULL)
+             if(olsr_check_for_higher_quality(hna_routes, tmp_net, tmp_rt->rt_etx) != NULL)
                {
                  continue;
                }
 
-             /* If we find an entry with higher hopcount we just edit it */
-             if((new_rt = olsr_check_for_higher_hopcount(hna_routes, tmp_net, tmp_rt->rt_metric)) != NULL)
+             /* If we find an entry with lower quality we just edit it */
+             if((new_rt = olsr_check_for_lower_quality(hna_routes, tmp_net, tmp_rt->rt_etx)) != NULL)
                {
                  /* Fill struct */
                  /* Net */
@@ -689,6 +694,7 @@ olsr_calculate_hna_routes()
                  /* Gateway */
                  COPY_IP(&new_rt->rt_router, &tmp_rt->rt_router);
                  /* Metric */
+                 new_rt->rt_etx = tmp_rt->rt_etx;
                  new_rt->rt_metric = tmp_rt->rt_metric;
                  /* Flags */
                  new_rt->rt_flags = RTF_UP | RTF_GATEWAY;
@@ -709,6 +715,7 @@ olsr_calculate_hna_routes()
                  /* Gateway */
                  COPY_IP(&new_rt->rt_router, &tmp_rt->rt_router);
                  /* Metric */
+                 new_rt->rt_etx = tmp_rt->rt_etx;
                  new_rt->rt_metric = tmp_rt->rt_metric;
                  /* Flags */
                  new_rt->rt_flags = RTF_UP | RTF_GATEWAY;
index 4c45a20..bd630cc 100644 (file)
@@ -36,7 +36,7 @@
  * to the project. For more information see the website or contact
  * the copyright holders.
  *
- * $Id: ifnet.c,v 1.43 2007/02/04 23:36:35 bernd67 Exp $
+ * $Id: ifnet.c,v 1.44 2007/02/10 19:27:33 bernd67 Exp $
  */
 
 
@@ -327,9 +327,11 @@ chk_if_changed(struct olsr_if *iface)
          OLSR_PRINTF(1, "IPv4 address changed for %s\n", ifr.ifr_name)
          OLSR_PRINTF(1, "\tOld:%s\n", sockaddr_to_string(&ifp->int_addr))
          OLSR_PRINTF(1, "\tNew:%s\n", sockaddr_to_string(&ifr.ifr_addr))
-         
+
+         ifp->int_addr = ifr.ifr_addr;
+
          if(memcmp(&olsr_cnf->main_addr, 
-                   &((struct sockaddr_in *)&ifp->int_addr)->sin_addr.s_addr, 
+                   &ifp->ip_addr,
                    olsr_cnf->ipsize) == 0)
            {
              OLSR_PRINTF(1, "New main address: %s\n", sockaddr_to_string(&ifr.ifr_addr))
@@ -339,7 +341,6 @@ chk_if_changed(struct olsr_if *iface)
                     olsr_cnf->ipsize);
            }
 
-         ifp->int_addr = ifr.ifr_addr;
          memcpy(&ifp->ip_addr, 
                 &((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr, 
                 olsr_cnf->ipsize);