<html><div style='background-color:'><P>Actually, I think the problem is surprisingly easy to solve.</P>
<P>It's like working for the secret service. If your ID changes, no-one is updated about this. Your old ID just kind of disappears over time (times out), and your new ID gets known gradually.</P>
<P>I propose to leave the link entries with the old ID to time out, taking their neighbor entries with them. The new link entries with the new ID automatically take care of setting up a new neighbor entry.</P>
<P>What do you think of the following changes in the add_new_entry() function (src/link_set.c, lines 402 a.o.):</P>
<P>  while(tmp_link_set)<BR>    {<BR>      if(COMP_IP(remote, &tmp_link_set->neighbor_iface_addr) &&<BR>         COMP_IP(local, &tmp_link_set->local_iface_addr) &&<BR>         COMP_IP(remote_main, &tmp_link_set->neighbor->neighbor_main_addr))<BR>        return tmp_link_set;<BR>      tmp_link_set = tmp_link_set->next;<BR>    }</P>
<P>And also, a couple of lines down (lines 502 a.o.):</P>
<P>  /* Copy the main address - make sure this is done every time<BR>   * as neighbors might change main address */<BR>  /* Erik Tromp - OOPS! Don't do this! Neighbor entries are hashed through their<BR>   * neighbor_main_addr field, and when that field is changed, their position<BR>   * in the hash table is no longer correct, so that the function<BR>   * olsr_lookup_neighbor_table() can no longer find the neighbor<BR>   * entry. */<BR>  /*COPY_IP(&neighbor->neighbor_main_addr, remote_main);*/<BR><BR></P>
<BLOCKQUOTE style="PADDING-LEFT: 5px; MARGIN-LEFT: 5px; BORDER-LEFT: #a0c6e5 2px solid; MARGIN-RIGHT: 0px"><FONT style="FONT-SIZE: 11px; FONT-FAMILY: tahoma,sans-serif">
<HR color=#a0c6e5 SIZE=1>
From: <I>Acinonyx <acinonyxs@yahoo.gr></I><BR>Reply-To: <I>OLSR development <olsr-dev@olsr.org></I><BR>To: <I>OLSR development <olsr-dev@olsr.org></I><BR>Subject: <I>Re: [olsr-dev] bug in mdi code</I><BR>Date: <I>Sun, 12 Nov 2006 15:29:22 +0200</I><BR><BR>
<META content="Microsoft SafeHTML" name=Generator>Yes you are right Erik,<BR><BR>the previous fix doesn't update the neighbor set. So we end up with a "ghost" neighbor entry. :(<BR><BR>Ok, so could we delete (or decrease linkcount if  > 1) and recreate a neighbor entry with the new main address?<BR><BR>Do you think it will work?<BR>
<BLOCKQUOTE cite=midBAY112-DAV12C955839706F30521458FF1F50@phx.gbl>
<STYLE>
</STYLE>
<FONT face=Arial size=2></FONT>
<DIV><FONT face=Arial size=2>Bill,</FONT></DIV>
<DIV><FONT face=Arial size=2><BR>I'm afraid that this fix is not enough.</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>Is updating 'neighbor->neighbor_main_addr' safe? It seems that the neighbor set is hashed through 'neighbor_main_addr'. If 'neighbor_main_addr' is changed, the neighbor entry must get another position in the hash table.</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>Also, a problem arises when a node is neighbor to another node via two separate network interfaces (i.e. via 2 links).</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>In that case there will be one neighbor entry with linkcount 2 (1 for each link).<BR><BR>When the main IP address of the neighbor node changes, the HELLO messages from that interface are sent with the new IP address as source ('remote'), and with the new IP address as originator address ('remote_main').</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>Because 'remote' does not match any existing link, the while(tmp_link_set) loop will not find any existing link, so a new link entry is made.</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>Also, since ''remote_main' does not match any existing neighbor entry, a new neighbor entry is made:</FONT></DIV>
<DIV><FONT face=Arial size=2>  if(NULL == (neighbor = olsr_lookup_neighbor_table(remote_main)))<BR>    {<BR></FONT></DIV>
<DIV><FONT face=Arial size=2>The linkcount will be 1:</FONT></DIV>
<DIV><FONT face=Arial size=2>  neighbor->linkcount++;<BR></FONT></DIV>
<DIV><FONT face=Arial size=2>Next, a HELLO message comes in via the second network interface, with the new IP address as originator address ('remote_main'). </FONT><FONT face=Arial size=2>The fix you propose will correctly update the (old) neighbor entry (the one with with 'linkcount' 2):</FONT></DIV>
<DIV><FONT face=Arial size=2>    COPY_IP(&tmp_link_set->neighbor->neighbor_main_addr, remote_main);</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>After a while, the link with the old remote IP address will time out. However, the old, but updated neigbor entry will not be removed, since its 'linkcount' > 1. Its 'linkcount' value will be decreased from 2 to 1.</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>The result: we have two neighbor entries, each with 'linkcount' 1, and each with the same 'neighbor_main_addr'.</FONT></DIV>
<DIV><FONT face=Arial size=2><BR>Besides this, there is a small bug in the function chk_if_changed (src/unix/ifnet.c)<BR><BR>       memcpy(&main_addr, <BR>       &((struct sockaddr_in *)&ifp->int_addr)->sin_addr.s_addr, <BR>       ipsize);<BR>     }</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>   ifp->int_addr = ifr.ifr_addr;<BR></FONT></DIV>
<DIV><FONT face=Arial size=2>The memcpy is copying the existing IP address in main_addr, not the new IP address. Or: ifr.ifr_addr is copied into ifp->int_addr too late.</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>Last: the olsr_process_received_mid function only adds MID aliases, not remove. I have written a function that removes the MID aliases which are registered but no longer declared in the received MID message. Here is the code:</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>/**<BR> *Remove aliases from 'entry' which are not listed in 'declared_aliases'.<BR> *<BR> <A href="mailto:*@param">*@param</A> entry the MID entry<BR> <A href="mailto:*@param">*@param</A> declared_aliases the list of declared aliases for the MID entry<BR> *<BR> <A href="mailto:*@return">*@return</A> nada<BR> */<BR>void<BR>olsr_prune_aliases(union olsr_ip_addr *m_addr, struct mid_alias *declared_aliases)<BR>{<BR>  struct mid_entry *entry;<BR>  olsr_u32_t hash;<BR>  struct mid_address *registered_aliases;<BR>  struct mid_address *previous_alias;<BR>  struct mid_alias *save_declared_aliases = declared_aliases;</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>  hash = olsr_hashing(m_addr);</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>  /* Check for registered entry */<BR>  for(entry = mid_set[hash].next;<BR>      entry != &mid_set[hash];<BR>      entry = entry->next)<BR>    {<BR>      if(COMP_IP(&entry->main_addr, m_addr))</FONT></DIV>
<DIV><FONT face=Arial size=2>        break;<BR>    }<BR>  if(entry == &mid_set[hash])<BR>    {<BR>      /* MID entry not found, nothing to prune here */<BR>      return;<BR>    }</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>  registered_aliases = entry->aliases;<BR>  previous_alias = NULL;</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>  while(registered_aliases != 0)<BR>    {<BR>      struct mid_address *current_alias = registered_aliases;<BR>      registered_aliases = registered_aliases->next_alias;</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>      declared_aliases = save_declared_aliases;</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>      /* Go through the list of declared aliases to find the matching current alias */<BR>      while(declared_aliases != 0 &&<BR>            ! COMP_IP(&current_alias->alias, &declared_aliases->alias_addr))<BR>        {<BR>          declared_aliases = declared_aliases->next;<BR>        }</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>      if (declared_aliases == 0)<BR>        {<BR>          /* Current alias not found in list of declared aliases: free current alias */<BR>          OLSR_PRINTF(1, "MID remove: (%s, ", olsr_ip_to_string(&entry->main_addr))<BR>          OLSR_PRINTF(1, "%s)\n", olsr_ip_to_string(&current_alias->alias))</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>          /* Update linked list as seen by 'entry' */<BR>          if (previous_alias != NULL)<BR>            {<BR>              previous_alias->next_alias = current_alias->next_alias;<BR>            }<BR>          else<BR>            {<BR>              entry->aliases = current_alias->next_alias;<BR>            }</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>          /* Remove from hash table */<BR>          DEQUEUE_ELEM(current_alias);<BR> <BR>          free(current_alias);</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>          /*<BR>           *Recalculate topology<BR>           */<BR>          changes_neighborhood = OLSR_TRUE;<BR>          changes_topology = OLSR_TRUE;<BR>        }<BR>      else<BR>        {<BR>          previous_alias = current_alias;<BR>        }<BR>    }<BR>}</FONT></DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2><BR></FONT> </DIV>
<DIV> </DIV>
<DIV><FONT face=Arial size=2>Regards,</FONT></DIV>
<DIV><FONT face=Arial size=2>Erik</FONT></DIV>
<DIV> </DIV>
<DIV><BR><BR><FONT face=Arial size=2>----- Original Message ----- <BR>From: "Acinonyx" <</FONT><A href="mailto:acinonyxs@yahoo.gr"><FONT face=Arial size=2>acinonyxs@yahoo.gr</FONT></A><FONT face=Arial size=2>><BR>To: "OLSR development" <</FONT><A href="mailto:olsr-dev@olsr.org"><FONT face=Arial size=2>olsr-dev@olsr.org</FONT></A><FONT face=Arial size=2>><BR>Sent: Friday, November 10, 2006 11:16 PM<BR>Subject: Re: [olsr-dev] bug in mdi code<BR><BR><BR>> Ok, here is a patch i made. It adds neighbor main address update on<BR>> every link entry update.<BR>><BR>> I tested it and it works.<BR>><BR>> Bill<BR>><BR>> -------------------<BR>> diff -Naur olsrd-0.4.10/src/link_set.c olsrd-0.4.10-patched/src/link_set.c<BR>> --- olsrd-0.4.10/src/link_set.c 2005-11-17 06:25:44.000000000 +0200<BR>> +++ olsrd-0.4.10-patched/src/link_set.c 2006-11-10 
23:45:24.000000000 +0200<BR>> @@ -403,7 +466,10 @@<BR>>      {<BR>>        if(COMP_IP(remote, &tmp_link_set->neighbor_iface_addr) &&<BR>>          COMP_IP(local, &tmp_link_set->local_iface_addr))<BR>> -       return tmp_link_set;<BR>> +        {<BR>> +          COPY_IP(&tmp_link_set->neighbor->neighbor_main_addr,<BR>> remote_main);<BR>> +         return tmp_link_set;<BR>> +        }<BR>>        tmp_link_set = tmp_link_set->next;<BR>>      
}<BR>><BR>><BR>><BR>><BR>> _______________________________________________<BR>> olsr-dev mailing list<BR>> </FONT><A href="mailto:olsr-dev@olsr.org"><FONT face=Arial size=2>olsr-dev@olsr.org</FONT></A><BR><FONT face=Arial size=2>> </FONT><A href="https://www.olsr.org/mailman/listinfo/olsr-dev"><FONT face=Arial size=2>https://www.olsr.org/mailman/listinfo/olsr-dev</FONT></A><BR><FONT face=Arial size=2>><BR></FONT></DIV><PRE><HR width="90%" SIZE=4>
_______________________________________________
olsr-dev mailing list
<A class=moz-txt-link-abbreviated href="mailto:olsr-dev@olsr.org">olsr-dev@olsr.org</A>
<A class=moz-txt-link-freetext href="https://www.olsr.org/mailman/listinfo/olsr-dev">https://www.olsr.org/mailman/listinfo/olsr-dev</A>
  </PRE></BLOCKQUOTE><BR><BR>
<P>>_______________________________________________<BR>>olsr-dev mailing list<BR>>olsr-dev@olsr.org<BR>>https://www.olsr.org/mailman/listinfo/olsr-dev<BR>
<P></FONT></P></BLOCKQUOTE></div></html>