implement rapid commit
authorflorian <florian@openbsd.org>
Mon, 3 Jun 2024 11:08:31 +0000 (11:08 +0000)
committerflorian <florian@openbsd.org>
Mon, 3 Jun 2024 11:08:31 +0000 (11:08 +0000)
sbin/dhcp6leased/dhcp6leased.c
sbin/dhcp6leased/dhcp6leased.conf.5
sbin/dhcp6leased/dhcp6leased.h
sbin/dhcp6leased/engine.c
sbin/dhcp6leased/frontend.c
sbin/dhcp6leased/parse.y
sbin/dhcp6leased/printconf.c

index 7cc309d..8f6ac0b 100644 (file)
@@ -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 <florian@openbsd.org>
@@ -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);
 
index 4c6278e..ca5f3fb 100644 (file)
@@ -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 <florian@openbsd.org>
 .\" Copyright (c) 2005 Esben Norby <norby@openbsd.org>
@@ -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
index e974657..ae85aa9 100644 (file)
@@ -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 <florian@openbsd.org>
@@ -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 {
index 75a09ed..61e1ebd 100644 (file)
@@ -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 <florian@openbsd.org>
@@ -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;
                }
index d50c606..b3e98c3 100644 (file)
@@ -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 <florian@openbsd.org>
@@ -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) +
index da2a095..f2da857 100644 (file)
@@ -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 <florian@openbsd.org>
@@ -111,7 +111,7 @@ typedef struct {
 
 %}
 
-%token ERROR DELEGATION FOR ON PREFIX REQUEST
+%token ERROR DELEGATION FOR ON PREFIX REQUEST RAPID COMMIT
 
 %token <v.string>      STRING
 %token <v.number>      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;
index 7f69e2d..fe8bb62 100644 (file)
@@ -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 <florian@openbsd.org>
@@ -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);
 }