From: florian Date: Sun, 2 Jun 2024 12:41:46 +0000 (+0000) Subject: Implement renew & rebind. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=1c8c2e64104ee57ce8c4748cb222f339bf4d3a70;p=openbsd Implement renew & rebind. Missed in previous. --- diff --git a/sbin/dhcp6leased/dhcp6leased.h b/sbin/dhcp6leased/dhcp6leased.h index e58cbe2376e..dc3c825f1e4 100644 --- a/sbin/dhcp6leased/dhcp6leased.h +++ b/sbin/dhcp6leased/dhcp6leased.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dhcp6leased.h,v 1.1 2024/06/02 12:28:05 florian Exp $ */ +/* $OpenBSD: dhcp6leased.h,v 1.2 2024/06/02 12:41:46 florian Exp $ */ /* * Copyright (c) 2017, 2021 Florian Obser @@ -156,8 +156,10 @@ enum imsg_type { IMSG_RECONF_IFACE_IA_END, IMSG_RECONF_IFACE_END, IMSG_RECONF_END, - IMSG_SEND_DISCOVER, + IMSG_SEND_SOLICIT, IMSG_SEND_REQUEST, + IMSG_SEND_RENEW, + IMSG_SEND_REBIND, IMSG_SOCKET_IPC, IMSG_OPEN_UDPSOCK, IMSG_UDPSOCK, diff --git a/sbin/dhcp6leased/engine.c b/sbin/dhcp6leased/engine.c index 56fd120cfbb..96514feba0c 100644 --- a/sbin/dhcp6leased/engine.c +++ b/sbin/dhcp6leased/engine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: engine.c,v 1.1 2024/06/02 12:28:05 florian Exp $ */ +/* $OpenBSD: engine.c,v 1.2 2024/06/02 12:41:46 florian Exp $ */ /* * Copyright (c) 2017, 2021, 2024 Florian Obser @@ -686,7 +686,7 @@ parse_dhcp(struct dhcp6leased_iface *iface, struct imsg_dhcp *dhcp) struct dhcp_iapd iapd; struct prefix *pds = NULL; size_t rem; - uint32_t t1, t2; + uint32_t t1, t2, lease_time; int serverid_len; uint8_t serverid[SERVERID_SIZE]; uint8_t *p; @@ -712,7 +712,7 @@ parse_dhcp(struct dhcp6leased_iface *iface, struct imsg_dhcp *dhcp) if (pds == NULL) fatal("%s: calloc", __func__); - serverid_len = t1 = t2 = 0; + serverid_len = t1 = t2 = lease_time = 0; p = dhcp->packet; rem = dhcp->len; @@ -828,6 +828,10 @@ parse_dhcp(struct dhcp6leased_iface *iface, struct imsg_dhcp *dhcp) ia_conf->prefix_len); goto out; } + + if (lease_time < pd->vltime) + lease_time = pd->vltime; + log_debug("%s: pltime: %u, vltime: %u, prefix: %s/%u", __func__, pd->pltime, pd->vltime, inet_ntop(AF_INET6, &pd->prefix, ntopbuf, INET6_ADDRSTRLEN), pd->prefix_len); @@ -864,8 +868,13 @@ parse_dhcp(struct dhcp6leased_iface *iface, struct imsg_dhcp *dhcp) state_transition(iface, IF_REQUESTING); break; case DHCPREPLY: - /* XXX rapid commit, rebinding, renewing */ - if (iface->state != IF_REQUESTING) { + /* XXX rapid commit */ + switch(iface->state) { + case IF_REQUESTING: + case IF_RENEWING: + case IF_REBINDING: + break; + default: log_debug("%s: ignoring unexpected %s", __func__, dhcp_message_type2str(hdr.msg_type)); goto out; @@ -878,6 +887,8 @@ parse_dhcp(struct dhcp6leased_iface *iface, struct imsg_dhcp *dhcp) /* XXX handle t1 = 0 or t2 = 0 */ iface->t1 = t1; iface->t2 = t2; + iface->lease_time = lease_time; + clock_gettime(CLOCK_MONOTONIC, &iface->request_time); state_transition(iface, IF_BOUND); break; case DHCPRECONFIGURE: @@ -1054,8 +1065,15 @@ XXXX break; case IF_BOUND: iface->timo.tv_sec = iface->t1; - if (old_state == IF_REQUESTING || old_state == IF_REBOOTING) { + switch(old_state) { + case IF_REQUESTING: + case IF_RENEWING: + case IF_REBINDING: + case IF_REBOOTING: configure_interfaces(iface); + break; + default: + break; } break; case IF_RENEWING: @@ -1128,7 +1146,7 @@ iface_timeout(int fd, short events, void *arg) timespecsub(&now, &iface->request_time, &res); log_debug("%s: res.tv_sec: %lld, t2: %u", __func__, res.tv_sec, iface->t2); - if (res.tv_sec > iface->t2) + if (res.tv_sec >= iface->t2) state_transition(iface, IF_REBINDING); else state_transition(iface, IF_RENEWING); @@ -1146,6 +1164,7 @@ iface_timeout(int fd, short events, void *arg) } } +/* XXX can this be merged into dhcp_request()? */ void request_dhcp_discover(struct dhcp6leased_iface *iface) { @@ -1161,7 +1180,7 @@ request_dhcp_discover(struct dhcp6leased_iface *iface) imsg.elapsed_time = 0xffff; else imsg.elapsed_time = res.tv_sec * 100; - engine_imsg_compose_frontend(IMSG_SEND_DISCOVER, 0, &imsg, sizeof(imsg)); + engine_imsg_compose_frontend(IMSG_SEND_SOLICIT, 0, &imsg, sizeof(imsg)); } void @@ -1195,19 +1214,29 @@ request_dhcp_request(struct dhcp6leased_iface *iface) fatalx("XXX state IF_REBOOTING in %s not IMPL", __func__); break; case IF_REQUESTING: + case IF_RENEWING: + case IF_REBINDING: imsg.serverid_len = iface->serverid_len; memcpy(imsg.serverid, iface->serverid, SERVERID_SIZE); memcpy(imsg.pds, iface->pds, sizeof(iface->pds)); break; + } + switch (iface->state) { + case IF_REQUESTING: + engine_imsg_compose_frontend(IMSG_SEND_REQUEST, 0, &imsg, + sizeof(imsg)); + break; case IF_RENEWING: - fatalx("XXX state IF_RENEWING in %s not IMPL", __func__); + engine_imsg_compose_frontend(IMSG_SEND_RENEW, 0, &imsg, + sizeof(imsg)); break; case IF_REBINDING: - fatalx("XXX state IF_REBINDING in %s not IMPL", __func__); + engine_imsg_compose_frontend(IMSG_SEND_REBIND, 0, &imsg, + sizeof(imsg)); break; + default: + fatalx("%s: wrong state", __func__); } - - engine_imsg_compose_frontend(IMSG_SEND_REQUEST, 0, &imsg, sizeof(imsg)); } void diff --git a/sbin/dhcp6leased/frontend.c b/sbin/dhcp6leased/frontend.c index 5e2e54c46fb..3fd768fca64 100644 --- a/sbin/dhcp6leased/frontend.c +++ b/sbin/dhcp6leased/frontend.c @@ -1,4 +1,4 @@ -/* $OpenBSD: frontend.c,v 1.1 2024/06/02 12:28:05 florian Exp $ */ +/* $OpenBSD: frontend.c,v 1.2 2024/06/02 12:41:46 florian Exp $ */ /* * Copyright (c) 2017, 2021, 2024 Florian Obser @@ -459,7 +459,10 @@ frontend_dispatch_engine(int fd, short event, void *bula) case IMSG_CTL_SHOW_INTERFACE_INFO: control_imsg_relay(&imsg); break; - case IMSG_SEND_DISCOVER: { + case IMSG_SEND_SOLICIT: + case IMSG_SEND_REQUEST: + case IMSG_SEND_RENEW: + case IMSG_SEND_REBIND: { struct imsg_req_dhcp imsg_req_dhcp; if (IMSG_DATA_SIZE(imsg) != sizeof(imsg_req_dhcp)) fatalx("%s: IMSG_SEND_DISCOVER wrong " @@ -474,25 +477,20 @@ frontend_dispatch_engine(int fd, short event, void *bula) break; iface_data_from_imsg(iface, &imsg_req_dhcp); - send_packet(DHCPSOLICIT, iface); - break; - } - case IMSG_SEND_REQUEST: { - struct imsg_req_dhcp imsg_req_dhcp; - if (IMSG_DATA_SIZE(imsg) != sizeof(imsg_req_dhcp)) - fatalx("%s: IMSG_SEND_REQUEST wrong " - "length: %lu", __func__, - IMSG_DATA_SIZE(imsg)); - memcpy(&imsg_req_dhcp, imsg.data, - sizeof(imsg_req_dhcp)); - - iface = get_iface_by_id(imsg_req_dhcp.if_index); - - if (iface == NULL) + switch (imsg.hdr.type) { + case IMSG_SEND_SOLICIT: + send_packet(DHCPSOLICIT, iface); break; - - iface_data_from_imsg(iface, &imsg_req_dhcp); - send_packet(DHCPREQUEST, iface); + case IMSG_SEND_REQUEST: + send_packet(DHCPREQUEST, iface); + break; + case IMSG_SEND_RENEW: + send_packet(DHCPRENEW, iface); + break; + case IMSG_SEND_REBIND: + send_packet(DHCPREBIND, iface); + break; + } break; } default: @@ -811,6 +809,8 @@ build_packet(uint8_t message_type, struct iface *iface, char *if_name) switch(message_type) { case DHCPSOLICIT: case DHCPREQUEST: + case DHCPRENEW: + case DHCPREBIND: break; default: fatalx("%s: %s not implemented", __func__, @@ -834,13 +834,22 @@ build_packet(uint8_t message_type, struct iface *iface, char *if_name) memcpy(p, &duid, sizeof(struct dhcp_duid)); p += sizeof(struct dhcp_duid); - if (message_type == DHCPREQUEST) { + switch(message_type) { + case DHCPSOLICIT: + case DHCPREBIND: + break; + case DHCPREQUEST: + case DHCPRENEW: opt_hdr.code = htons(DHO_SERVERID); opt_hdr.len = htons(iface->serverid_len); memcpy(p, &opt_hdr, sizeof(struct dhcp_option_hdr)); p += sizeof(struct dhcp_option_hdr); memcpy(p, iface->serverid, iface->serverid_len); p += iface->serverid_len; + break; + default: + fatalx("%s: %s not implemented", __func__, + dhcp_message_type2str(message_type)); } SIMPLEQ_FOREACH(ia_conf, &iface_conf->iface_ia_list, entry) { struct prefix *pd; @@ -869,6 +878,8 @@ build_packet(uint8_t message_type, struct iface *iface, char *if_name) iaprefix.prefix_len = ia_conf->prefix_len; break; case DHCPREQUEST: + case DHCPRENEW: + case DHCPREBIND: pd = &iface->pds[ia_conf->id - 1]; iaprefix.prefix_len = pd->prefix_len; memcpy(&iaprefix.prefix, &pd->prefix,