summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorFlorian Obser <florian@cvs.openbsd.org>2024-06-02 12:41:47 +0000
committerFlorian Obser <florian@cvs.openbsd.org>2024-06-02 12:41:47 +0000
commitaaada35af5a74bbdea395e0844b26f1f81c6cb93 (patch)
treea216d9b7f1791f56d10d27bad8d656c556acecc8 /sbin
parent9e73f2233650133b84a59527fb42e087e3d12db0 (diff)
Implement renew & rebind.
Missed in previous.
Diffstat (limited to 'sbin')
-rw-r--r--sbin/dhcp6leased/dhcp6leased.h6
-rw-r--r--sbin/dhcp6leased/engine.c53
-rw-r--r--sbin/dhcp6leased/frontend.c53
3 files changed, 77 insertions, 35 deletions
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 <florian@openbsd.org>
@@ -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 <florian@openbsd.org>
@@ -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 <florian@openbsd.org>
@@ -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,