Subject: Re: IPv6 autoconfiguration problem
To: None <itojun@iijlab.net>
From: Jan Mikael Melen <Jan.Melen@iki.fi>
List: tech-net
Date: 04/02/2003 22:43:26
--Boundary-00=_e1zi+sdC2YyADBX
Content-Type: text/plain;
  charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

On Wednesday 02 April 2003 15:12, itojun@iijlab.net wrote:
> >> 	ok.  but the values you have chosen are way too short.  i don'
> >> 	recommend such a setting.
> >
> >Yes, I know that those are very short and not to be used in the normal
> >case but these values were chosen to demonstrate the problem because the
> >problem also exists if I have a longer life time for the addresses. All
> >the active connections will get no route to host while the address is
> >missing from the interface.
> >
> >It is also quite irritating if one makes a program that listen's to
> >routing socket when you'll get all the time RTM_DELADDR and RTM_NEWADDR
> >from the routing socket because the address is lost and right after
> >reconfigured again. This causes waste of clock cycles which are used to
> >update all sort of neat routing stuff and few seconds later again updating
> >the same data back in.
>

It seems that the problem is in prelist_update in file nd6_rtr.c. The handling 
of vltime is a bit buggy at least to my understanding of what the RFC 2462 is 
specifying in together with the discussion in the ipngwg. 

The major fault that I noticed was that the code compares the vltime received 
in the earlier RA to the vltime received in new RA, when the vltime is 
smaller than 2 shours and makes the update decission based on that. Now if 
the new vltime is same as the previous or smaller no update to the valid life 
time will be done and that causes that the address is lost always when the 
valid life time expires. Here is a patch file that will patch the code in the 
way I believe it should work. This changes the behaviour so that the vltime 
is compared in to the remaining lifetime of the address instead of the the 
whole life time. At least after making this correction I got work in all my 
test cases.

  Jan

--Boundary-00=_e1zi+sdC2YyADBX
Content-Type: text/x-diff;
  charset="iso-8859-1";
  name="nd6_rtr.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="nd6_rtr.patch"

*** nd6_rtr.c	Wed Apr  2 20:23:55 2003
--- nd6_rtr.c	Wed Apr  2 22:08:29 2003
***************
*** 926,934 ****
--- 926,944 ----
  			 * 5.5.3 (e).
  			 */
  			int update = 0;
+ 			long time_second = time.tv_sec;
+ 			int storedlifetime;
  
  			lt6 = &ia6->ia6_lifetime;
  
+ 			/* One might be wondering if this interpretation *
+ 			 * is really conform to the RFC, because the     *
+ 			 * text can read that "Lifetimes" are never      *
+ 			 * decreased. See the discussion in the IETF     *
+ 			 * ipngwg ML in August 2001, with the Subject    *
+ 			 * "StoredLifetime in RFC 2462".                 */
+ 			storedlifetime = lt6->ia6t_expire - time_second;
+ 
  #if 0	/* RFC 2462 5.5.3 (e) */
  			lt6->ia6t_pltime = new->ndpr_pltime;
  			if (TWOHOUR < new->ndpr_vltime
***************
*** 950,960 ****
  			lt6->ia6t_pltime = new->ndpr_pltime;
  #else	/* update from Jim Bound, (ipng 6712) */
  			if (TWOHOUR < new->ndpr_vltime
! 			 || lt6->ia6t_vltime < new->ndpr_vltime) {
  				lt6->ia6t_vltime = new->ndpr_vltime;
  				update++;
! 			} else if (auth) {
! 				lt6->ia6t_vltime = new->ndpr_vltime;
  				update++;
  			}
  
--- 960,981 ----
  			lt6->ia6t_pltime = new->ndpr_pltime;
  #else	/* update from Jim Bound, (ipng 6712) */
  			if (TWOHOUR < new->ndpr_vltime
! 			 || storedlifetime < new->ndpr_vltime) {
! 			        /* RFC 2462 5.5.3 (e.1) */
  				lt6->ia6t_vltime = new->ndpr_vltime;
  				update++;
! 			} else if (storedlifetime <= TWOHOUR) { 
! 			        /* RFC 2462 5.5.3 (e.2) */
! 			        /* new->ndpr_vltime <= storedlifetime *
! 				 * this is redundant with the first   *
! 				 * condition                          */
! 			        if (auth) {
! 			                lt6->ia6t_vltime = new->ndpr_vltime;
! 			                update++;
! 				}
! 			} else {
! 			        /* RFC 2462 5.5.3 (e.3) */
! 			        lt6->ia6t_vltime = TWOHOUR;
  				update++;
  			}
  

--Boundary-00=_e1zi+sdC2YyADBX--