Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package iwd for openSUSE:Factory checked in 
at 2024-02-21 17:55:59
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/iwd (Old)
 and      /work/SRC/openSUSE:Factory/.iwd.new.1706 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "iwd"

Wed Feb 21 17:55:59 2024 rev:45 rq:1147787 version:2.14

Changes:
--------
--- /work/SRC/openSUSE:Factory/iwd/iwd.changes  2024-01-26 22:47:42.905165676 
+0100
+++ /work/SRC/openSUSE:Factory/.iwd.new.1706/iwd.changes        2024-02-21 
17:56:14.574926973 +0100
@@ -1,0 +2,8 @@
+Sat Feb 17 09:45:20 UTC 2024 - Luigi Baldoni <aloi...@gmx.com>
+
+- Update to version 2.14
+  * Fix issue with accepting PTK 4/4 after receiving PTK 2/4.
+  * Fix issue with frequency limit for quick scans.
+  * Fix issue with limiting DHCPv4 attempts.
+
+-------------------------------------------------------------------

Old:
----
  iwd-2.13.tar.sign
  iwd-2.13.tar.xz

New:
----
  iwd-2.14.tar.sign
  iwd-2.14.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ iwd.spec ++++++
--- /var/tmp/diff_new_pack.RZoL3H/_old  2024-02-21 17:56:15.142947513 +0100
+++ /var/tmp/diff_new_pack.RZoL3H/_new  2024-02-21 17:56:15.142947513 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           iwd
-Version:        2.13
+Version:        2.14
 Release:        0
 Summary:        Wireless daemon for Linux
 License:        LGPL-2.1-or-later
@@ -31,7 +31,7 @@
 BuildRequires:  pkg-config
 BuildRequires:  systemd-rpm-macros
 BuildRequires:  pkgconfig(dbus-1)
-BuildRequires:  pkgconfig(ell) >= 0.61
+BuildRequires:  pkgconfig(ell) >= 0.62
 BuildRequires:  pkgconfig(readline)
 BuildRequires:  pkgconfig(systemd)
 %{?systemd_ordering}

++++++ iwd-2.13.tar.xz -> iwd-2.14.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ChangeLog new/iwd-2.14/ChangeLog
--- old/iwd-2.13/ChangeLog      2024-01-12 20:08:50.000000000 +0100
+++ new/iwd-2.14/ChangeLog      2024-02-09 22:15:09.000000000 +0100
@@ -1,3 +1,8 @@
+ver 2.14:
+       Fix issue with accepting PTK 4/4 after receiving PTK 2/4.
+       Fix issue with frequency limit for quick scans.
+       Fix issue with limiting DHCPv4 attempts.
+
 ver 2.13:
        Fix issue with handling netconfig and roaming conditions.
        Fix issue with logging requirement for CMD_EXTERNAL_AUTH.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/configure new/iwd-2.14/configure
--- old/iwd-2.13/configure      2024-01-12 20:10:38.000000000 +0100
+++ new/iwd-2.14/configure      2024-02-09 22:16:59.000000000 +0100
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.71 for iwd 2.13.
+# Generated by GNU Autoconf 2.71 for iwd 2.14.
 #
 #
 # Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation,
@@ -618,8 +618,8 @@
 # Identity of this package.
 PACKAGE_NAME='iwd'
 PACKAGE_TARNAME='iwd'
-PACKAGE_VERSION='2.13'
-PACKAGE_STRING='iwd 2.13'
+PACKAGE_VERSION='2.14'
+PACKAGE_STRING='iwd 2.14'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
@@ -1433,7 +1433,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures iwd 2.13 to adapt to many kinds of systems.
+\`configure' configures iwd 2.14 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1504,7 +1504,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of iwd 2.13:";;
+     short | recursive ) echo "Configuration of iwd 2.14:";;
    esac
   cat <<\_ACEOF
 
@@ -1661,7 +1661,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-iwd configure 2.13
+iwd configure 2.14
 generated by GNU Autoconf 2.71
 
 Copyright (C) 2021 Free Software Foundation, Inc.
@@ -1879,7 +1879,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by iwd $as_me 2.13, which was
+It was created by iwd $as_me 2.14, which was
 generated by GNU Autoconf 2.71.  Invocation command line was
 
   $ $0$ac_configure_args_raw
@@ -3154,7 +3154,7 @@
 
 # Define the identity of the package.
  PACKAGE='iwd'
- VERSION='2.13'
+ VERSION='2.14'
 
 
 printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h
@@ -14236,7 +14236,7 @@
                        test "${enable_monitor}" != "no" ||
                        test "${enable_wired}" = "yes" ||
                        test "${enable_hwsim}" = "yes"); then
-               ell_min_version="0.61"
+               ell_min_version="0.62"
        else
                ell_min_version="0.5"
        fi
@@ -14984,7 +14984,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by iwd $as_me 2.13, which was
+This file was extended by iwd $as_me 2.14, which was
 generated by GNU Autoconf 2.71.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -15052,7 +15052,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config='$ac_cs_config_escaped'
 ac_cs_version="\\
-iwd config.status 2.13
+iwd config.status 2.14
 configured by $0, generated by GNU Autoconf 2.71,
   with options \\"\$ac_cs_config\\"
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/configure.ac new/iwd-2.14/configure.ac
--- old/iwd-2.13/configure.ac   2024-01-12 20:08:50.000000000 +0100
+++ new/iwd-2.14/configure.ac   2024-02-09 22:15:09.000000000 +0100
@@ -1,5 +1,5 @@
 AC_PREREQ([2.69])
-AC_INIT([iwd],[2.13])
+AC_INIT([iwd],[2.14])
 
 AC_CONFIG_HEADERS(config.h)
 AC_CONFIG_AUX_DIR(build-aux)
@@ -297,7 +297,7 @@
                        test "${enable_monitor}" != "no" ||
                        test "${enable_wired}" = "yes" ||
                        test "${enable_hwsim}" = "yes"); then
-               ell_min_version="0.61"
+               ell_min_version="0.62"
        else
                ell_min_version="0.5"
        fi
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/acd.c new/iwd-2.14/ell/acd.c
--- old/iwd-2.13/ell/acd.c      2023-09-27 11:03:04.000000000 +0200
+++ new/iwd-2.14/ell/acd.c      2024-02-06 18:44:14.000000000 +0100
@@ -326,7 +326,7 @@
                /*
                 * We still have an initial announcement to send, but rather
                 * than wait for that (potentially 2 seconds) we can remove
-                * the timeout, send annouce now, and still transition to the
+                * the timeout, send announce now, and still transition to the
                 * defending state.
                 */
                if (acd->timeout)
@@ -518,14 +518,14 @@
 
 LIB_EXPORT bool l_acd_set_debug(struct l_acd *acd,
                                l_acd_debug_cb_t function,
-                               void *user_data, l_acd_destroy_func_t destory)
+                               void *user_data, l_acd_destroy_func_t destroy)
 {
        if (unlikely(!acd))
                return false;
 
        acd->debug_handler = function;
        acd->debug_data = user_data;
-       acd->debug_destroy = destory;
+       acd->debug_destroy = destroy;
 
        return true;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/acd.h new/iwd-2.14/ell/acd.h
--- old/iwd-2.13/ell/acd.h      2023-09-27 11:03:04.000000000 +0200
+++ new/iwd-2.14/ell/acd.h      2024-02-06 18:44:14.000000000 +0100
@@ -40,7 +40,7 @@
 bool l_acd_stop(struct l_acd *acd);
 void l_acd_destroy(struct l_acd *acd);
 bool l_acd_set_debug(struct l_acd *acd, l_acd_debug_cb_t function,
-                       void *user_data, l_acd_destroy_func_t destory);
+                       void *user_data, l_acd_destroy_func_t destroy);
 bool l_acd_set_skip_probes(struct l_acd *acd, bool skip);
 bool l_acd_set_defend_policy(struct l_acd *acd,
                                enum l_acd_defend_policy policy);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/cleanup.h new/iwd-2.14/ell/cleanup.h
--- old/iwd-2.13/ell/cleanup.h  2023-09-27 11:03:04.000000000 +0200
+++ new/iwd-2.14/ell/cleanup.h  2024-02-06 18:44:14.000000000 +0100
@@ -7,6 +7,9 @@
 
 #pragma once
 
+#define __L_AUTODESTRUCT(func)                         \
+       __attribute((cleanup(_l_ ## func ## _cleanup)))
+
 #define DEFINE_CLEANUP_FUNC(func)                      \
        inline __attribute__((always_inline))           \
-       void func ## _cleanup(void *p) { func(*(void **) p); }
+       void _l_ ## func ## _cleanup(void *p) { func(*(void **) p); }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/dhcp-server.c 
new/iwd-2.14/ell/dhcp-server.c
--- old/iwd-2.13/ell/dhcp-server.c      2023-09-27 11:03:04.000000000 +0200
+++ new/iwd-2.14/ell/dhcp-server.c      2024-02-06 18:44:14.000000000 +0100
@@ -1168,14 +1168,14 @@
 
 LIB_EXPORT bool l_dhcp_server_set_debug(struct l_dhcp_server *server,
                                l_dhcp_debug_cb_t function,
-                               void *user_data, l_dhcp_destroy_cb_t destory)
+                               void *user_data, l_dhcp_destroy_cb_t destroy)
 {
        if (unlikely(!server))
                return false;
 
        server->debug_handler = function;
        server->debug_data = user_data;
-       server->debug_destroy = destory;
+       server->debug_destroy = destroy;
 
        return true;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/dhcp.c new/iwd-2.14/ell/dhcp.c
--- old/iwd-2.13/ell/dhcp.c     2023-09-27 11:03:04.000000000 +0200
+++ new/iwd-2.14/ell/dhcp.c     2024-02-06 18:44:14.000000000 +0100
@@ -45,6 +45,8 @@
        client->state = (s)
 
 #define BITS_PER_LONG (sizeof(unsigned long) * 8)
+#define CLIENT_MAX_ATTEMPT_LIMIT 30
+#define CLIENT_MIN_ATTEMPT_LIMIT 3
 
 enum dhcp_state {
        DHCP_STATE_INIT,
@@ -159,6 +161,7 @@
        uint32_t rtnl_add_cmdid;
        struct l_rtnl_address *rtnl_configured_address;
        uint8_t attempt;
+       uint8_t max_attempts;
        l_dhcp_client_event_cb_t event_handler;
        void *event_data;
        l_dhcp_destroy_cb_t event_destroy;
@@ -558,9 +561,16 @@
                 * "The retransmission delay SHOULD be doubled with subsequent
                 * retransmissions up to a maximum of 64 seconds.
                 */
-               client->attempt += 1;
-               next_timeout = minsize(2 << client->attempt, 64);
-               break;
+               if (client->attempt < client->max_attempts) {
+                       next_timeout = minsize(2 << client->attempt++, 64);
+                       break;
+               }
+
+               CLIENT_DEBUG("Max request/discover attempts reached");
+
+               dhcp_client_event_notify(client,
+                               L_DHCP_CLIENT_EVENT_MAX_ATTEMPTS_REACHED);
+               return;
        case DHCP_STATE_INIT:
        case DHCP_STATE_INIT_REBOOT:
        case DHCP_STATE_REBOOTING:
@@ -988,6 +998,7 @@
 
        client->state = DHCP_STATE_INIT;
        client->ifindex = ifindex;
+       client->max_attempts = CLIENT_MAX_ATTEMPT_LIMIT;
 
        /* Enable these options by default */
        dhcp_enable_option(client, L_DHCP_OPTION_SUBNET_MASK);
@@ -1309,3 +1320,21 @@
        client->rtnl = rtnl;
        return true;
 }
+
+LIB_EXPORT bool l_dhcp_client_set_max_attempts(struct l_dhcp_client *client,
+                                               uint8_t attempts)
+{
+       if (unlikely(!client))
+               return false;
+
+       if (unlikely(client->state != DHCP_STATE_INIT))
+               return false;
+
+       if (attempts < CLIENT_MIN_ATTEMPT_LIMIT ||
+                               attempts > CLIENT_MAX_ATTEMPT_LIMIT)
+               return false;
+
+       client->max_attempts = attempts;
+
+       return true;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/dhcp.h new/iwd-2.14/ell/dhcp.h
--- old/iwd-2.13/ell/dhcp.h     2023-09-27 11:03:04.000000000 +0200
+++ new/iwd-2.14/ell/dhcp.h     2024-02-06 18:44:14.000000000 +0100
@@ -41,6 +41,7 @@
        L_DHCP_CLIENT_EVENT_LEASE_EXPIRED,
        L_DHCP_CLIENT_EVENT_LEASE_RENEWED,
        L_DHCP_CLIENT_EVENT_NO_LEASE,
+       L_DHCP_CLIENT_EVENT_MAX_ATTEMPTS_REACHED,
 };
 
 enum l_dhcp_server_event {
@@ -73,6 +74,8 @@
 
 bool l_dhcp_client_set_rtnl(struct l_dhcp_client *client,
                                        struct l_netlink *rtnl);
+bool l_dhcp_client_set_max_attempts(struct l_dhcp_client *client,
+                                       uint8_t attempts);
 
 const struct l_dhcp_lease *l_dhcp_client_get_lease(
                                        const struct l_dhcp_client *client);
@@ -119,7 +122,7 @@
                                const char *end_ip);
 bool l_dhcp_server_set_debug(struct l_dhcp_server *server,
                                l_dhcp_debug_cb_t function,
-                               void *user_data, l_dhcp_destroy_cb_t destory);
+                               void *user_data, l_dhcp_destroy_cb_t destroy);
 bool l_dhcp_server_set_event_handler(struct l_dhcp_server *server,
                                        l_dhcp_server_event_cb_t handler,
                                        void *user_data,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/dhcp6.c new/iwd-2.14/ell/dhcp6.c
--- old/iwd-2.13/ell/dhcp6.c    2023-09-27 11:03:04.000000000 +0200
+++ new/iwd-2.14/ell/dhcp6.c    2024-02-06 18:44:14.000000000 +0100
@@ -1602,7 +1602,7 @@
 
 /*
  * Set the link local address to use instead of binding to the in6addr_any
- * address by default.  This allows multiple clients to coexist simulatenously
+ * address by default.  This allows multiple clients to coexist simultaneously
  * on different ifindexes
  */
 LIB_EXPORT bool l_dhcp6_client_set_link_local_address(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/dir.c new/iwd-2.14/ell/dir.c
--- old/iwd-2.13/ell/dir.c      2023-09-27 11:03:04.000000000 +0200
+++ new/iwd-2.14/ell/dir.c      2024-02-06 18:44:14.000000000 +0100
@@ -15,8 +15,10 @@
 #include <limits.h>
 #include <sys/inotify.h>
 #include <errno.h>
+#include <sys/stat.h>
 
 #include "private.h"
+#include "useful.h"
 #include "queue.h"
 #include "io.h"
 #include "dir.h"
@@ -336,3 +338,53 @@
 
        l_free(watch);
 }
+
+/**
+ * l_dir_create:
+ * @abspath: Absolute path of the directory to create
+ *
+ * Attempts to create a directory tree given by @abspath.  @abspath must be
+ * an absolute path.
+ *
+ * Returns: 0 if successful, a negative errno otherwise
+ **/
+LIB_EXPORT int l_dir_create(const char *abspath)
+{
+       static const mode_t create_mode = S_IRUSR | S_IWUSR | S_IXUSR;
+       struct stat st;
+       _auto_(l_free) char *dir = NULL;
+       const char *prev, *next;
+       int err;
+
+       if (!abspath || abspath[0] != '/')
+               return -EINVAL;
+
+       err = stat(abspath, &st);
+       if (!err) {
+               /* File exists */
+               if (S_ISDIR(st.st_mode))
+                       return 0;
+
+               return -ENOTDIR;
+       }
+
+       if (errno != ENOENT)
+               return -errno;
+
+       dir = l_malloc(strlen(abspath) + 1);
+       dir[0] = '\0';
+
+       for (prev = abspath; prev[0] && (next = strchrnul(prev + 1, '/'));
+                                                               prev = next) {
+               /* Skip consecutive '/' characters */
+               if (next - prev == 1)
+                       continue;
+
+               strncat(dir, prev, next - prev);
+
+               if (mkdir(dir, create_mode) == -1 && errno != EEXIST)
+                       return -errno;
+       }
+
+       return 0;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/dir.h new/iwd-2.14/ell/dir.h
--- old/iwd-2.13/ell/dir.h      2023-09-27 11:03:04.000000000 +0200
+++ new/iwd-2.14/ell/dir.h      2024-02-06 18:44:14.000000000 +0100
@@ -33,6 +33,8 @@
                                        l_dir_watch_destroy_func_t destroy);
 void l_dir_watch_destroy(struct l_dir_watch *watch);
 
+int l_dir_create(const char *abspath);
+
 #ifdef __cplusplus
 }
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/ecc.c new/iwd-2.14/ell/ecc.c
--- old/iwd-2.13/ell/ecc.c      2023-11-19 18:31:06.000000000 +0100
+++ new/iwd-2.14/ell/ecc.c      2024-02-06 18:44:14.000000000 +0100
@@ -808,7 +808,7 @@
 
 /*
  * Build a scalar = value modulo p where p is the prime number for a given
- * curve.  bytes can contain a numer with up to 2x number of digits as the
+ * curve.  bytes can contain a number with up to 2x number of digits as the
  * curve.  This is used in Hash to Curve calculations.
  */
 LIB_EXPORT struct l_ecc_scalar *l_ecc_scalar_new_modp(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/file.c new/iwd-2.14/ell/file.c
--- old/iwd-2.13/ell/file.c     2023-09-27 11:03:04.000000000 +0200
+++ new/iwd-2.14/ell/file.c     2024-02-06 18:44:14.000000000 +0100
@@ -15,9 +15,12 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
 
 #include "file.h"
 #include "private.h"
+#include "useful.h"
 
 /**
  * l_file_get_contents:
@@ -72,3 +75,56 @@
        close(fd);
        return NULL;
 }
+
+/**
+ * l_file_set_contents:
+ * @filename: Destination filename
+ * @contents: Pointer to the contents
+ * @len: Length in bytes of the contents buffer
+ *
+ * Given a content buffer, write it to a file named @filename.  This function
+ * ensures that the contents are consistent (i.e. due to a crash right after
+ * opening or during write() by writing the contents to a temporary which is 
then
+ * renamed to @filename.
+ *
+ * Returns: 0 if successful, a negative errno otherwise
+ **/
+LIB_EXPORT int l_file_set_contents(const char *filename,
+                                       const void *contents, size_t len)
+{
+       _auto_(l_free) char *tmp_path = NULL;
+       ssize_t r;
+       int fd;
+
+       if (!filename || !contents)
+               return -EINVAL;
+
+       tmp_path = l_strdup_printf("%s.XXXXXX.tmp", filename);
+
+       fd = L_TFR(mkostemps(tmp_path, 4, O_CLOEXEC));
+       if (fd == -1)
+               return -errno;
+
+       r = L_TFR(write(fd, contents, len));
+       L_TFR(close(fd));
+
+       if (r != (ssize_t) len) {
+               r = -EIO;
+               goto error_write;
+       }
+
+       /*
+        * Now that the file contents are written, rename to the real
+        * file name; this way we are uniquely sure that the whole
+        * thing is there.
+        * conserve @r's value from 'write'
+        */
+       if (rename(tmp_path, filename) == -1)
+               r = -errno;
+
+error_write:
+       if (r < 0)
+               unlink(tmp_path);
+
+       return r < 0 ? r : 0;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/file.h new/iwd-2.14/ell/file.h
--- old/iwd-2.13/ell/file.h     2023-09-27 11:03:04.000000000 +0200
+++ new/iwd-2.14/ell/file.h     2024-02-06 18:44:14.000000000 +0100
@@ -13,6 +13,7 @@
 #endif
 
 void *l_file_get_contents(const char *filename, size_t *out_len);
+int l_file_set_contents(const char *filename, const void *data, size_t len);
 
 #ifdef __cplusplus
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/hashmap.c new/iwd-2.14/ell/hashmap.c
--- old/iwd-2.13/ell/hashmap.c  2023-09-27 11:03:04.000000000 +0200
+++ new/iwd-2.14/ell/hashmap.c  2024-02-06 18:44:14.000000000 +0100
@@ -32,7 +32,7 @@
 /**
  * l_hashmap:
  *
- * Opague object representing the hash table.
+ * Opaque object representing the hash table.
  */
 struct l_hashmap {
        l_hashmap_hash_func_t hash_func;
@@ -296,7 +296,7 @@
  * @hashmap: hash table object
  * @destroy: destroy function
  *
- * Free hash table and call @destory on all remaining entries.
+ * Free hash table and call @destroy on all remaining entries.
  *
  * NOTE: While the destroy is in progress, the hashmap is assumed to be
  * invariant.  The behavior of adding or removing entries while a destroy
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/idle.c new/iwd-2.14/ell/idle.c
--- old/iwd-2.13/ell/idle.c     2023-09-27 11:03:04.000000000 +0200
+++ new/iwd-2.14/ell/idle.c     2024-02-06 18:44:14.000000000 +0100
@@ -28,7 +28,7 @@
 /**
  * l_idle:
  *
- * Opague object representing the idle time event.
+ * Opaque object representing the idle time event.
  */
 struct l_idle {
        union {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/io.c new/iwd-2.14/ell/io.c
--- old/iwd-2.13/ell/io.c       2023-09-27 11:03:04.000000000 +0200
+++ new/iwd-2.14/ell/io.c       2024-02-06 18:44:14.000000000 +0100
@@ -29,7 +29,7 @@
 /**
  * l_io:
  *
- * Opague object representing the IO.
+ * Opaque object representing the IO.
  */
 struct l_io {
        int fd;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/main.c new/iwd-2.14/ell/main.c
--- old/iwd-2.13/ell/main.c     2023-09-27 11:03:04.000000000 +0200
+++ new/iwd-2.14/ell/main.c     2024-02-06 18:44:14.000000000 +0100
@@ -568,7 +568,7 @@
 /**
  * l_main_quit:
  *
- * Teminate the running main loop
+ * Terminate the running main loop
  *
  * Returns: #true when terminating the main loop or #false in case of failure
  **/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/netconfig.c new/iwd-2.14/ell/netconfig.c
--- old/iwd-2.13/ell/netconfig.c        2023-11-25 20:14:48.000000000 +0100
+++ new/iwd-2.14/ell/netconfig.c        2024-02-06 18:44:14.000000000 +0100
@@ -549,6 +549,12 @@
                        netconfig_failed(nc, AF_INET);
 
                break;
+       case L_DHCP_CLIENT_EVENT_MAX_ATTEMPTS_REACHED:
+               L_WARN_ON(nc->v4_configured);
+
+               netconfig_failed(nc, AF_INET);
+
+               break;
        }
 }
 
@@ -1933,10 +1939,10 @@
        /*
         * Handle the case of no link-local address having been found during
         * the dump.  If nc->ifaddr6_dump_cmd_id is 0, we have found one or
-        * the dump is being cancelled.  Otherwise try disabing the
+        * the dump is being cancelled.  Otherwise try disabling the
         * "disable_ipv6" setting for the interface since it may have been
         * enabled.  Also write "addr_gen_mode" which triggers regerating
-        * the link-local addresss on the interface in the kernel if it
+        * the link-local address on the interface in the kernel if it
         * was previously removed.
         */
        if (!nc->ifaddr6_dump_cmd_id || !nc->started)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/queue.c new/iwd-2.14/ell/queue.c
--- old/iwd-2.13/ell/queue.c    2023-09-27 11:03:04.000000000 +0200
+++ new/iwd-2.14/ell/queue.c    2024-02-06 18:44:14.000000000 +0100
@@ -23,7 +23,7 @@
 /**
  * l_queue:
  *
- * Opague object representing the queue.
+ * Opaque object representing the queue.
  */
 struct l_queue {
        struct l_queue_entry *head;
@@ -59,7 +59,7 @@
  * @queue: queue object
  * @destroy: destroy function
  *
- * Free queue and call @destory on all remaining entries.
+ * Free queue and call @destroy on all remaining entries.
  **/
 LIB_EXPORT void l_queue_destroy(struct l_queue *queue,
                                l_queue_destroy_func_t destroy)
@@ -73,7 +73,7 @@
  * @queue: queue object
  * @destroy: destroy function
  *
- * Clear queue and call @destory on all remaining entries.
+ * Clear queue and call @destroy on all remaining entries.
  **/
 LIB_EXPORT void l_queue_clear(struct l_queue *queue,
                                l_queue_destroy_func_t destroy)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/random.h new/iwd-2.14/ell/random.h
--- old/iwd-2.13/ell/random.h   2023-09-27 11:03:04.000000000 +0200
+++ new/iwd-2.14/ell/random.h   2024-02-06 18:44:14.000000000 +0100
@@ -8,14 +8,14 @@
 #ifndef __ELL_RANDOM_H
 #define __ELL_RANDOM_H
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #include <stddef.h>
 #include <stdbool.h>
 #include <stdint.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 bool l_getrandom(void *buf, size_t len);
 bool l_getrandom_is_supported(void);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/ringbuf.c new/iwd-2.14/ell/ringbuf.c
--- old/iwd-2.13/ell/ringbuf.c  2023-09-27 11:03:04.000000000 +0200
+++ new/iwd-2.14/ell/ringbuf.c  2024-02-06 18:44:14.000000000 +0100
@@ -29,7 +29,7 @@
 /**
  * l_ringbuf:
  *
- * Opague object representing the Ring Buffer.
+ * Opaque object representing the Ring Buffer.
  */
 struct l_ringbuf {
        void *buffer;
@@ -42,7 +42,7 @@
 
 #define RINGBUF_RESET 0
 
-/* Find last (most siginificant) set bit */
+/* Find last (most significant) set bit */
 static inline unsigned int fls(unsigned int x)
 {
        return x ? sizeof(x) * 8 - __builtin_clz(x) : 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/signal.c new/iwd-2.14/ell/signal.c
--- old/iwd-2.13/ell/signal.c   2023-09-27 11:03:04.000000000 +0200
+++ new/iwd-2.14/ell/signal.c   2024-02-06 18:44:14.000000000 +0100
@@ -33,7 +33,7 @@
 /**
  * l_signal:
  *
- * Opague object representing the signal.
+ * Opaque object representing the signal.
  */
 struct l_signal {
        struct signal_desc *desc;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/string.c new/iwd-2.14/ell/string.c
--- old/iwd-2.13/ell/string.c   2023-09-27 11:03:04.000000000 +0200
+++ new/iwd-2.14/ell/string.c   2024-02-06 18:44:14.000000000 +0100
@@ -26,7 +26,7 @@
 /**
  * l_string:
  *
- * Opague object representing the string buffer.
+ * Opaque object representing the string buffer.
  */
 struct l_string {
        size_t max;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/strv.c new/iwd-2.14/ell/strv.c
--- old/iwd-2.13/ell/strv.c     2023-09-27 11:03:04.000000000 +0200
+++ new/iwd-2.14/ell/strv.c     2024-02-06 18:44:14.000000000 +0100
@@ -190,7 +190,7 @@
 /**
  * l_strv_new:
  *
- * Returns: new emptry string array
+ * Returns: new empty string array
  **/
 LIB_EXPORT char **l_strv_new(void)
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/time.h new/iwd-2.14/ell/time.h
--- old/iwd-2.13/ell/time.h     2023-09-27 11:03:04.000000000 +0200
+++ new/iwd-2.14/ell/time.h     2024-02-06 18:44:14.000000000 +0100
@@ -8,13 +8,13 @@
 #ifndef __ELL_TIME_H
 #define __ELL_TIME_H
 
+#include <stdint.h>
+#include <stdbool.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#include <stdint.h>
-#include <stdbool.h>
-
 #define L_USEC_PER_SEC 1000000ULL
 #define L_MSEC_PER_SEC 1000ULL
 #define L_USEC_PER_MSEC 1000ULL
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/timeout.c new/iwd-2.14/ell/timeout.c
--- old/iwd-2.13/ell/timeout.c  2023-09-27 11:03:04.000000000 +0200
+++ new/iwd-2.14/ell/timeout.c  2024-02-06 18:44:14.000000000 +0100
@@ -34,7 +34,7 @@
 /**
  * l_timeout:
  *
- * Opague object representing the timeout.
+ * Opaque object representing the timeout.
  */
 struct l_timeout {
        int fd;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/timeout.h new/iwd-2.14/ell/timeout.h
--- old/iwd-2.13/ell/timeout.h  2023-09-27 11:03:04.000000000 +0200
+++ new/iwd-2.14/ell/timeout.h  2024-02-06 18:44:14.000000000 +0100
@@ -8,12 +8,12 @@
 #ifndef __ELL_TIMEOUT_H
 #define __ELL_TIMEOUT_H
 
+#include <stdint.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-#include <stdint.h>
-
 struct l_timeout;
 
 typedef void (*l_timeout_notify_cb_t) (struct l_timeout *timeout,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/tls-extensions.c 
new/iwd-2.14/ell/tls-extensions.c
--- old/iwd-2.13/ell/tls-extensions.c   2023-09-27 11:03:04.000000000 +0200
+++ new/iwd-2.14/ell/tls-extensions.c   2024-02-06 18:44:14.000000000 +0100
@@ -955,7 +955,7 @@
 
        /*
         * The normal policy otherwise is that the extension must be
-        * present in renegotation if the previous Client or Server Hello
+        * present in renegotiation if the previous Client or Server Hello
         * did include this extension, or the SCSV in the Client Hello case.
         */
        return !tls->ready || !tls->renegotiation_info.secure_renegotiation;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/tls.c new/iwd-2.14/ell/tls.c
--- old/iwd-2.13/ell/tls.c      2023-09-27 11:03:04.000000000 +0200
+++ new/iwd-2.14/ell/tls.c      2024-02-06 18:44:14.000000000 +0100
@@ -1311,7 +1311,7 @@
                 * Note: could handle NULL client_write with non-NULL
                 * server_handle or server_handle_absent as "server-oriented"
                 * extension (7.4.1.4) and write empty extension_data and
-                * simliarly require empty extension_data in
+                * similarly require empty extension_data in
                 * tls_handle_client_hello if client_handle NULL.
                 */
                if (!ext_write)
@@ -3299,7 +3299,7 @@
                 *
                 *    * (RSA key exchange algorithm case) the correct
                 *      receival of this Finished message confirms the
-                *      posession of the master secret, it is verified by
+                *      possession of the master secret, it is verified by
                 *      both the successful decryption and the MAC of this
                 *      message (either should be enough) because we entered
                 *      the TLS_HANDSHAKE_WAIT_FINISHED state only after
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/uintset.h new/iwd-2.14/ell/uintset.h
--- old/iwd-2.13/ell/uintset.h  2023-09-27 11:03:04.000000000 +0200
+++ new/iwd-2.14/ell/uintset.h  2024-02-06 18:44:14.000000000 +0100
@@ -8,15 +8,15 @@
 #ifndef __ELL_UINTSET_H
 #define __ELL_UINTSET_H
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
 #include <stdint.h>
 #include <stddef.h>
 #include <stdbool.h>
 #include <ell/cleanup.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 typedef void (*l_uintset_foreach_func_t) (uint32_t number, void *user_data);
 
 struct l_uintset;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/useful.h new/iwd-2.14/ell/useful.h
--- old/iwd-2.13/ell/useful.h   2023-11-19 18:31:06.000000000 +0100
+++ new/iwd-2.14/ell/useful.h   2024-02-06 18:44:14.000000000 +0100
@@ -5,11 +5,6 @@
  * SPDX-License-Identifier: LGPL-2.1-or-later
  */
 
-#include <unistd.h>
-#include <errno.h>
-
-#include <ell/util.h>
-
 #define align_len(len, boundary) (((len)+(boundary)-1) & ~((boundary)-1))
 
 #define likely(x)   __builtin_expect(!!(x), 1)
@@ -64,20 +59,10 @@
        _x / _d;                                        \
 })
 
-#define __AUTODESTRUCT(func)                           \
-       __attribute((cleanup(func ## _cleanup)))
-
+#ifndef _auto_
 #define _auto_(func)                                   \
-       __AUTODESTRUCT(func)
-
-/* Enables declaring _auto_(close) int fd = <-1 or L_TFR(open(...))>; */
-inline __attribute__((always_inline)) void close_cleanup(void *p)
-{
-       int fd = *(int *) p;
-
-       if (fd >= 0)
-               L_TFR(close(fd));
-}
+       __L_AUTODESTRUCT(func)
+#endif
 
 /*
  * Trick the compiler into thinking that var might be changed somehow by
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/utf8.c new/iwd-2.14/ell/utf8.c
--- old/iwd-2.13/ell/utf8.c     2023-09-27 11:03:04.000000000 +0200
+++ new/iwd-2.14/ell/utf8.c     2024-02-06 18:44:14.000000000 +0100
@@ -1,6 +1,7 @@
 /*
  * Embedded Linux library
  * Copyright (C) 2011-2014  Intel Corporation
+ * Copyright (C) 2024  Cruise, LLC
  *
  * SPDX-License-Identifier: LGPL-2.1-or-later
  */
@@ -42,6 +43,70 @@
        [0x80 ... 0xFF] = 0,
 };
 
+/**
+ * l_ascii_strdown
+ * @str: a pointer to an ASCII string
+ * @len: maximum bytes to process or negative if string is null terminated
+ *
+ * Returns: Newly allocated string with all upper case characters converted
+ * to lower case.
+ **/
+LIB_EXPORT char *l_ascii_strdown(const char *str, ssize_t len)
+{
+       size_t slen;
+       size_t i;
+       char *ret;
+
+       if (!str)
+               return NULL;
+
+       if (len < 0)
+               slen = strlen(str);
+       else
+               slen = minsize(strlen(str), (size_t) len);
+
+       ret = l_malloc(slen + 1);
+
+       for (i = 0; i < slen; i++)
+               ret[i] = l_ascii_tolower(str[i]);
+
+       ret[i] = '\0';
+
+       return ret;
+}
+
+/**
+ * l_ascii_strup
+ * @str: a pointer to an ASCII string
+ * @len: maximum bytes to process or negative if string is null terminated
+ *
+ * Returns: Newly allocated string with all lower case characters converted
+ * to upper case.
+ **/
+LIB_EXPORT char *l_ascii_strup(const char *str, ssize_t len)
+{
+       size_t slen;
+       size_t i;
+       char *ret;
+
+       if (!str)
+               return NULL;
+
+       if (len < 0)
+               slen = strlen(str);
+       else
+               slen = minsize(strlen(str), (size_t) len);
+
+       ret = l_malloc(slen + 1);
+
+       for (i = 0; i < slen; i++)
+               ret[i] = l_ascii_toupper(str[i]);
+
+       ret[i] = '\0';
+
+       return ret;
+}
+
 static inline bool __attribute__ ((always_inline))
                        valid_unicode(wchar_t c)
 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/utf8.h new/iwd-2.14/ell/utf8.h
--- old/iwd-2.13/ell/utf8.h     2023-09-27 11:03:04.000000000 +0200
+++ new/iwd-2.14/ell/utf8.h     2024-02-06 18:44:14.000000000 +0100
@@ -1,6 +1,7 @@
 /*
  * Embedded Linux library
  * Copyright (C) 2011-2014  Intel Corporation
+ * Copyright (C) 2024  Cruise, LLC
  *
  * SPDX-License-Identifier: LGPL-2.1-or-later
  */
@@ -86,6 +87,25 @@
        return false;
 }
 
+static inline __attribute__ ((always_inline)) char l_ascii_toupper(char c)
+{
+       if (!l_ascii_islower(c))
+               return c;
+
+       return c - 32;
+}
+
+static inline __attribute__ ((always_inline)) char l_ascii_tolower(char c)
+{
+       if (!l_ascii_isupper(c))
+               return c;
+
+       return c + 32;
+}
+
+char *l_ascii_strdown(const char *str, ssize_t len);
+char *l_ascii_strup(const char *str, ssize_t len);
+
 bool l_utf8_validate(const char *src, size_t len, const char **end);
 size_t l_utf8_strlen(const char *str);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/util.c new/iwd-2.14/ell/util.c
--- old/iwd-2.13/ell/util.c     2023-09-27 11:03:04.000000000 +0200
+++ new/iwd-2.14/ell/util.c     2024-02-06 18:44:14.000000000 +0100
@@ -127,7 +127,7 @@
  * l_strdup:
  * @str: string pointer
  *
- * Allocates and duplicates sring
+ * Allocates and duplicates string
  *
  * Returns: a newly allocated string
  **/
@@ -153,7 +153,7 @@
  * @str: string pointer
  * @max: Maximum number of characters to copy
  *
- * Allocates and duplicates sring.  If the string is longer than @max
+ * Allocates and duplicates string.  If the string is longer than @max
  * characters, only @max are copied and a null terminating character
  * is added.
  *
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/ell/util.h new/iwd-2.14/ell/util.h
--- old/iwd-2.13/ell/util.h     2023-11-19 18:31:06.000000000 +0100
+++ new/iwd-2.14/ell/util.h     2024-02-06 18:44:14.000000000 +0100
@@ -14,6 +14,8 @@
 #include <inttypes.h>
 #include <endian.h>
 #include <byteswap.h>
+#include <unistd.h>
+#include <errno.h>
 #include <sys/uio.h>
 #include <ell/cleanup.h>
 
@@ -314,6 +316,15 @@
        while (__result == -1L && errno == EINTR);  \
        __result; }))
 
+/* Enables declaring _auto_(close) int fd = <-1 or L_TFR(open(...))>; */
+inline __attribute__((always_inline)) void _l_close_cleanup(void *p)
+{
+       int fd = *(int *) p;
+
+       if (fd >= 0)
+               L_TFR(close(fd));
+}
+
 #define _L_IN_SET_CMP(val, type, cmp, ...) __extension__ ({            \
                const type __v = (val);                                 \
                const typeof(__v) __elems[] = {__VA_ARGS__};            \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/src/eapol.c new/iwd-2.14/src/eapol.c
--- old/iwd-2.13/src/eapol.c    2023-12-14 00:02:54.000000000 +0100
+++ new/iwd-2.14/src/eapol.c    2024-02-09 22:15:09.000000000 +0100
@@ -2092,6 +2092,10 @@
        if (L_BE64_TO_CPU(ek->key_replay_counter) != sm->replay_counter)
                return;
 
+       /* Ensure we received Message 2 and thus have a PTK to verify MIC */
+       if (!sm->handshake->have_snonce)
+               return;
+
        kck = handshake_state_get_kck(sm->handshake);
 
        if (!eapol_verify_mic(sm->handshake->akm_suite, kck, ek,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/src/knownnetworks.c 
new/iwd-2.14/src/knownnetworks.c
--- old/iwd-2.13/src/knownnetworks.c    2023-12-27 13:34:15.000000000 +0100
+++ new/iwd-2.14/src/knownnetworks.c    2024-02-09 22:15:09.000000000 +0100
@@ -517,8 +517,23 @@
        return l_queue_find(known_networks, network_info_match, &query);
 }
 
+static void known_network_append_frequencies(const struct network_info *info,
+                                               struct scan_freq_set *set,
+                                               uint8_t max)
+{
+       const struct l_queue_entry *entry;
+
+       for (entry = l_queue_get_entries(info->known_frequencies); entry && max;
+                                       entry = entry->next, max--) {
+               const struct known_frequency *known_freq = entry->data;
+
+               scan_freq_set_add(set, known_freq->frequency);
+       }
+}
+
 struct scan_freq_set *known_networks_get_recent_frequencies(
-                                               uint8_t num_networks_tosearch)
+                                               uint8_t num_networks_tosearch,
+                                               uint8_t freqs_per_network)
 {
        /*
         * This search function assumes that the known networks are always
@@ -527,10 +542,9 @@
         * list.
         */
        const struct l_queue_entry *network_entry;
-       const struct l_queue_entry *freq_entry;
        struct scan_freq_set *set;
 
-       if (!num_networks_tosearch)
+       if (!num_networks_tosearch || !freqs_per_network)
                return NULL;
 
        set = scan_freq_set_new();
@@ -541,14 +555,8 @@
                                                num_networks_tosearch--) {
                const struct network_info *network = network_entry->data;
 
-               for (freq_entry = l_queue_get_entries(
-                                               network->known_frequencies);
-                               freq_entry; freq_entry = freq_entry->next) {
-                       const struct known_frequency *known_freq =
-                                                       freq_entry->data;
-
-                       scan_freq_set_add(set, known_freq->frequency);
-               }
+               known_network_append_frequencies(network, set,
+                                                       freqs_per_network);
        }
 
        return set;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/src/knownnetworks.h 
new/iwd-2.14/src/knownnetworks.h
--- old/iwd-2.13/src/knownnetworks.h    2023-12-27 13:34:15.000000000 +0100
+++ new/iwd-2.14/src/knownnetworks.h    2024-02-09 22:15:09.000000000 +0100
@@ -113,8 +113,10 @@
                                                enum security security);
 
 struct scan_freq_set *known_networks_get_recent_frequencies(
-                                               uint8_t num_networks_tosearch);
-int known_network_add_frequency(struct network_info *info, uint32_t frequency);
+                                               uint8_t num_networks_tosearch,
+                                               uint8_t freqs_per_network);
+int known_network_add_frequency(struct network_info *info,
+                               uint32_t frequency);
 void known_network_frequency_sync(struct network_info *info);
 
 uint32_t known_networks_watch_add(known_networks_watch_func_t func,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/src/netconfig.c new/iwd-2.14/src/netconfig.c
--- old/iwd-2.13/src/netconfig.c        2023-01-23 19:46:38.000000000 +0100
+++ new/iwd-2.14/src/netconfig.c        2024-02-09 22:15:09.000000000 +0100
@@ -50,6 +50,8 @@
 #include "src/netconfig.h"
 #include "src/sysfs.h"
 
+#define DHCP_ATTEMPTS 4
+
 /*
  * Routing priority offset, configurable in main.conf. The route with lower
  * priority offset is preferred.
@@ -696,6 +698,7 @@
        int dhcp_priority = L_LOG_INFO;
        struct l_dhcp6_client *dhcp6;
        struct l_icmp6_client *icmp6;
+       struct l_dhcp_client *dhcp;
 
        l_debug("Creating netconfig for interface: %d", ifindex);
 
@@ -723,8 +726,8 @@
        l_netconfig_set_event_handler(netconfig->nc, netconfig_event_handler,
                                        netconfig, NULL);
 
-       l_dhcp_client_set_debug(l_netconfig_get_dhcp_client(netconfig->nc),
-                               do_debug, "[DHCPv4] ", NULL, dhcp_priority);
+       dhcp = l_netconfig_get_dhcp_client(netconfig->nc);
+       l_dhcp_client_set_max_attempts(dhcp, DHCP_ATTEMPTS);
 
        dhcp6 = l_netconfig_get_dhcp6_client(netconfig->nc);
        l_dhcp6_client_set_lla_randomized(dhcp6, true);
@@ -735,6 +738,8 @@
        if (debug_level) {
                l_dhcp6_client_set_debug(dhcp6, do_debug, "[DHCPv6] ", NULL);
                l_icmp6_client_set_debug(icmp6, do_debug, "[ICMPv6] ", NULL);
+               l_dhcp_client_set_debug(dhcp, do_debug, "[DHCPv4] ", NULL,
+                                       dhcp_priority);
        }
 
        return netconfig;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/src/netdev.c new/iwd-2.14/src/netdev.c
--- old/iwd-2.13/src/netdev.c   2023-12-14 00:02:54.000000000 +0100
+++ new/iwd-2.14/src/netdev.c   2024-02-09 22:15:09.000000000 +0100
@@ -4734,7 +4734,7 @@
        uint16_t type;
        uint16_t len;
        const void *data;
-       uint8_t reason_code;
+       uint16_t reason_code;
 
        if (!netdev->connected)
                return;
@@ -4762,7 +4762,8 @@
 
        reason_code = l_get_le16(mmpdu_body(hdr));
 
-       l_info("disconnect event, src="MAC" dest="MAC" bssid="MAC" reason=%u",
+       l_info("unprotected disconnect event, src="MAC" dest="MAC
+                        " bssid="MAC" reason=%u",
                        MAC_STR(hdr->address_2), MAC_STR(hdr->address_1),
                        MAC_STR(hdr->address_3), reason_code);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/src/network.c new/iwd-2.14/src/network.c
--- old/iwd-2.13/src/network.c  2023-12-27 13:34:15.000000000 +0100
+++ new/iwd-2.14/src/network.c  2024-02-09 22:15:09.000000000 +0100
@@ -802,21 +802,13 @@
        return network->info;
 }
 
-static void add_known_frequency(void *data, void *user_data)
-{
-       struct scan_bss *bss = data;
-       struct network_info *info = user_data;
-
-       known_network_add_frequency(info, bss->frequency);
-}
-
 void network_set_info(struct network *network, struct network_info *info)
 {
        if (info) {
                network->info = info;
                network->info->seen_count++;
 
-               l_queue_foreach(network->bss_list, add_known_frequency, info);
+               network_update_known_frequencies(network);
        } else {
                network->info->seen_count--;
                network->info = NULL;
@@ -1087,15 +1079,39 @@
        return true;
 }
 
+bool network_update_known_frequencies(struct network *network)
+{
+       const struct l_queue_entry *e;
+       struct l_queue *reversed;
+
+       if (!network->info)
+               return false;
+
+       reversed = l_queue_new();
+
+       for (e = l_queue_get_entries(network->bss_list); e; e = e->next) {
+               struct scan_bss *bss = e->data;
+
+               l_queue_push_head(reversed, bss);
+       }
+
+       for (e = l_queue_get_entries(reversed); e; e = e->next) {
+               struct scan_bss *bss = e->data;
+
+               known_network_add_frequency(network->info, bss->frequency);
+       }
+
+       l_queue_destroy(reversed, NULL);
+
+       return true;
+}
+
 bool network_bss_add(struct network *network, struct scan_bss *bss)
 {
        if (!l_queue_insert(network->bss_list, bss, scan_bss_rank_compare,
                                                                        NULL))
                return false;
 
-       if (network->info)
-               known_network_add_frequency(network->info, bss->frequency);
-
        /* Done if BSS is not HS20 or we already have network_info set */
        if (!bss->hs20_capable)
                return true;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/src/network.h new/iwd-2.14/src/network.h
--- old/iwd-2.13/src/network.h  2022-09-07 20:42:27.000000000 +0200
+++ new/iwd-2.14/src/network.h  2024-02-09 22:15:09.000000000 +0100
@@ -61,6 +61,8 @@
 void network_set_force_default_owe_group(struct network *network);
 bool network_get_force_default_owe_group(struct network *network);
 
+bool network_update_known_frequencies(struct network *network);
+
 int network_can_connect_bss(struct network *network,
                                                const struct scan_bss *bss);
 int network_autoconnect(struct network *network, struct scan_bss *bss);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/iwd-2.13/src/station.c new/iwd-2.14/src/station.c
--- old/iwd-2.13/src/station.c  2024-01-12 20:08:50.000000000 +0100
+++ new/iwd-2.14/src/station.c  2024-02-09 22:15:09.000000000 +0100
@@ -64,6 +64,9 @@
 #include "src/eap-tls-common.h"
 #include "src/storage.h"
 
+#define STATION_RECENT_NETWORK_LIMIT   5
+#define STATION_RECENT_FREQS_LIMIT     5
+
 static struct l_queue *station_list;
 static uint32_t netdev_watch;
 static uint32_t mfp_setting;
@@ -350,6 +353,8 @@
                l_queue_insert(station->networks_sorted, network,
                                network_rank_compare, NULL);
 
+               network_update_known_frequencies(network);
+
                return false;
        }
 
@@ -799,6 +804,8 @@
                scan_bss_free(bss);
        }
 
+       network_update_known_frequencies(network);
+
        l_queue_destroy(bss_list, NULL);
 
 done:
@@ -1434,7 +1441,9 @@
                return -EAGAIN;
        }
 
-       known_freq_set = known_networks_get_recent_frequencies(5);
+       known_freq_set = known_networks_get_recent_frequencies(
+                                               STATION_RECENT_NETWORK_LIMIT,
+                                               STATION_RECENT_FREQS_LIMIT);
        if (!known_freq_set)
                return -ENODATA;
 
@@ -2627,6 +2636,12 @@
                util_address_to_string(current_bss->addr),
                util_ssid_to_utf8(current_bss->ssid_len, current_bss->ssid));
 
+       /*
+        * Reverse now so the known frequency list gets updated in the correct
+        * order (via network_bss_update).
+        */
+       l_queue_reverse(bss_list);
+
        while ((bss = l_queue_pop_head(bss_list))) {
                double rank;
                uint32_t kbps100 = DIV_ROUND_CLOSEST(bss->data_rate, 100000);
@@ -2757,7 +2772,8 @@
        const struct network_info *info = network_get_info(
                                                station->connected_network);
        struct scan_freq_set *freqs = network_info_get_roam_frequencies(info,
-                                       station->connected_bss->frequency, 5);
+                                       station->connected_bss->frequency,
+                                       STATION_RECENT_FREQS_LIMIT);
        int r = -ENODATA;
 
        if (!freqs)
@@ -3684,6 +3700,8 @@
                return true;
        }
 
+       network_update_known_frequencies(network_psk ?: network_open);
+
        error = network_connect_new_hidden_network(network_psk ?: network_open,
                                                        msg);
 

Reply via email to