-/* $OpenBSD: engine.c,v 1.19 2024/07/10 12:44:46 florian Exp $ */
+/* $OpenBSD: engine.c,v 1.20 2024/07/10 12:52:51 florian Exp $ */
/*
* Copyright (c) 2017, 2021, 2024 Florian Obser <florian@openbsd.org>
void remove_dhcp6leased_iface(uint32_t);
void parse_dhcp(struct dhcp6leased_iface *,
struct imsg_dhcp *);
-void parse_ia_pd_options(uint8_t *, size_t, struct prefix *);
+int parse_ia_pd_options(uint8_t *, size_t, struct prefix *);
void state_transition(struct dhcp6leased_iface *, enum
if_state);
void iface_timeout(int, short, void *);
log_debug("%s: IA_PD, IAID: %08x, T1: %u, T2: %u",
__func__, ntohl(iapd.iaid), ntohl(iapd.t1),
ntohl(iapd.t2));
- if (ntohl(iapd.iaid) < iface_conf->ia_count)
- parse_ia_pd_options(p +
+ if (ntohl(iapd.iaid) < iface_conf->ia_count) {
+ int status_code;
+ status_code = parse_ia_pd_options(p +
sizeof(struct dhcp_iapd), opt_hdr.len -
sizeof(struct dhcp_iapd),
&iface->new_pds[ntohl(iapd.iaid)]);
+
+ if (status_code != DHCP_STATUS_SUCCESS &&
+ iface->state == IF_RENEWING) {
+ state_transition(iface, IF_REBINDING);
+ goto out;
+ }
+ }
break;
case DHO_RAPID_COMMIT:
if (opt_hdr.len != 0) {
return;
}
-void
+int
parse_ia_pd_options(uint8_t *p, size_t len, struct prefix *prefix)
{
struct dhcp_option_hdr opt_hdr;
dhcp_option_type2str(opt_hdr.code), opt_hdr.len);
if (len < opt_hdr.len) {
log_warnx("%s: malformed packet, ignoring", __func__);
- return;
+ return DHCP_STATUS_UNSPECFAIL;
}
switch (opt_hdr.code) {
if (len < sizeof(struct dhcp_iaprefix)) {
log_warnx("%s: malformed packet, ignoring",
__func__);
- return;
+ return DHCP_STATUS_UNSPECFAIL;
}
memcpy(&iaprefix, p, sizeof(struct dhcp_iaprefix));
break;
case DHO_STATUS_CODE:
- /*
- * XXX handle STATUS_CODE if not success
- * STATUS_CODE can also appear in other parts of
- * the packet.
- */
+ /* XXX STATUS_CODE can also appear outside of options */
if (len < 2) {
log_warnx("%s: malformed packet, ignoring",
__func__);
- return;
+ return DHCP_STATUS_UNSPECFAIL;
}
memcpy(&status_code, p, sizeof(uint16_t));
status_code = ntohs(status_code);
p += opt_hdr.len;
len -= opt_hdr.len;
}
+ return status_code;
}
/* XXX check valid transitions */