Sly Midnight <[email protected]> writes:

>>Synopsis:      rtadvd does not detect dynamic changes to monitored
> interface
>>Category:      system
>>Environment:
>         System      : OpenBSD 5.8
>         Details     : OpenBSD 5.8 (GENERIC.MP) #1: Mon Nov  2 11:58:21
> EST 2015
>                         
> [email protected]:/usr/src/sys/arch/amd64/compile/GENERIC.MP
>
>         Architecture: OpenBSD.amd64
>         Machine     : amd64
>>Description:
>         rtadvd is designed to detect and automatically determine which
> prefixes are local to a specific link when it is fired up without
>         a configuration file and just started with an interface
> identifier as a command line argument.
>
>         It is able to detect automatically when an IPv6 address is added
> to the monitored interface and discern the prefix on it's own
>         and start sending out Advertisements with the prefix on that
> same interface announcing itself as the default gateway for that
>         prefix.
>
>         Starting with about OpenBSD 5.5 or 5.6 I noticed the daemon
> would pickup the available prefixes on the monitored interface
>         upon startup, but not detect when an address was either removed
> or added.  Addresses removed, continued to have the
>         prefix advertised, and addresses added would not be advertised
> until the daemon was restarted.
>
>         The delay in reporting this was because the daemon does pickup
> the information initially upon startup and thus does mostly work.
>         And since IPv6 addressing changes on my network are not frequent
> I didn't have a way to easily confirm if my initial suspicions
>         were reproducible without affecting my network with testing. 
> But now some other change in the boot process or the other
>         software I use to provision my IPv6 connectivity (or my ISP now
> responds slower), it won't even detect the first address added
>         to the monitored interface after boot up, because the rtadvd
> daemon has already started way before my other dhcpv6 client
>         has had the opportunity to ask for and receive a delegated
> prefix.  So after my firewall box reboots, I have to login and manually
>         restart rtadvd after I confirm I have a valid IPv6 address on
> the internal interface I run rtadvd on before hosts on my internal
>         network can gain IPv6 connectivity.
>>How-To-Repeat:
>         Install a recent version of OpenBSD 5.8 and enable IPv6 on at
> least 1 interface.
>         Load rtadvd with that interface identifier as the sole command
> line argument.
>         Now add an IPv6 address to that interface and then proceed to
> send a SIGUSR1 signal to it's PID, and check /var/log/daemon and
>         notice it does not have knowledge of the newly added IPv6
> address and it's prefix.
>
>         Restart daemon and send another -SIGUSR1 and now notice it is
> aware of the prefix.
>         Delete that address and send yet another -SIGUSR1 and notice it
> still thinks it should be advertising for that prefix that was removed.
>>Fix:
>         I do not know what method rtadvd employs to detect changes in
> the monitored interface's addressing.
>         A member of the mailing list who also has some experience with
> IPv6 suggested it monitors the routing table for changes to routes
>         on that interface.  But I am not sure.
>
>         Only available work around is to restart daemon every time there
> is an IPv6 addressing change on that interface.

Thanks for your detailed report; the following diff should help.

(I did not try to track down the commits that did break this feature.)

Index: if.c
===================================================================
RCS file: /cvs/src/usr.sbin/rtadvd/if.c,v
retrieving revision 1.30
diff -u -p -r1.30 if.c
--- if.c        3 Nov 2015 15:59:31 -0000       1.30
+++ if.c        26 Nov 2015 23:22:04 -0000
@@ -256,7 +256,7 @@ get_next_msg(char *buf, char *lim, int i
                                continue;
 
                        if ((gw = rti_info[RTAX_GATEWAY]) == NULL ||
-                           gw->sa_family != AF_LINK)
+                           gw->sa_family != AF_INET6)
                                continue;
                        if (ifindex && SDL(gw)->sdl_index != ifindex)
                                continue;
@@ -319,12 +319,8 @@ int
 get_rtm_ifindex(char *buf)
 {
        struct rt_msghdr *rtm = (struct rt_msghdr *)buf;
-       struct sockaddr *sa, *rti_info[RTAX_MAX];
-
-       sa = (struct sockaddr *)(buf + rtm->rtm_hdrlen);
-       get_rtaddrs(rtm->rtm_addrs, sa, rti_info);
 
-       return(((struct sockaddr_dl *)rti_info[RTAX_GATEWAY])->sdl_index);
+       return rtm->rtm_index;
 }
 
 int


-- 
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE

Reply via email to