From 3ae4b9df79285457e898ae3ce0dd69c842f0a5b2 Mon Sep 17 00:00:00 2001 From: florian Date: Mon, 3 Jun 2024 11:08:31 +0000 Subject: [PATCH] implement rapid commit --- sbin/dhcp6leased/dhcp6leased.c | 8 +++++--- sbin/dhcp6leased/dhcp6leased.conf.5 | 16 ++++++++++++++-- sbin/dhcp6leased/dhcp6leased.h | 3 ++- sbin/dhcp6leased/engine.c | 29 ++++++++++++++++++++++++++--- sbin/dhcp6leased/frontend.c | 20 +++++++++++++------- sbin/dhcp6leased/parse.y | 11 +++++++++-- sbin/dhcp6leased/printconf.c | 5 ++++- 7 files changed, 73 insertions(+), 19 deletions(-) diff --git a/sbin/dhcp6leased/dhcp6leased.c b/sbin/dhcp6leased/dhcp6leased.c index 7cc309d435b..8f6ac0b2664 100644 --- a/sbin/dhcp6leased/dhcp6leased.c +++ b/sbin/dhcp6leased/dhcp6leased.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dhcp6leased.c,v 1.6 2024/06/02 17:38:44 florian Exp $ */ +/* $OpenBSD: dhcp6leased.c,v 1.7 2024/06/03 11:08:31 florian Exp $ */ /* * Copyright (c) 2017, 2021, 2024 Florian Obser @@ -648,8 +648,8 @@ main_imsg_send_config(struct dhcp6leased_conf *xconf) struct iface_ia_conf *ia_conf; struct iface_pd_conf *pd_conf; - main_imsg_compose_frontend(IMSG_RECONF_CONF, -1, NULL, 0); - main_imsg_compose_engine(IMSG_RECONF_CONF, -1, NULL, 0); + main_imsg_compose_frontend(IMSG_RECONF_CONF, -1, xconf, sizeof(*xconf)); + main_imsg_compose_engine(IMSG_RECONF_CONF, -1, xconf, sizeof(*xconf)); /* Send the interface list to the frontend & engine. */ SIMPLEQ_FOREACH(iface_conf, &xconf->iface_list, entry) { @@ -898,6 +898,8 @@ merge_config(struct dhcp6leased_conf *conf, struct dhcp6leased_conf *xconf) free(iface_conf); } + conf->rapid_commit = xconf->rapid_commit; + /* Add new interfaces. */ SIMPLEQ_CONCAT(&conf->iface_list, &xconf->iface_list); diff --git a/sbin/dhcp6leased/dhcp6leased.conf.5 b/sbin/dhcp6leased/dhcp6leased.conf.5 index 4c6278eb438..ca5f3fbf799 100644 --- a/sbin/dhcp6leased/dhcp6leased.conf.5 +++ b/sbin/dhcp6leased/dhcp6leased.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: dhcp6leased.conf.5,v 1.2 2024/06/02 22:41:42 jsg Exp $ +.\" $OpenBSD: dhcp6leased.conf.5,v 1.3 2024/06/03 11:08:31 florian Exp $ .\" .\" Copyright (c) 2018, 2021, 2024 Florian Obser .\" Copyright (c) 2005 Esben Norby @@ -18,7 +18,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: June 2 2024 $ +.Dd $Mdocdate: June 3 2024 $ .Dt DHCP6LEASED.CONF 5 .Os .Sh NAME @@ -37,6 +37,9 @@ config file is divided into the following main sections: .It Sy Macros User-defined variables may be defined and used later, simplifying the configuration file. +.It Sy Global Configuration +Global settings for +.Xr dhcp6leased 8 . .It Sy Prefix delegation .Xr dhcp6leased 8 requests prefix delegation from a DHCPv6 server and assigns prefixes @@ -51,6 +54,15 @@ and may contain any of those characters. Macro names may not be reserved words (for example, .Ic interface ) . Macros are not expanded inside quotes. +.Sh GLOBAL CONFIGURATION +These settings affect the operation of the +.Xr dhcp6leased 8 +daemon as a whole. +.Bl -tag -width Ds +.It Ic request rapid commit +Send the rapid commit DHCPv6 option, requesting a two-message exchange +from the server instead of the normal four-message exchange. +.El .Sh PREFIX DELEGATION A list of interfaces on which to request prefix delegation: .Bd -unfilled -offset indent diff --git a/sbin/dhcp6leased/dhcp6leased.h b/sbin/dhcp6leased/dhcp6leased.h index e974657d87e..ae85aa92ad2 100644 --- a/sbin/dhcp6leased/dhcp6leased.h +++ b/sbin/dhcp6leased/dhcp6leased.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dhcp6leased.h,v 1.3 2024/06/02 13:35:52 florian Exp $ */ +/* $OpenBSD: dhcp6leased.h,v 1.4 2024/06/03 11:08:31 florian Exp $ */ /* * Copyright (c) 2017, 2021 Florian Obser @@ -210,6 +210,7 @@ struct iface_conf { struct dhcp6leased_conf { SIMPLEQ_HEAD(iface_conf_head, iface_conf) iface_list; + int rapid_commit; }; struct imsg_ifinfo { diff --git a/sbin/dhcp6leased/engine.c b/sbin/dhcp6leased/engine.c index 75a09ed1da9..61e1ebd46ea 100644 --- a/sbin/dhcp6leased/engine.c +++ b/sbin/dhcp6leased/engine.c @@ -1,4 +1,4 @@ -/* $OpenBSD: engine.c,v 1.4 2024/06/02 13:55:37 florian Exp $ */ +/* $OpenBSD: engine.c,v 1.5 2024/06/03 11:08:31 florian Exp $ */ /* * Copyright (c) 2017, 2021, 2024 Florian Obser @@ -444,9 +444,15 @@ engine_dispatch_main(int fd, short event, void *bula) if (nconf != NULL) fatalx("%s: IMSG_RECONF_CONF already in " "progress", __func__); + if (IMSG_DATA_SIZE(imsg) != + sizeof(struct dhcp6leased_conf)) + fatalx("%s: IMSG_RECONF_CONF wrong length: %lu", + __func__, IMSG_DATA_SIZE(imsg)); if ((nconf = malloc(sizeof(struct dhcp6leased_conf))) == NULL) fatal(NULL); + memcpy(nconf, imsg.data, + sizeof(struct dhcp6leased_conf)); SIMPLEQ_INIT(&nconf->iface_list); break; case IMSG_RECONF_IFACE: @@ -676,7 +682,7 @@ parse_dhcp(struct dhcp6leased_iface *iface, struct imsg_dhcp *dhcp) struct prefix *pds = NULL; size_t rem; uint32_t t1, t2, lease_time; - int serverid_len; + int serverid_len, rapid_commit = 0; uint8_t serverid[SERVERID_SIZE]; uint8_t *p; char ifnamebuf[IF_NAMESIZE], *if_name; @@ -787,6 +793,14 @@ parse_dhcp(struct dhcp6leased_iface *iface, struct imsg_dhcp *dhcp) sizeof(struct dhcp_iapd), &pds[ntohl(iapd.iaid) -1]); break; + case DHO_RAPID_COMMIT: + if (opt_hdr.len != 0) { + log_warnx("%s: invalid rapid commit option", + __func__); + goto out; + } + rapid_commit = 1; + break; default: log_debug("unhandled option: %u", opt_hdr.code); break; @@ -857,12 +871,15 @@ parse_dhcp(struct dhcp6leased_iface *iface, struct imsg_dhcp *dhcp) state_transition(iface, IF_REQUESTING); break; case DHCPREPLY: - /* XXX rapid commit */ switch(iface->state) { case IF_REQUESTING: case IF_RENEWING: case IF_REBINDING: break; + case IF_INIT: + if (rapid_commit && engine_conf->rapid_commit) + break; + /* fall through */ default: log_debug("%s: ignoring unexpected %s", __func__, dhcp_message_type2str(hdr.msg_type)); @@ -1061,6 +1078,12 @@ XXXX case IF_REBOOTING: configure_interfaces(iface); break; + case IF_INIT: + if (engine_conf->rapid_commit) + configure_interfaces(iface); + else + fatal("invalid transition Init -> Bound"); + break; default: break; } diff --git a/sbin/dhcp6leased/frontend.c b/sbin/dhcp6leased/frontend.c index d50c606463b..b3e98c34e3a 100644 --- a/sbin/dhcp6leased/frontend.c +++ b/sbin/dhcp6leased/frontend.c @@ -1,4 +1,4 @@ -/* $OpenBSD: frontend.c,v 1.6 2024/06/02 15:19:05 florian Exp $ */ +/* $OpenBSD: frontend.c,v 1.7 2024/06/03 11:08:31 florian Exp $ */ /* * Copyright (c) 2017, 2021, 2024 Florian Obser @@ -322,9 +322,15 @@ frontend_dispatch_main(int fd, short event, void *bula) if (nconf != NULL) fatalx("%s: IMSG_RECONF_CONF already in " "progress", __func__); + if (IMSG_DATA_SIZE(imsg) != + sizeof(struct dhcp6leased_conf)) + fatalx("%s: IMSG_RECONF_CONF wrong length: %lu", + __func__, IMSG_DATA_SIZE(imsg)); if ((nconf = malloc(sizeof(struct dhcp6leased_conf))) == NULL) fatal(NULL); + memcpy(nconf, imsg.data, + sizeof(struct dhcp6leased_conf)); SIMPLEQ_INIT(&nconf->iface_list); break; case IMSG_RECONF_IFACE: @@ -899,12 +905,12 @@ build_packet(uint8_t message_type, struct iface *iface, char *if_name) memcpy(p, &elapsed_time, sizeof(uint16_t)); p += sizeof(uint16_t); -#ifdef notyet - opt_hdr.code = htons(DHO_RAPID_COMMIT); - opt_hdr.len = htons(0); - memcpy(p, &opt_hdr, sizeof(struct dhcp_option_hdr)); - p += sizeof(struct dhcp_option_hdr); -#endif + if (message_type == DHCPSOLICIT && frontend_conf->rapid_commit) { + opt_hdr.code = htons(DHO_RAPID_COMMIT); + opt_hdr.len = htons(0); + memcpy(p, &opt_hdr, sizeof(struct dhcp_option_hdr)); + p += sizeof(struct dhcp_option_hdr); + } opt_hdr.code = htons(DHO_VENDOR_CLASS); opt_hdr.len = htons(sizeof(struct dhcp_vendor_class) + diff --git a/sbin/dhcp6leased/parse.y b/sbin/dhcp6leased/parse.y index da2a095fb00..f2da857dc0b 100644 --- a/sbin/dhcp6leased/parse.y +++ b/sbin/dhcp6leased/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.4 2024/06/02 17:44:06 florian Exp $ */ +/* $OpenBSD: parse.y,v 1.5 2024/06/03 11:08:31 florian Exp $ */ /* * Copyright (c) 2018, 2024 Florian Obser @@ -111,7 +111,7 @@ typedef struct { %} -%token ERROR DELEGATION FOR ON PREFIX REQUEST +%token ERROR DELEGATION FOR ON PREFIX REQUEST RAPID COMMIT %token STRING %token NUMBER @@ -122,6 +122,7 @@ typedef struct { grammar : /* empty */ | grammar '\n' | grammar varset '\n' + | grammar conf_main '\n' | grammar ia_pd '\n' | grammar error '\n' { file->errors++; } ; @@ -165,6 +166,10 @@ optnl : '\n' optnl /* zero or more newlines */ nl : '\n' optnl /* one or more newlines */ ; +conf_main : REQUEST RAPID COMMIT { + conf->rapid_commit = 1; + } + ; ia_pd : REQUEST PREFIX DELEGATION ON STRING FOR { iface_conf = conf_get_iface($5); @@ -253,10 +258,12 @@ lookup(char *s) { /* This has to be sorted always. */ static const struct keywords keywords[] = { + {"commit", COMMIT}, {"delegation", DELEGATION}, {"for", FOR}, {"on", ON}, {"prefix", PREFIX}, + {"rapid", RAPID}, {"request", REQUEST}, }; const struct keywords *p; diff --git a/sbin/dhcp6leased/printconf.c b/sbin/dhcp6leased/printconf.c index 7f69e2d7ca9..fe8bb623a52 100644 --- a/sbin/dhcp6leased/printconf.c +++ b/sbin/dhcp6leased/printconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: printconf.c,v 1.2 2024/06/02 13:35:52 florian Exp $ */ +/* $OpenBSD: printconf.c,v 1.3 2024/06/03 11:08:31 florian Exp $ */ /* * Copyright (c) 2024 Florian Obser @@ -100,6 +100,9 @@ print_config(struct dhcp6leased_conf *conf, int verbose) { struct iface_conf *iface; + if (conf->rapid_commit) + printf("request rapid commit\n\n"); + SIMPLEQ_FOREACH(iface, &conf->iface_list, entry) print_iface_conf(iface, verbose); } -- 2.20.1