@@ -985,13 +985,15 @@ static void dhcpv6_send(enum dhcpv6_msg req_msg_type, uint8_t trid[3], uint32_t
985985
986986 switch (req_msg_type ) {
987987 case DHCPV6_MSG_REQUEST :
988- /* Some broken ISPs won't behave properly if IA_NA is
989- * sent on Requests when they have provided an empty
990- * IA_NA on Advertise.
991- * Therefore we don't comply with RFC7550 and omit
992- * IA_NA as a workaround.
993- */
994- iov [IOV_HDR_IA_NA ].iov_len = 0 ;
988+ if (!config_dhcp -> strict_rfc7550 ) {
989+ /* Some broken ISPs won't behave properly if IA_NA is
990+ * sent on Requests when they have provided an empty
991+ * IA_NA on Advertise.
992+ * Therefore we don't comply with RFC7550 and omit
993+ * IA_NA as a workaround.
994+ */
995+ iov [IOV_HDR_IA_NA ].iov_len = 0 ;
996+ }
995997 break ;
996998 case DHCPV6_MSG_SOLICIT :
997999 break ;
@@ -2134,6 +2136,7 @@ int dhcpv6_promote_server_cand(void)
21342136 struct dhcpv6_server_cand * cand = odhcp6c_get_state (STATE_SERVER_CAND , & cand_len );
21352137 uint16_t hdr [2 ];
21362138 int ret = DHCPV6_STATELESS ;
2139+ bool override_ia = false;
21372140
21382141 // Clear lingering candidate state info
21392142 odhcp6c_clear_state (STATE_SERVER_ID );
@@ -2143,25 +2146,47 @@ int dhcpv6_promote_server_cand(void)
21432146 if (!cand_len )
21442147 return -1 ;
21452148
2146- if (!cand -> ia_pd_len && cand -> has_noaddravail ) {
2147- bool override = false;
2149+ if (config_dhcp -> strict_rfc7550 ) {
2150+ if (!cand -> ia_pd_len && cand -> has_noaddravail ) {
2151+ /* Some ISPs provide neither IA_NA nor IA_PD, so we
2152+ * should fallback to SLAAC.
2153+ */
2154+
2155+ if (na_mode == IA_MODE_TRY ) {
2156+ na_mode = IA_MODE_NONE ;
2157+ override_ia = true;
2158+ }
21482159
2149- if (na_mode == IA_MODE_TRY ) {
2160+ if (pd_mode == IA_MODE_TRY ) {
2161+ pd_mode = IA_MODE_NONE ;
2162+ override_ia = true;
2163+ }
2164+ }
2165+ } else {
2166+ if (cand -> has_noaddravail && na_mode == IA_MODE_TRY ) {
2167+ /* Some broken ISPs require a new Solicit message
2168+ * without IA_NA if they haven't provided an address
2169+ * on the Advertise message.
2170+ */
21502171 na_mode = IA_MODE_NONE ;
2151- override = true;
2172+ override_ia = true;
21522173 }
21532174
2154- if (pd_mode == IA_MODE_TRY ) {
2175+ if (!cand -> ia_pd_len && pd_mode == IA_MODE_TRY ) {
2176+ /* Some broken ISPs require a new Solicit message
2177+ * without IA_PD if they haven't provided a prefix
2178+ * on the Advertise message.
2179+ */
21552180 pd_mode = IA_MODE_NONE ;
2156- override = true;
2181+ override_ia = true;
21572182 }
2183+ }
21582184
2159- if (override ) {
2160- dhcpv6_retx [DHCPV6_MSG_SOLICIT ].max_timeo = cand -> sol_max_rt ;
2161- dhcpv6_retx [DHCPV6_MSG_INFO_REQ ].max_timeo = cand -> inf_max_rt ;
2185+ if (override_ia ) {
2186+ dhcpv6_retx [DHCPV6_MSG_SOLICIT ].max_timeo = cand -> sol_max_rt ;
2187+ dhcpv6_retx [DHCPV6_MSG_INFO_REQ ].max_timeo = cand -> inf_max_rt ;
21622188
2163- return -1 ;
2164- }
2189+ return -1 ;
21652190 }
21662191
21672192 hdr [0 ] = htons (DHCPV6_OPT_SERVERID );
0 commit comments