dhcpv6: Check status code for IA_ADDR operations
authorPaul Donald <[email protected]>
Sat, 18 Oct 2025 20:22:41 +0000 (22:22 +0200)
committerÁlvaro Fernández Rojas <[email protected]>
Sun, 19 Oct 2025 16:40:09 +0000 (18:40 +0200)
Check for error status code in the IA Address option in replies to RENEW
messages.

Signed-off-by: Paul Donald <[email protected]>
Link: https://github.com/openwrt/odhcp6c/pull/103
Signed-off-by: Álvaro Fernández Rojas <[email protected]>
src/dhcpv6.c

index e8dd2aebe3120b9d6723e1427330e50abcc9a986..fa0c2a1787ca91b7b0b686767b4b37b5a89176a8 100644 (file)
@@ -1425,8 +1425,8 @@ static unsigned int dhcpv6_parse_ia(void *opt, void *end, int *ret)
                                        The status of any operations involving this IA Prefix option is
                                        indicated in a Status Code option (see Section 21.13) in the
                                        IAprefix-options field. */
-                                       uint8_t *status_msg = (slen > 2) ? &sdata[2] : NULL;
-                                       uint16_t msg_len = (slen > 2) ? slen - 2 : 0;
+                                       uint8_t *status_msg = &sdata[2];
+                                       uint16_t msg_len = slen - 2;
                                        uint16_t code = ((int)sdata[0]) << 8 | ((int)sdata[1]);
 
                                        if (code == DHCPV6_Success)
@@ -1497,13 +1497,38 @@ static unsigned int dhcpv6_parse_ia(void *opt, void *end, int *ret)
 
                        entry.length = 128;
                        entry.target = addr->addr;
+                       uint16_t stype, slen;
+                       uint8_t *sdata;
+
+                       bool update_state = true;
+                       dhcpv6_for_each_option(odata + sizeof(*addr) - 4U,
+                                       odata + olen, stype, slen, sdata) {
+                               if (stype == DHCPV6_OPT_STATUS && slen > 2) {
+                                       /* RFC 8415 §21.6
+                                       The status of any operations involving this IA Address is indicated
+                                       in a Status Code option in the IAaddr-options field, as specified in
+                                       Section 21.13. */
+                                       uint8_t *status_msg = &sdata[2];
+                                       uint16_t msg_len = slen - 2;
+                                       uint16_t code = ((int)sdata[0]) << 8 | ((int)sdata[1]);
+
+                                       if (code == DHCPV6_Success)
+                                               continue;
 
-                       if (odhcp6c_update_entry(STATE_IA_NA, &entry, 0, 0))
-                               updated_IAs++;
+                                       dhcpv6_log_status_code(code, "IA_ADDR", status_msg, msg_len);
+                                       if (ret) *ret = 0; // renewal failed
+                                       update_state = false;
+                               }
+                       }
 
-                       syslog(LOG_INFO, "%s preferred %d valid %d",
-                                       inet_ntop(AF_INET6, &entry.target, buf, sizeof(buf)),
-                                       entry.preferred , entry.valid);
+                       if (update_state) {
+                               if (odhcp6c_update_entry(STATE_IA_NA, &entry, 0, 0))
+                                       updated_IAs++;
+
+                               syslog(LOG_INFO, "%s preferred %d valid %d",
+                                               inet_ntop(AF_INET6, &entry.target, buf, sizeof(buf)),
+                                               entry.preferred , entry.valid);
+                       }
                        break;
                }
                default: