@@ -3302,7 +3302,7 @@ dhcp6_recvif(struct interface *ifp, const char *sfrom,
33023302 size_t i ;
33033303 const char * op ;
33043304 struct dhcp6_state * state ;
3305- uint8_t * o ;
3305+ uint8_t * o , preference = 0 ;
33063306 uint16_t ol ;
33073307 const struct dhcp_opt * opt ;
33083308 const struct if_options * ifo ;
@@ -3464,16 +3464,24 @@ dhcp6_recvif(struct interface *ifp, const char *sfrom,
34643464 valid_op = false;
34653465 break ;
34663466 }
3467+
3468+ o = dhcp6_findmoption (r , len , D6_OPTION_PREFERENCE , & ol );
3469+ if (o && ol == sizeof (uint8_t ))
3470+ preference = * o ;
3471+
3472+ /* If we already have an advertisement check that this one
3473+ * has a higher preference value. */
34673474 if (state -> recv_len && state -> recv -> type == DHCP6_ADVERTISE ) {
3468- /* We already have an advertismemnt.
3469- * RFC 8415 says we have to wait for the IRT to elapse.
3470- * To keep the same behaviour we won't do anything with
3471- * this. In the future we should make a lists of
3472- * ADVERTS and pick the "best" one. */
3473- logdebugx ( "%s: discarding ADVERTISEMENT from %s" ,
3474- ifp -> name , sfrom ) ;
3475- return ;
3475+ o = dhcp6_findmoption ( state -> recv , state -> recv_len ,
3476+ D6_OPTION_PREFERENCE , & ol );
3477+ if ( o && ol == sizeof ( uint8_t ) && * o >= preference ) {
3478+ logdebugx (
3479+ "%s: discarding ADVERTISEMENT from %s (%u)" ,
3480+ ifp -> name , sfrom , preference );
3481+ return ;
3482+ }
34763483 }
3484+
34773485 /* RFC7083 */
34783486 o = dhcp6_findmoption (r , len , D6_OPTION_SOL_MAX_RT , & ol );
34793487 if (o && ol == sizeof (uint32_t )) {
@@ -3592,16 +3600,19 @@ dhcp6_recvif(struct interface *ifp, const char *sfrom,
35923600 if (ia == NULL )
35933601 ia = TAILQ_FIRST (& state -> addrs );
35943602 if (ia == NULL )
3595- loginfox ("%s: ADV (no address) from %s" ,
3596- ifp -> name , sfrom );
3603+ loginfox ("%s: ADV (no address) from %s (%u) " ,
3604+ ifp -> name , sfrom , preference );
35973605 else
3598- loginfox ("%s: ADV %s from %s" ,
3599- ifp -> name , ia -> saddr , sfrom );
3600- if (state -> RTC > 1 ) {
3601- // IRT already elapsed, initiate request
3606+ loginfox ("%s: ADV %s from %s (%u)" ,
3607+ ifp -> name , ia -> saddr , sfrom , preference );
3608+
3609+ /*
3610+ * RFC 8415 18.2.1 says we must collect until ADVERTISEMENTs
3611+ * until we get one with a preference of 255 or
3612+ * the initial RT has elpased.
3613+ */
3614+ if (preference == 255 || state -> RTC > 1 )
36023615 dhcp6_startrequest (ifp );
3603- }
3604- // We will request when the IRT elapses
36053616 return ;
36063617 }
36073618
0 commit comments