<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
<META content="MSHTML 6.00.2800.1498" name=GENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY><FONT face=Arial size=2>
<DIV>Bill,</DIV>
<DIV><BR>I'm afraid that this fix is not enough.</DIV>
<DIV> </DIV>
<DIV>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.</DIV>
<DIV> </DIV>
<DIV>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><FONT face=Arial size=2></FONT> </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><FONT face=Arial size=2></FONT> </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><FONT face=Arial size=2></FONT> </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:</DIV></FONT>
<DIV><FONT face=Arial size=2>  neighbor->linkcount++;<BR></DIV></FONT>
<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><FONT face=Arial size=2></FONT> </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><FONT face=Arial size=2></FONT> </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><FONT face=Arial size=2></FONT> </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><FONT face=Arial size=2></FONT> </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><FONT face=Arial size=2></FONT> </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><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2>Regards,</FONT></DIV>
<DIV><FONT face=Arial size=2>Erik</FONT></DIV>
<DIV><FONT face=Arial size=2></FONT> </DIV>
<DIV><FONT face=Arial size=2></FONT><FONT face=Arial size=2></FONT><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></BODY></HTML>