@@ -38,6 +38,7 @@ _public_ int sd_radv_new(sd_radv **ret) {
3838 * ra = (sd_radv ) {
3939 .n_ref = 1 ,
4040 .fd = -1 ,
41+ .lifetime_usec = RADV_DEFAULT_ROUTER_LIFETIME_USEC ,
4142 };
4243
4344 * ret = TAKE_PTR (ra );
@@ -81,7 +82,7 @@ _public_ sd_event *sd_radv_get_event(sd_radv *ra) {
8182_public_ int sd_radv_is_running (sd_radv * ra ) {
8283 assert_return (ra , false);
8384
84- return ra -> state != SD_RADV_STATE_IDLE ;
85+ return ra -> state != RADV_STATE_IDLE ;
8586}
8687
8788static void radv_reset (sd_radv * ra ) {
@@ -128,7 +129,13 @@ static sd_radv *radv_free(sd_radv *ra) {
128129
129130DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC (sd_radv , sd_radv , radv_free );
130131
131- static int radv_send (sd_radv * ra , const struct in6_addr * dst , uint32_t router_lifetime ) {
132+ static bool router_lifetime_is_valid (usec_t lifetime_usec ) {
133+ return lifetime_usec == 0 ||
134+ (lifetime_usec >= RADV_MIN_ROUTER_LIFETIME_USEC &&
135+ lifetime_usec <= RADV_MAX_ROUTER_LIFETIME_USEC );
136+ }
137+
138+ static int radv_send (sd_radv * ra , const struct in6_addr * dst , usec_t lifetime_usec ) {
132139 sd_radv_route_prefix * rt ;
133140 sd_radv_prefix * p ;
134141 struct sockaddr_in6 dst_addr = {
@@ -162,6 +169,7 @@ static int radv_send(sd_radv *ra, const struct in6_addr *dst, uint32_t router_li
162169 int r ;
163170
164171 assert (ra );
172+ assert (router_lifetime_is_valid (lifetime_usec ));
165173
166174 r = sd_event_now (ra -> event , clock_boottime_or_monotonic (), & time_now );
167175 if (r < 0 )
@@ -173,7 +181,8 @@ static int radv_send(sd_radv *ra, const struct in6_addr *dst, uint32_t router_li
173181 adv .nd_ra_type = ND_ROUTER_ADVERT ;
174182 adv .nd_ra_curhoplimit = ra -> hop_limit ;
175183 adv .nd_ra_flags_reserved = ra -> flags ;
176- adv .nd_ra_router_lifetime = htobe16 (router_lifetime );
184+ assert_cc (RADV_MAX_ROUTER_LIFETIME_USEC <= UINT16_MAX * USEC_PER_SEC );
185+ adv .nd_ra_router_lifetime = htobe16 (DIV_ROUND_UP (lifetime_usec , USEC_PER_SEC ));
177186 iov [msg .msg_iovlen ++ ] = IOVEC_MAKE (& adv , sizeof (adv ));
178187
179188 /* MAC address is optional, either because the link does not use L2
@@ -274,7 +283,7 @@ static int radv_recv(sd_event_source *s, int fd, uint32_t revents, void *userdat
274283
275284 (void ) in_addr_to_string (AF_INET6 , (const union in_addr_union * ) & src , & addr );
276285
277- r = radv_send (ra , & src , ra -> lifetime );
286+ r = radv_send (ra , & src , ra -> lifetime_usec );
278287 if (r < 0 )
279288 log_radv_errno (ra , r , "Unable to send solicited Router Advertisement to %s, ignoring: %m" , strnull (addr ));
280289 else
@@ -283,54 +292,54 @@ static int radv_recv(sd_event_source *s, int fd, uint32_t revents, void *userdat
283292 return 0 ;
284293}
285294
286- static usec_t radv_compute_timeout (usec_t min , usec_t max ) {
287- assert_return (min <= max , SD_RADV_DEFAULT_MIN_TIMEOUT_USEC );
288-
289- /* RFC 4861: min must be no less than 3s, max must be no less than 4s */
290- min = MAX (min , 3 * USEC_PER_SEC );
291- max = MAX (max , 4 * USEC_PER_SEC );
292-
293- return min + (random_u32 () % (max - min ));
294- }
295-
296295static int radv_timeout (sd_event_source * s , uint64_t usec , void * userdata ) {
297- int r ;
296+ usec_t min_timeout , max_timeout , time_now , timeout ;
298297 sd_radv * ra = userdata ;
299- usec_t min_timeout = SD_RADV_DEFAULT_MIN_TIMEOUT_USEC ;
300- usec_t max_timeout = SD_RADV_DEFAULT_MAX_TIMEOUT_USEC ;
301- usec_t time_now , timeout ;
298+ int r ;
302299
303300 assert (s );
304301 assert (ra );
305302 assert (ra -> event );
303+ assert (router_lifetime_is_valid (ra -> lifetime_usec ));
306304
307305 r = sd_event_now (ra -> event , clock_boottime_or_monotonic (), & time_now );
308306 if (r < 0 )
309307 goto fail ;
310308
311- r = radv_send (ra , NULL , ra -> lifetime );
309+ r = radv_send (ra , NULL , ra -> lifetime_usec );
312310 if (r < 0 )
313311 log_radv_errno (ra , r , "Unable to send Router Advertisement: %m" );
314312
315313 /* RFC 4861, Section 6.2.4, sending initial Router Advertisements */
316- if (ra -> ra_sent < SD_RADV_MAX_INITIAL_RTR_ADVERTISEMENTS ) {
317- max_timeout = SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC ;
318- min_timeout = SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC / 3 ;
319- }
314+ if (ra -> ra_sent < RADV_MAX_INITIAL_RTR_ADVERTISEMENTS )
315+ max_timeout = RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC ;
316+ else
317+ max_timeout = RADV_DEFAULT_MAX_TIMEOUT_USEC ;
320318
321319 /* RFC 4861, Section 6.2.1, lifetime must be at least MaxRtrAdvInterval,
322- so lower the interval here */
323- if (ra -> lifetime > 0 && (ra -> lifetime * USEC_PER_SEC ) < max_timeout ) {
324- max_timeout = ra -> lifetime * USEC_PER_SEC ;
320+ * so lower the interval here */
321+ if (ra -> lifetime_usec > 0 )
322+ max_timeout = MIN (max_timeout , ra -> lifetime_usec );
323+
324+ if (max_timeout >= 9 * USEC_PER_SEC )
325325 min_timeout = max_timeout / 3 ;
326- }
326+ else
327+ min_timeout = max_timeout * 3 / 4 ;
327328
328- timeout = radv_compute_timeout (min_timeout , max_timeout );
329+ /* RFC 4861, Section 6.2.1.
330+ * MaxRtrAdvInterval MUST be no less than 4 seconds and no greater than 1800 seconds.
331+ * MinRtrAdvInterval MUST be no less than 3 seconds and no greater than .75 * MaxRtrAdvInterval. */
332+ assert (max_timeout >= RADV_MIN_MAX_TIMEOUT_USEC );
333+ assert (max_timeout <= RADV_MAX_MAX_TIMEOUT_USEC );
334+ assert (min_timeout >= RADV_MIN_MIN_TIMEOUT_USEC );
335+ assert (min_timeout <= max_timeout * 3 / 4 );
336+
337+ timeout = min_timeout + random_u64_range (max_timeout - min_timeout );
329338 log_radv (ra , "Next Router Advertisement in %s" , FORMAT_TIMESPAN (timeout , USEC_PER_SEC ));
330339
331340 r = event_reset_time (ra -> event , & ra -> timeout_event_source ,
332341 clock_boottime_or_monotonic (),
333- time_now + timeout , MSEC_PER_SEC ,
342+ usec_add ( time_now , timeout ) , MSEC_PER_SEC ,
334343 radv_timeout , ra ,
335344 ra -> event_priority , "radv-timeout" , true);
336345 if (r < 0 )
@@ -352,7 +361,7 @@ _public_ int sd_radv_stop(sd_radv *ra) {
352361 if (!ra )
353362 return 0 ;
354363
355- if (ra -> state == SD_RADV_STATE_IDLE )
364+ if (ra -> state == RADV_STATE_IDLE )
356365 return 0 ;
357366
358367 log_radv (ra , "Stopping IPv6 Router Advertisement daemon" );
@@ -365,7 +374,7 @@ _public_ int sd_radv_stop(sd_radv *ra) {
365374
366375 radv_reset (ra );
367376 ra -> fd = safe_close (ra -> fd );
368- ra -> state = SD_RADV_STATE_IDLE ;
377+ ra -> state = RADV_STATE_IDLE ;
369378
370379 return 0 ;
371380}
@@ -377,7 +386,7 @@ _public_ int sd_radv_start(sd_radv *ra) {
377386 assert_return (ra -> event , - EINVAL );
378387 assert_return (ra -> ifindex > 0 , - EINVAL );
379388
380- if (ra -> state != SD_RADV_STATE_IDLE )
389+ if (ra -> state != RADV_STATE_IDLE )
381390 return 0 ;
382391
383392 r = event_reset_time (ra -> event , & ra -> timeout_event_source ,
@@ -404,7 +413,7 @@ _public_ int sd_radv_start(sd_radv *ra) {
404413
405414 (void ) sd_event_source_set_description (ra -> recv_event_source , "radv-receive-message" );
406415
407- ra -> state = SD_RADV_STATE_ADVERTISING ;
416+ ra -> state = RADV_STATE_ADVERTISING ;
408417
409418 log_radv (ra , "Started IPv6 Router Advertisement daemon" );
410419
@@ -420,7 +429,7 @@ _public_ int sd_radv_set_ifindex(sd_radv *ra, int ifindex) {
420429 assert_return (ra , - EINVAL );
421430 assert_return (ifindex > 0 , - EINVAL );
422431
423- if (ra -> state != SD_RADV_STATE_IDLE )
432+ if (ra -> state != RADV_STATE_IDLE )
424433 return - EBUSY ;
425434
426435 ra -> ifindex = ifindex ;
@@ -456,7 +465,7 @@ int sd_radv_get_ifname(sd_radv *ra, const char **ret) {
456465_public_ int sd_radv_set_mac (sd_radv * ra , const struct ether_addr * mac_addr ) {
457466 assert_return (ra , - EINVAL );
458467
459- if (ra -> state != SD_RADV_STATE_IDLE )
468+ if (ra -> state != RADV_STATE_IDLE )
460469 return - EBUSY ;
461470
462471 if (mac_addr )
@@ -479,35 +488,38 @@ _public_ int sd_radv_set_mtu(sd_radv *ra, uint32_t mtu) {
479488_public_ int sd_radv_set_hop_limit (sd_radv * ra , uint8_t hop_limit ) {
480489 assert_return (ra , - EINVAL );
481490
482- if (ra -> state != SD_RADV_STATE_IDLE )
491+ if (ra -> state != RADV_STATE_IDLE )
483492 return - EBUSY ;
484493
485494 ra -> hop_limit = hop_limit ;
486495
487496 return 0 ;
488497}
489498
490- _public_ int sd_radv_set_router_lifetime (sd_radv * ra , uint16_t router_lifetime ) {
499+ _public_ int sd_radv_set_router_lifetime (sd_radv * ra , uint64_t lifetime_usec ) {
491500 assert_return (ra , - EINVAL );
492501
493- if (ra -> state != SD_RADV_STATE_IDLE )
502+ if (ra -> state != RADV_STATE_IDLE )
494503 return - EBUSY ;
495504
505+ if (!router_lifetime_is_valid (lifetime_usec ))
506+ return - EINVAL ;
507+
496508 /* RFC 4191, Section 2.2, "...If the Router Lifetime is zero, the preference value MUST be set
497509 * to (00) by the sender..." */
498- if (router_lifetime == 0 &&
510+ if (lifetime_usec == 0 &&
499511 (ra -> flags & (0x3 << 3 )) != (SD_NDISC_PREFERENCE_MEDIUM << 3 ))
500- return - ETIME ;
512+ return - EINVAL ;
501513
502- ra -> lifetime = router_lifetime ;
514+ ra -> lifetime_usec = lifetime_usec ;
503515
504516 return 0 ;
505517}
506518
507519_public_ int sd_radv_set_managed_information (sd_radv * ra , int managed ) {
508520 assert_return (ra , - EINVAL );
509521
510- if (ra -> state != SD_RADV_STATE_IDLE )
522+ if (ra -> state != RADV_STATE_IDLE )
511523 return - EBUSY ;
512524
513525 SET_FLAG (ra -> flags , ND_RA_FLAG_MANAGED , managed );
@@ -518,7 +530,7 @@ _public_ int sd_radv_set_managed_information(sd_radv *ra, int managed) {
518530_public_ int sd_radv_set_other_information (sd_radv * ra , int other ) {
519531 assert_return (ra , - EINVAL );
520532
521- if (ra -> state != SD_RADV_STATE_IDLE )
533+ if (ra -> state != RADV_STATE_IDLE )
522534 return - EBUSY ;
523535
524536 SET_FLAG (ra -> flags , ND_RA_FLAG_OTHER , other );
@@ -535,7 +547,7 @@ _public_ int sd_radv_set_preference(sd_radv *ra, unsigned preference) {
535547
536548 /* RFC 4191, Section 2.2, "...If the Router Lifetime is zero, the preference value MUST be set
537549 * to (00) by the sender..." */
538- if (ra -> lifetime == 0 && preference != SD_NDISC_PREFERENCE_MEDIUM )
550+ if (ra -> lifetime_usec == 0 && preference != SD_NDISC_PREFERENCE_MEDIUM )
539551 return - EINVAL ;
540552
541553 ra -> flags = (ra -> flags & ~(0x3 << 3 )) | (preference << 3 );
@@ -595,7 +607,7 @@ _public_ int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p, int dynamic) {
595607
596608 /* If RAs have already been sent, send an RA immediately to announce the newly-added prefix */
597609 if (ra -> ra_sent > 0 ) {
598- r = radv_send (ra , NULL , ra -> lifetime );
610+ r = radv_send (ra , NULL , ra -> lifetime_usec );
599611 if (r < 0 )
600612 log_radv_errno (ra , r , "Unable to send Router Advertisement for added prefix: %m" );
601613 else
@@ -698,7 +710,7 @@ _public_ int sd_radv_add_route_prefix(sd_radv *ra, sd_radv_route_prefix *p, int
698710
699711 /* If RAs have already been sent, send an RA immediately to announce the newly-added route prefix */
700712 if (ra -> ra_sent > 0 ) {
701- r = radv_send (ra , NULL , ra -> lifetime );
713+ r = radv_send (ra , NULL , ra -> lifetime_usec );
702714 if (r < 0 )
703715 log_radv_errno (ra , r , "Unable to send Router Advertisement for added route prefix: %m" );
704716 else
@@ -743,7 +755,7 @@ _public_ int sd_radv_set_rdnss(sd_radv *ra, uint32_t lifetime,
743755 if (!opt_rdnss )
744756 return - ENOMEM ;
745757
746- opt_rdnss -> type = SD_RADV_OPT_RDNSS ;
758+ opt_rdnss -> type = RADV_OPT_RDNSS ;
747759 opt_rdnss -> length = len / 8 ;
748760 opt_rdnss -> lifetime = htobe32 (lifetime );
749761
@@ -779,7 +791,7 @@ _public_ int sd_radv_set_dnssl(sd_radv *ra, uint32_t lifetime,
779791 if (!opt_dnssl )
780792 return - ENOMEM ;
781793
782- opt_dnssl -> type = SD_RADV_OPT_DNSSL ;
794+ opt_dnssl -> type = RADV_OPT_DNSSL ;
783795 opt_dnssl -> length = len / 8 ;
784796 opt_dnssl -> lifetime = htobe32 (lifetime );
785797
@@ -911,7 +923,7 @@ _public_ int sd_radv_route_prefix_new(sd_radv_route_prefix **ret) {
911923 * p = (sd_radv_route_prefix ) {
912924 .n_ref = 1 ,
913925
914- .opt .type = SD_RADV_OPT_ROUTE_INFORMATION ,
926+ .opt .type = RADV_OPT_ROUTE_INFORMATION ,
915927 .opt .length = DIV_ROUND_UP (sizeof (p -> opt ), 8 ),
916928 .opt .prefixlen = 64 ,
917929
0 commit comments