From: Florian Obser Subject: Re: rad(8): track vltime / pltime for "auto prefix"es To: tech@openbsd.org Date: Fri, 31 May 2024 18:27:22 +0200 Thank you for the detailed write-up. I now understand what is going on. We should always announce the minimum of static configured and interface discovered lifetimes. For that rad(8) needs to track more information, I already have a plan on how to implement this, but currently not enough time. Since I think the two outstanding diffs are strictly better than what we have I chose to commit those and work on a diff on top. For the time being I went with your suggestion of documenting this behaviour in the man page with a slightly tweaked text. On 2024-05-25 11:40 -07, Ryan Vogt wrote: > On Fri, May 24, 2024 at 11:16:36AM +0200, Florian Obser wrote: >> On 2024-05-23 13:20 -07, Ryan Vogt wrote: >> > On Mon, May 20, 2024 at 12:16:33PM +0000, Florian Obser wrote: >> >> Prefixes delegated via DHCPv6 have a lifetime, honour it. >> >> >> >> The "auto prefix" feature derives the prefix to announce from a >> >> configured IPv6 address. If that address has a vltime / pltime use >> >> that value in router advertisements instead of statically configured >> >> values. >> >> >> >> We also need to count down the vltime / pltime as time progresses. >> >> >> >> This is on top of "rad(8): reduce calls to getifaddrs(3)" and also needs >> >> "send RTM_CHGADDRATTR for vltime / pltime changes" to work correctly. >> > >> > Hi, I have a question about the intended behaviour of this patch in a >> > few cases, which I've outlined below. > > [snip] > >> > To set up our situation, I have rad(8) running on igc1. On igc1, I >> > have a static prefix, and a prefix delegated from DHCPv6 (dhcpcd >> > running on igc0): >> > >> > $ ifconfig igc1 >> > [...] >> > inet6 fe80::bbbb:bbbb:bbbb:bbbb%igc1 prefixlen 64 scopeid 0x2 >> > inet6 fdaa:aaaa:aaaa:1::1 prefixlen 64 >> > inet6 2001:db80:eeee:eeee::1 prefixlen 64 pltime 103481 \ >> > vltime 103481 >> > >> > The fdaa:... prefix is static, and the 2001:... prefix is delegated by >> > my ISP. > > [snip] > >> > 4) The fourth case is an extension of the third case, with a more- >> > explicit rad.conf. Here's an rad.conf that someone with an >> > essentially-static delegation from their ISP could use (I'm not so >> > lucky): >> > >> > interface igc1 { >> > prefix fdaa:aaaa:aaaa:1:: { >> > preferred lifetime 2000 >> > valid lifetime 3000 >> > } >> > prefix 2001:db80:eeee:eeee:: { >> > preferred lifetime 4000 >> > valid lifetime 5000 >> > } >> > } >> > >> > The behaviour with the new patch is that clients receive the following >> > prefix info options from rad: >> > >> > - fdaa:aaaa:aaaa:1::/64 with valid time 3000, pref. time 2000 >> > - 2001:db80:eeee:eeee::/64 with valid time 103481, >> > pref. time 103481 >> > >> >> I don't think this actually happens, if you are not configuring an auto >> prefix rad(8) does not look at prefixes, does it? >> >> if (ra_iface_conf->autoprefix) >> get_interface_prefixes(ra_iface, >> ra_iface_conf->autoprefix, ifap); >> >> I think you should get this: >> - fdaa:aaaa:aaaa:1::/64 with valid time 3000, pref. time 2000 >> - 2001:db80:eeee:eeee::/64 with valid time 5000, pref. time 4000 > > Sorry that I took a while to get back to you -- I wanted to double- > check my testing and investigate a little more. > > I'm not sure how much it matters if you're planning on changing the > the rad(8) patch anyway, but I've confirmed that the patch behaves as > I reported in my previous message. > > To shed a little light on the situation, here are two slightly > different rad.conf(5) files. The first produces the behaviour I > reported. The second produces the behaviour you expected. > > 4.a) For this rad.conf: > > interface igc1 { > prefix fdaa:aaaa:aaaa:1:: { > preferred lifetime 2000 > valid lifetime 3000 > } > prefix 2001:db80:eeee:eeee:: { > preferred lifetime 4000 > valid lifetime 5000 > } > } > > we get RA messages from rad(8) containing these two prefix info options > (the ones I originally reported): > > - fdaa:aaaa:aaaa:1::/64 with valid time 3000, pref. time 2000 > - 2001:db80:eeee:eeee::/64 with valid time 103481, > pref. time 103481 > > 4.b) For this rad.conf: > > interface igc1 { > no auto prefix # Difference from 4.a is this line > prefix fdaa:aaaa:aaaa:1:: { > preferred lifetime 2000 > valid lifetime 3000 > } > prefix 2001:db80:eeee:eeee:: { > preferred lifetime 4000 > valid lifetime 5000 > } > } > > we see the behaviour you expected: > > - fdaa:aaaa:aaaa:1::/64 with valid time 3000, pref. time 2000 > - 2001:db80:eeee:eeee::/64 with valid time 5000, > pref. time 4000 > > Some investigation -- > > In your previous message, you highlighted a few lines of code in > merge_ra_interfaces(): > > if (ra_iface_conf->autoprefix) > get_interface_prefixes(ra_iface, > ra_iface_conf->autoprefix, ifap); > > Just before the highlighted code, merge_ra_interfaces() deals with > adding the static prefixes (there's an "add static prefixes for %s" > debug message). For both versions of rad.conf (4.a and 4.b): both > fdaa:aaaa:aaaa:1::/64 and 2001:db80:eeee:eeee::/64 get added as static > prefixes here -- each with a call to add_new_prefix_to_ra_iface(). > > After the static prefixes are dealt with in merge_ra_interfaces(), we > reach the highlighted lines of code. Here's where the behaviour > becomes different without the "no auto prefix" line in rad.conf. > Without the "no auto prefix" line, we call > add_new_prefix_to_ra_iface() again for both prefixes. > > The first prefix, fdaa:aaaa:aaaa:1::/64, gets ignored during its > second call to add_new_prefix_to_ra_iface(), producing an > "ignoring duplicate %s/%d prefix" debug message. > > The second prefix, 2001:db80:eeee:eeee::/64, however, takes a > different path through add_new_prefix_to_ra_iface() during its second > call: > > - The call to find_ra_prefix_conf(), right at the top of > add_new_prefix_to_ra_iface(), returns non-NULL > - decaying_vltime != ND6_INFINITE_LIFETIME and > decaying_pltime != ND6_INFINITE_LIFETIME, so we go through > that branch of the following ifs and else-ifs. > > I believe what's happening is that add_new_prefix_to_ra_iface() isn't > recognizing 2001:db80:eeee:eeee::/64 as a duplicate prefix because of > the check for decaying preferred/valid lifetimes. > -- In my defence, I have been left unsupervised.