Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package iwd for openSUSE:Factory checked in at 2021-11-27 00:51:29 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/iwd (Old) and /work/SRC/openSUSE:Factory/.iwd.new.1895 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "iwd" Sat Nov 27 00:51:29 2021 rev:24 rq:933999 version:1.20 Changes: -------- --- /work/SRC/openSUSE:Factory/iwd/iwd.changes 2021-11-08 17:25:14.492734968 +0100 +++ /work/SRC/openSUSE:Factory/.iwd.new.1895/iwd.changes 2021-11-27 00:52:19.766593853 +0100 @@ -1,0 +2,8 @@ +Fri Nov 26 07:34:37 UTC 2021 - Malte Ohmstede <malte.ohmst...@gmail.com> + +- update to v1.20 + * Fix issue with handling Hotspot 2.0 requirements. + * Add support for evict_nocarrier setting during roaming. + * Add support for experimental NetworkConfigurationAgent API. + +------------------------------------------------------------------- Old: ---- iwd-1.19.tar.sign iwd-1.19.tar.xz New: ---- iwd-1.20.tar.sign iwd-1.20.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ iwd.spec ++++++ --- /var/tmp/diff_new_pack.kcugFk/_old 2021-11-27 00:52:20.246592195 +0100 +++ /var/tmp/diff_new_pack.kcugFk/_new 2021-11-27 00:52:20.250592181 +0100 @@ -17,7 +17,7 @@ Name: iwd -Version: 1.19 +Version: 1.20 Release: 0 Summary: Wireless daemon for Linux License: LGPL-2.1-or-later @@ -33,7 +33,7 @@ BuildRequires: readline-devel BuildRequires: systemd-rpm-macros BuildRequires: pkgconfig(dbus-1) -BuildRequires: pkgconfig(ell) >= 0.45 +BuildRequires: pkgconfig(ell) >= 0.46 BuildRequires: pkgconfig(systemd) %{?systemd_ordering} ++++++ iwd-1.19.tar.xz -> iwd-1.20.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iwd-1.19/AUTHORS new/iwd-1.20/AUTHORS --- old/iwd-1.19/AUTHORS 2021-08-22 06:20:36.000000000 +0200 +++ new/iwd-1.20/AUTHORS 2021-11-18 21:21:21.000000000 +0100 @@ -31,3 +31,5 @@ Joseph Benden <j...@benden.us> Michael Johnson <mjohnson...@gmail.com> Matt Oberle <matt.r.obe...@gmail.com> +Marc-Antoine Perennou <marc-anto...@perennou.com> +Torsten Schmitz <noreply.tors...@gmail.com> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iwd-1.19/ChangeLog new/iwd-1.20/ChangeLog --- old/iwd-1.19/ChangeLog 2021-11-02 19:50:50.000000000 +0100 +++ new/iwd-1.20/ChangeLog 2021-11-18 21:21:21.000000000 +0100 @@ -1,3 +1,8 @@ +ver 1.20: + Fix issue with handling Hotspot 2.0 requirements. + Add support for evict_nocarrier setting during roaming. + Add support for experimental NetworkConfigurationAgent API. + ver 1.19: Fix issue with handling OCV if offloading is supported. Fix issue with handling SA Query on channel switch event. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iwd-1.19/Makefile.am new/iwd-1.20/Makefile.am --- old/iwd-1.19/Makefile.am 2021-11-02 19:50:50.000000000 +0100 +++ new/iwd-1.20/Makefile.am 2021-11-18 21:21:21.000000000 +0100 @@ -246,6 +246,7 @@ src/diagnostic.h src/diagnostic.c \ src/ip-pool.h src/ip-pool.c \ src/band.h src/band.c \ + src/sysfs.h src/sysfs.c \ $(eap_sources) \ $(builtin_sources) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iwd-1.19/Makefile.in new/iwd-1.20/Makefile.in --- old/iwd-1.19/Makefile.in 2021-11-02 19:52:37.000000000 +0100 +++ new/iwd-1.20/Makefile.in 2021-11-18 21:23:10.000000000 +0100 @@ -300,14 +300,15 @@ src/module.c src/rrm.c src/frame-xchg.h src/frame-xchg.c \ src/eap-wsc.c src/eap-wsc.h src/wscutil.h src/wscutil.c \ src/diagnostic.h src/diagnostic.c src/ip-pool.h src/ip-pool.c \ - src/band.h src/band.c src/eap.c src/eap.h src/eap-private.h \ - src/eap-md5.c src/eap-tls.c src/eap-ttls.c src/eap-mschapv2.c \ - src/eap-mschapv2.h src/eap-sim.c src/eap-aka.c src/eap-peap.c \ - src/eap-gtc.c src/eap-pwd.c src/util.h src/util.c src/crypto.h \ - src/crypto.c src/simutil.h src/simutil.c src/simauth.h \ - src/simauth.c src/watchlist.h src/watchlist.c \ - src/eap-tls-common.h src/eap-tls-common.c src/mschaputil.h \ - src/mschaputil.c src/ofono.c + src/band.h src/band.c src/sysfs.h src/sysfs.c src/eap.c \ + src/eap.h src/eap-private.h src/eap-md5.c src/eap-tls.c \ + src/eap-ttls.c src/eap-mschapv2.c src/eap-mschapv2.h \ + src/eap-sim.c src/eap-aka.c src/eap-peap.c src/eap-gtc.c \ + src/eap-pwd.c src/util.h src/util.c src/crypto.h src/crypto.c \ + src/simutil.h src/simutil.c src/simauth.h src/simauth.c \ + src/watchlist.h src/watchlist.c src/eap-tls-common.h \ + src/eap-tls-common.c src/mschaputil.h src/mschaputil.c \ + src/ofono.c am__objects_3 = src/eap.$(OBJEXT) src/eap-md5.$(OBJEXT) \ src/eap-tls.$(OBJEXT) src/eap-ttls.$(OBJEXT) \ src/eap-mschapv2.$(OBJEXT) src/eap-sim.$(OBJEXT) \ @@ -342,8 +343,8 @@ @DAEMON_TRUE@ src/rrm.$(OBJEXT) src/frame-xchg.$(OBJEXT) \ @DAEMON_TRUE@ src/eap-wsc.$(OBJEXT) src/wscutil.$(OBJEXT) \ @DAEMON_TRUE@ src/diagnostic.$(OBJEXT) src/ip-pool.$(OBJEXT) \ -@DAEMON_TRUE@ src/band.$(OBJEXT) $(am__objects_3) \ -@DAEMON_TRUE@ $(am__objects_5) +@DAEMON_TRUE@ src/band.$(OBJEXT) src/sysfs.$(OBJEXT) \ +@DAEMON_TRUE@ $(am__objects_3) $(am__objects_5) src_iwd_OBJECTS = $(am_src_iwd_OBJECTS) am__tools_hwsim_SOURCES_DIST = tools/hwsim.c src/mpdu.h src/util.h \ src/util.c src/storage.h src/storage.c src/common.h \ @@ -573,12 +574,13 @@ src/$(DEPDIR)/sae.Po src/$(DEPDIR)/scan.Po \ src/$(DEPDIR)/simauth.Po src/$(DEPDIR)/simutil.Po \ src/$(DEPDIR)/station.Po src/$(DEPDIR)/storage.Po \ - src/$(DEPDIR)/util.Po src/$(DEPDIR)/watchlist.Po \ - src/$(DEPDIR)/wiphy.Po src/$(DEPDIR)/wsc.Po \ - src/$(DEPDIR)/wscutil.Po tools/$(DEPDIR)/hwsim.Po \ - tools/$(DEPDIR)/probe-req.Po unit/$(DEPDIR)/test-arc4.Po \ - unit/$(DEPDIR)/test-band.Po unit/$(DEPDIR)/test-client.Po \ - unit/$(DEPDIR)/test-cmac-aes.Po unit/$(DEPDIR)/test-crypto.Po \ + src/$(DEPDIR)/sysfs.Po src/$(DEPDIR)/util.Po \ + src/$(DEPDIR)/watchlist.Po src/$(DEPDIR)/wiphy.Po \ + src/$(DEPDIR)/wsc.Po src/$(DEPDIR)/wscutil.Po \ + tools/$(DEPDIR)/hwsim.Po tools/$(DEPDIR)/probe-req.Po \ + unit/$(DEPDIR)/test-arc4.Po unit/$(DEPDIR)/test-band.Po \ + unit/$(DEPDIR)/test-client.Po unit/$(DEPDIR)/test-cmac-aes.Po \ + unit/$(DEPDIR)/test-crypto.Po \ unit/$(DEPDIR)/test-eap-mschapv2.Po \ unit/$(DEPDIR)/test-eap-sim.Po unit/$(DEPDIR)/test-eapol.Po \ unit/$(DEPDIR)/test-hmac-md5.Po \ @@ -1266,6 +1268,7 @@ @DAEMON_TRUE@ src/diagnostic.h src/diagnostic.c \ @DAEMON_TRUE@ src/ip-pool.h src/ip-pool.c \ @DAEMON_TRUE@ src/band.h src/band.c \ +@DAEMON_TRUE@ src/sysfs.h src/sysfs.c \ @DAEMON_TRUE@ $(eap_sources) \ @DAEMON_TRUE@ $(builtin_sources) @@ -1894,6 +1897,7 @@ src/ip-pool.$(OBJEXT): src/$(am__dirstamp) \ src/$(DEPDIR)/$(am__dirstamp) src/band.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) +src/sysfs.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) src/eap.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp) src/eap-md5.$(OBJEXT): src/$(am__dirstamp) \ src/$(DEPDIR)/$(am__dirstamp) @@ -2243,6 +2247,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/simutil.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/station.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/storage.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/sysfs.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/util.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/watchlist.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/wiphy.Po@am__quote@ # am--include-marker @@ -3334,6 +3339,7 @@ -rm -f src/$(DEPDIR)/simutil.Po -rm -f src/$(DEPDIR)/station.Po -rm -f src/$(DEPDIR)/storage.Po + -rm -f src/$(DEPDIR)/sysfs.Po -rm -f src/$(DEPDIR)/util.Po -rm -f src/$(DEPDIR)/watchlist.Po -rm -f src/$(DEPDIR)/wiphy.Po @@ -3555,6 +3561,7 @@ -rm -f src/$(DEPDIR)/simutil.Po -rm -f src/$(DEPDIR)/station.Po -rm -f src/$(DEPDIR)/storage.Po + -rm -f src/$(DEPDIR)/sysfs.Po -rm -f src/$(DEPDIR)/util.Po -rm -f src/$(DEPDIR)/watchlist.Po -rm -f src/$(DEPDIR)/wiphy.Po diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iwd-1.19/client/command.h new/iwd-1.20/client/command.h --- old/iwd-1.19/client/command.h 2019-10-30 11:50:34.000000000 +0100 +++ new/iwd-1.20/client/command.h 2021-11-18 21:21:21.000000000 +0100 @@ -83,10 +83,14 @@ } __attribute__((aligned(8))); #define COMMAND_FAMILY(name, init, exit) \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wattributes\"") \ static struct command_family_desc __command_family_ ## name \ - __attribute__((used, section("__command"), aligned(8))) = {\ + __attribute__((used, retain, \ + section("__command"), aligned(8))) = { \ #name, init, exit \ }; \ + _Pragma("GCC diagnostic pop") bool command_init(char **argv, int argc); void command_exit(void); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iwd-1.19/client/dbus-proxy.c new/iwd-1.20/client/dbus-proxy.c --- old/iwd-1.19/client/dbus-proxy.c 2020-03-25 10:37:15.000000000 +0100 +++ new/iwd-1.20/client/dbus-proxy.c 2021-11-18 21:21:21.000000000 +0100 @@ -315,7 +315,8 @@ } proxy = callback_data->user_data; - if (!strcmp(proxy->type->interface, IWD_AGENT_MANAGER_INTERFACE)) + if (!strcmp(proxy->type->interface, IWD_AGENT_MANAGER_INTERFACE) || + !strcmp(proxy->type->interface, IWD_DAEMON_INTERFACE)) return; quit: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iwd-1.19/client/dbus-proxy.h new/iwd-1.20/client/dbus-proxy.h --- old/iwd-1.19/client/dbus-proxy.h 2021-11-02 19:50:50.000000000 +0100 +++ new/iwd-1.20/client/dbus-proxy.h 2021-11-18 21:21:21.000000000 +0100 @@ -118,10 +118,14 @@ } __attribute__((aligned(8))); #define INTERFACE_TYPE(interface, init, exit) \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wattributes\"") \ static struct interface_type_desc __interface_type_ ## interface\ - __attribute__((used, section("__interface"), aligned(8))) = {\ + __attribute__((used, retain, section("__interface"), \ + aligned(8))) = { \ #interface, init, exit \ }; \ + _Pragma("GCC diagnostic pop") bool dbus_proxy_init(void); bool dbus_proxy_exit(void); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iwd-1.19/configure new/iwd-1.20/configure --- old/iwd-1.19/configure 2021-11-02 19:52:30.000000000 +0100 +++ new/iwd-1.20/configure 2021-11-18 21:23:04.000000000 +0100 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for iwd 1.19. +# Generated by GNU Autoconf 2.69 for iwd 1.20. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -587,8 +587,8 @@ # Identity of this package. PACKAGE_NAME='iwd' PACKAGE_TARNAME='iwd' -PACKAGE_VERSION='1.19' -PACKAGE_STRING='iwd 1.19' +PACKAGE_VERSION='1.20' +PACKAGE_STRING='iwd 1.20' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1394,7 +1394,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 1.19 to adapt to many kinds of systems. +\`configure' configures iwd 1.20 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1465,7 +1465,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of iwd 1.19:";; + short | recursive ) echo "Configuration of iwd 1.20:";; esac cat <<\_ACEOF @@ -1616,7 +1616,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -iwd configure 1.19 +iwd configure 1.20 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1981,7 +1981,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 1.19, which was +It was created by iwd $as_me 1.20, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2844,7 +2844,7 @@ # Define the identity of the package. PACKAGE='iwd' - VERSION='1.19' + VERSION='1.20' cat >>confdefs.h <<_ACEOF @@ -13349,7 +13349,7 @@ test "${enable_monitor}" != "no" || test "${enable_wired}" = "yes" || test "${enable_hwsim}" = "yes"); then - ell_min_version="0.45" + ell_min_version="0.46" else ell_min_version="0.5" fi @@ -14078,7 +14078,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 1.19, which was +This file was extended by iwd $as_me 1.20, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -14144,7 +14144,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -iwd config.status 1.19 +iwd config.status 1.20 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iwd-1.19/configure.ac new/iwd-1.20/configure.ac --- old/iwd-1.19/configure.ac 2021-11-02 19:50:50.000000000 +0100 +++ new/iwd-1.20/configure.ac 2021-11-18 21:21:21.000000000 +0100 @@ -1,5 +1,5 @@ AC_PREREQ(2.60) -AC_INIT(iwd, 1.19) +AC_INIT(iwd, 1.20) AC_CONFIG_HEADERS(config.h) AC_CONFIG_AUX_DIR(build-aux) @@ -263,7 +263,7 @@ test "${enable_monitor}" != "no" || test "${enable_wired}" = "yes" || test "${enable_hwsim}" = "yes"); then - ell_min_version="0.45" + ell_min_version="0.46" else ell_min_version="0.5" fi diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iwd-1.19/ell/dhcp-server.c new/iwd-1.20/ell/dhcp-server.c --- old/iwd-1.19/ell/dhcp-server.c 2021-09-14 21:48:51.000000000 +0200 +++ new/iwd-1.20/ell/dhcp-server.c 2021-11-18 20:53:14.000000000 +0100 @@ -1032,10 +1032,6 @@ server->address = ia.s_addr; } - /* Assign a default gateway if not already set */ - if (!server->gateway) - server->gateway = server->address; - /* Assign a default netmask if not already */ if (!server->netmask) { if (inet_pton(AF_INET,"255.255.255.0", &ia) != 1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iwd-1.19/ell/dhcp6.c new/iwd-1.20/ell/dhcp6.c --- old/iwd-1.19/ell/dhcp6.c 2021-03-29 14:19:13.000000000 +0200 +++ new/iwd-1.20/ell/dhcp6.c 2021-11-18 20:53:14.000000000 +0100 @@ -850,6 +850,14 @@ client->event_handler(client, event, client->event_data); } +static void dhcp6_client_enter_state(struct l_dhcp6_client *client, + enum dhcp6_state new_state) +{ + client->state = new_state; + l_util_debug(client->debug_handler, client->debug_data, + "Entering state: %s", dhcp6_state_to_str(new_state)); +} + static inline void dhcp6_client_new_transaction(struct l_dhcp6_client *client, enum dhcp6_state new_state) { @@ -858,9 +866,7 @@ client->transaction_id = l_getrandom_uint32() & 0x00FFFFFFU; client->transaction_start_t = 0; - client->state = new_state; - l_util_debug(client->debug_handler, client->debug_data, - "Entering state: %s", dhcp6_state_to_str(new_state)); + dhcp6_client_enter_state(client, new_state); } static void dhcp6_client_timeout_send(struct l_timeout *timeout, @@ -960,21 +966,27 @@ { uint32_t t1 = _dhcp6_lease_get_t1(client->lease); uint32_t t2 = _dhcp6_lease_get_t2(client->lease); + enum l_dhcp6_client_event event; client->lease_start_t = l_time_now(); /* TODO: Emit IP_CHANGED if any addresses were removed / added */ if (client->state == DHCP6_STATE_REQUESTING || client->state == DHCP6_STATE_SOLICITING) - dhcp6_client_event_notify(client, - L_DHCP6_CLIENT_EVENT_LEASE_OBTAINED); + event = L_DHCP6_CLIENT_EVENT_LEASE_OBTAINED; else - dhcp6_client_event_notify(client, - L_DHCP6_CLIENT_EVENT_LEASE_RENEWED); + event = L_DHCP6_CLIENT_EVENT_LEASE_RENEWED; l_timeout_remove(client->timeout_lease); client->timeout_lease = NULL; + /* + * Switch over to BOUND state so that l_dhcp6_client_get_lease() will + * return the lease properly + */ + dhcp6_client_enter_state(client, DHCP6_STATE_BOUND); + dhcp6_client_event_notify(client, event); + if (t1 == 0xffffffff || t2 == 0xffffffff) { CLIENT_DEBUG("T1 (%u) or T2 (%u) was infinite", t1, t2); return; @@ -1402,7 +1414,6 @@ l_timeout_remove(client->timeout_send); client->timeout_send = NULL; dhcp6_client_setup_lease(client); - dhcp6_client_new_transaction(client, r); return; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iwd-1.19/ell/log.h new/iwd-1.20/ell/log.h --- old/iwd-1.19/ell/log.h 2020-09-05 09:26:19.000000000 +0200 +++ new/iwd-1.20/ell/log.h 2021-11-18 20:53:14.000000000 +0100 @@ -61,12 +61,20 @@ unsigned int flags; } __attribute__((aligned(8))); +/* + * Set the retain attribute so that the section cannot be discarded by ld + * --gc-sections -z start-stop-gc. Older compilers would warn for the unknown + * attribute, so just disable -Wattributes. + */ #define L_DEBUG_SYMBOL(symbol, format, ...) do { \ +_Pragma("GCC diagnostic push") \ +_Pragma("GCC diagnostic ignored \"-Wattributes\"") \ static struct l_debug_desc symbol \ - __attribute__((used, section("__ell_debug"), aligned(8))) = { \ + __attribute__((used, retain, section("__ell_debug"), aligned(8))) = { \ .file = __FILE__, .func = __func__, \ .flags = L_DEBUG_FLAG_DEFAULT, \ }; \ +_Pragma("GCC diagnostic pop") \ if (symbol.flags & L_DEBUG_FLAG_PRINT) \ l_log(L_LOG_DEBUG, "%s:%s() " format, __FILE__, \ __func__ , ##__VA_ARGS__); \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iwd-1.19/src/anqp.c new/iwd-1.20/src/anqp.c --- old/iwd-1.19/src/anqp.c 2021-08-22 06:20:37.000000000 +0200 +++ new/iwd-1.20/src/anqp.c 2021-11-18 21:21:21.000000000 +0100 @@ -256,7 +256,7 @@ &anqp_frame_prefix, anqp_response_frame_event, NULL); - return true; + return request->id; } void anqp_cancel(uint32_t id) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iwd-1.19/src/ap.c new/iwd-1.20/src/ap.c --- old/iwd-1.19/src/ap.c 2021-11-02 19:50:50.000000000 +0100 +++ new/iwd-1.20/src/ap.c 2021-11-18 21:21:21.000000000 +0100 @@ -101,6 +101,8 @@ bool started : 1; bool gtk_set : 1; bool netconfig_set_addr4 : 1; + bool in_event : 1; + bool free_pending : 1; }; struct sta_state { @@ -250,6 +252,35 @@ } } +static bool ap_event_done(struct ap_state *ap, bool prev_in_event) +{ + ap->in_event = prev_in_event; + + if (!prev_in_event && ap->free_pending) { + ap_free(ap); + return true; + } + + return ap->free_pending; +} + +/* + * Returns true if the AP is considered freed and the caller must avoid + * accessing @ap. + */ +static bool ap_event(struct ap_state *ap, enum ap_event_type event, + const void *event_data) +{ + bool prev = ap->in_event; + + if (ap->free_pending) + return true; + + ap->in_event = true; + ap->ops->handle_event(event, event_data, ap->user_data); + return ap_event_done(ap, prev); +} + static void ap_del_station(struct sta_state *sta, uint16_t reason, bool disassociate) { @@ -284,23 +315,34 @@ ap_stop_handshake(sta); /* + * If the event handler tears the AP down, we've made sure above that + * a subsequent ap_sta_free(sta) has no need to access sta->ap. + */ + if (send_event) + if (ap_event(ap, AP_EVENT_STATION_REMOVED, &event_data)) + return; + + /* * Expire any DHCP leases owned by this client when it disconnects to * make it harder for somebody to DoS the IP pool. If the client * comes back and the lease is still in the expired leases list they * will get their IP back. */ if (ap->netconfig_dhcp) { + bool prev = ap->in_event; + + /* + * If the LEASE_EXPIRED event in ap_dhcp_event_cb triggers an + * ap_free(), delay cleanup to avoid destroying the DHCP + * server midway through l_dhcp_server_expire_by_mac(). + */ + ap->in_event = true; + sta->ip_alloc_lease = NULL; l_dhcp_server_expire_by_mac(ap->netconfig_dhcp, sta->addr); - } - /* - * If the event handler tears the AP down, we've made sure above that - * a subsequent ap_sta_free(sta) has no need to access sta->ap. - */ - if (send_event) - ap->ops->handle_event(AP_EVENT_STATION_REMOVED, &event_data, - ap->user_data); + ap_event_done(ap, prev); + } } static bool ap_sta_match_addr(const void *a, const void *b) @@ -335,19 +377,16 @@ static void ap_new_rsna(struct sta_state *sta) { struct ap_state *ap = sta->ap; + struct ap_event_station_added_data event_data = {}; l_debug("STA "MAC" authenticated", MAC_STR(sta->addr)); sta->rsna = true; - if (ap->ops->handle_event) { - struct ap_event_station_added_data event_data = {}; - event_data.mac = sta->addr; - event_data.assoc_ies = sta->assoc_ies; - event_data.assoc_ies_len = sta->assoc_ies_len; - ap->ops->handle_event(AP_EVENT_STATION_ADDED, &event_data, - ap->user_data); - } + event_data.mac = sta->addr; + event_data.assoc_ies = sta->assoc_ies; + event_data.assoc_ies_len = sta->assoc_ies_len; + ap_event(ap, AP_EVENT_STATION_ADDED, &event_data); } static void ap_drop_rsna(struct sta_state *sta) @@ -356,6 +395,7 @@ struct l_genl_msg *msg; uint32_t ifindex = netdev_get_ifindex(sta->ap->netdev); uint8_t key_id = 0; + struct ap_event_station_removed_data event_data = {}; sta->rsna = false; @@ -380,12 +420,8 @@ ap_stop_handshake(sta); - if (ap->ops->handle_event) { - struct ap_event_station_removed_data event_data = {}; - event_data.mac = sta->addr; - ap->ops->handle_event(AP_EVENT_STATION_REMOVED, &event_data, - ap->user_data); - } + event_data.mac = sta->addr; + ap_event(ap, AP_EVENT_STATION_REMOVED, &event_data); } static void ap_set_rsn_info(struct ap_state *ap, struct ie_rsn_info *rsn) @@ -405,7 +441,7 @@ ap->wsc_dpid = 0; ap_update_beacon(ap); - ap->ops->handle_event(AP_EVENT_PBC_MODE_EXIT, NULL, ap->user_data); + ap_event(ap, AP_EVENT_PBC_MODE_EXIT, NULL); } struct ap_pbc_record_expiry_data { @@ -1090,9 +1126,7 @@ &expiry_data); event_data.mac = sta->addr; - sta->ap->ops->handle_event(AP_EVENT_REGISTRATION_SUCCESS, - &event_data, - sta->ap->user_data); + ap_event(sta->ap, AP_EVENT_REGISTRATION_SUCCESS, &event_data); break; default: break; @@ -1594,11 +1628,11 @@ const char *ssid = NULL; const uint8_t *rsn = NULL; size_t ssid_len = 0; - struct l_uintset *rates = NULL; + _auto_(l_uintset_free) struct l_uintset *rates = NULL; struct ie_rsn_info rsn_info; int err; struct ie_tlv_iter iter; - uint8_t *wsc_data = NULL; + _auto_(l_free) uint8_t *wsc_data = NULL; ssize_t wsc_data_len; bool fils_ip_req = false; struct ie_fils_ip_addr_request_info fils_ip_req_info; @@ -1685,9 +1719,6 @@ goto bad_frame; } - l_free(wsc_data); - wsc_data = NULL; - if (wsc_req.request_type != WSC_REQUEST_TYPE_ENROLLEE_OPEN_8021X) { err = MMPDU_REASON_CODE_INVALID_IE; @@ -1728,8 +1759,9 @@ event_data.mac = sta->addr; event_data.assoc_ies = ies; event_data.assoc_ies_len = ies_len; - ap->ops->handle_event(AP_EVENT_REGISTRATION_START, &event_data, - ap->user_data); + + if (ap_event(ap, AP_EVENT_REGISTRATION_START, &event_data)) + return; /* * Since we're starting the PBC Registration Protocol @@ -1781,7 +1813,7 @@ if (sta->rates) l_uintset_free(sta->rates); - sta->rates = rates; + sta->rates = l_steal_ptr(rates); l_free(sta->assoc_ies); @@ -1823,11 +1855,6 @@ else if (sta->associated) ap_stop_handshake(sta); - if (rates) - l_uintset_free(rates); - - l_free(wsc_data); - if (!ap_assoc_resp(ap, sta, sta->addr, err, reassoc, req, (void *) ies + ies_len - (void *) req, NULL, ap_fail_assoc_resp_cb)) @@ -2209,6 +2236,7 @@ { struct ap_event_start_failed_data data = { err }; + ap->in_event = true; ap->ops->handle_event(AP_EVENT_START_FAILED, &data, ap->user_data); ap_reset(ap); l_genl_family_free(ap->nl80211); @@ -2224,13 +2252,11 @@ switch (event) { case L_DHCP_SERVER_EVENT_NEW_LEASE: - ap->ops->handle_event(AP_EVENT_DHCP_NEW_LEASE, lease, - ap->user_data); + ap_event(ap, AP_EVENT_DHCP_NEW_LEASE, lease); break; case L_DHCP_SERVER_EVENT_LEASE_EXPIRED: - ap->ops->handle_event(AP_EVENT_DHCP_LEASE_EXPIRED, lease, - ap->user_data); + ap_event(ap, AP_EVENT_DHCP_LEASE_EXPIRED, lease); break; default: @@ -2267,7 +2293,7 @@ } ap->started = true; - ap->ops->handle_event(AP_EVENT_STARTED, NULL, ap->user_data); + ap_event(ap, AP_EVENT_STARTED, NULL); } static struct l_genl_msg *ap_build_cmd_start_ap(struct ap_state *ap) @@ -2552,6 +2578,8 @@ switch (l_genl_msg_get_command(msg)) { case NL80211_CMD_STOP_AP: + ap->in_event = true; + if (ap->start_stop_cmd_id) { struct ap_event_start_failed_data data = { -ECANCELED }; @@ -3304,7 +3332,9 @@ if (ap->started) { ap->started = false; - ap->ops->handle_event(AP_EVENT_STOPPING, NULL, ap->user_data); + + if (ap_event(ap, AP_EVENT_STOPPING, NULL)) + return; } ap_reset(ap); @@ -3355,6 +3385,11 @@ /* Free @ap without a graceful shutdown */ void ap_free(struct ap_state *ap) { + if (ap->in_event) { + ap->free_pending = true; + return; + } + ap_reset(ap); l_genl_family_free(ap->nl80211); l_free(ap); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iwd-1.19/src/eap-private.h new/iwd-1.20/src/eap-private.h --- old/iwd-1.19/src/eap-private.h 2020-09-05 09:43:41.000000000 +0200 +++ new/iwd-1.20/src/eap-private.h 2021-11-18 21:21:21.000000000 +0100 @@ -94,10 +94,14 @@ } __attribute__((aligned(8))); #define EAP_METHOD_BUILTIN(name, init, exit) \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wattributes\"") \ static struct eap_method_desc __eap_builtin_ ## name \ - __attribute__((used, section("__eap"), aligned(8))) = { \ + __attribute__((used, retain, section("__eap"), \ + aligned(8))) = { \ #name, init, exit \ }; \ + _Pragma("GCC diagnostic pop") int eap_register_method(struct eap_method *method); int eap_unregister_method(struct eap_method *method); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iwd-1.19/src/eap.c new/iwd-1.20/src/eap.c --- old/iwd-1.19/src/eap.c 2021-05-04 15:01:25.000000000 +0200 +++ new/iwd-1.20/src/eap.c 2021-11-18 21:21:21.000000000 +0100 @@ -413,8 +413,14 @@ return buf; } +_Pragma("GCC diagnostic push") +_Pragma("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") #define IS_EXPANDED_RESPONSE(id, t) \ (type == EAP_TYPE_EXPANDED && vendor_id == (id) && vendor_type == (t)) +_Pragma("GCC diagnostic pop") + +#define RESPONSE_IS(t) \ + (type == (t) || IS_EXPANDED_RESPONSE(0, (t))) static void eap_handle_response(struct eap_state *eap, const uint8_t *pkt, size_t len) @@ -428,14 +434,6 @@ eap->method->vendor_id[2]; uint32_t our_vendor_type = eap->method->vendor_type; - bool response_is(enum eap_type wanted) - { - if (type == wanted) - return true; - - return IS_EXPANDED_RESPONSE(0, wanted); - } - if (len < 1) /* Invalid packets to be ignored */ return; @@ -461,7 +459,7 @@ return; } - if (response_is(EAP_TYPE_NAK)) { + if (RESPONSE_IS(EAP_TYPE_NAK)) { l_debug("EAP peer not configured for method: %s", eap_type_to_str(our_type, our_vendor_id, our_vendor_type)); @@ -500,7 +498,7 @@ */ if (!eap->identity) { - if (!response_is(EAP_TYPE_IDENTITY)) + if (!RESPONSE_IS(EAP_TYPE_IDENTITY)) goto unsupported_method; /* @@ -528,7 +526,7 @@ * (with the exception of the Nak) */ if (our_type != EAP_TYPE_EXPANDED) { - if (response_is(our_type)) + if (RESPONSE_IS(our_type)) goto handle_response; } else if (IS_EXPANDED_RESPONSE(our_vendor_id, our_vendor_type)) goto handle_response; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iwd-1.19/src/ie.c new/iwd-1.20/src/ie.c --- old/iwd-1.19/src/ie.c 2021-11-02 19:50:50.000000000 +0100 +++ new/iwd-1.20/src/ie.c 2021-11-18 21:21:21.000000000 +0100 @@ -2035,7 +2035,8 @@ } int ie_parse_hs20_indication(struct ie_tlv_iter *iter, uint8_t *version_out, - uint16_t *pps_mo_id_out, uint8_t *domain_id_out) + uint16_t *pps_mo_id_out, uint8_t *domain_id_out, + bool *dgaf_disable_out) { unsigned int len = ie_tlv_iter_get_length(iter); const uint8_t *data = ie_tlv_iter_get_data(iter); @@ -2060,6 +2061,9 @@ if (pps_mo_present && domain_id_present) return -EPROTOTYPE; + if (dgaf_disable_out) + *dgaf_disable_out = test_bit(&hs20_config, 0); + if (version_out) *version_out = bit_field(hs20_config, 4, 4); @@ -2087,7 +2091,7 @@ int ie_parse_hs20_indication_from_data(const uint8_t *data, size_t len, uint8_t *version, uint16_t *pps_mo_id, - uint8_t *domain_id) + uint8_t *domain_id, bool *dgaf_disable) { struct ie_tlv_iter iter; @@ -2099,7 +2103,8 @@ if (ie_tlv_iter_get_tag(&iter) != IE_TYPE_VENDOR_SPECIFIC) return -EPROTOTYPE; - return ie_parse_hs20_indication(&iter, version, pps_mo_id, domain_id); + return ie_parse_hs20_indication(&iter, version, pps_mo_id, domain_id, + dgaf_disable); } /* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iwd-1.19/src/ie.h new/iwd-1.20/src/ie.h --- old/iwd-1.19/src/ie.h 2021-11-02 19:50:50.000000000 +0100 +++ new/iwd-1.20/src/ie.h 2021-11-18 21:21:21.000000000 +0100 @@ -616,10 +616,11 @@ int ie_build_roaming_consortium(const uint8_t *rc, size_t rc_len, uint8_t *to); int ie_parse_hs20_indication(struct ie_tlv_iter *iter, uint8_t *version, - uint16_t *pps_mo_id, uint8_t *domain_id); + uint16_t *pps_mo_id, uint8_t *domain_id, + bool *dgaf_disable); int ie_parse_hs20_indication_from_data(const uint8_t *data, size_t len, uint8_t *version, uint16_t *pps_mo_id, - uint8_t *domain_id); + uint8_t *domain_id, bool *dgaf_disable); int ie_build_hs20_indication(uint8_t version, uint8_t *to); enum ie_rsnx_capability { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iwd-1.19/src/module.h new/iwd-1.20/src/module.h --- old/iwd-1.19/src/module.h 2020-04-14 20:38:37.000000000 +0200 +++ new/iwd-1.20/src/module.h 2021-11-18 21:21:21.000000000 +0100 @@ -33,19 +33,25 @@ }; #define IWD_MODULE(name, init, exit) \ + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wattributes\"") \ static struct iwd_module_desc __iwd_module_ ## name \ - __attribute__((used, section("__iwd_module"), aligned(8))) = {\ + __attribute__((used, retain, section("__iwd_module"), \ + aligned(8))) = { \ #name, init, exit \ - }; + }; \ + _Pragma("GCC diagnostic pop") #define IWD_MODULE_DEPENDS(name, dep) \ - static struct iwd_module_depends \ - __iwd_module__##name##_##dep \ - __attribute__((used, section("__iwd_module_dep"), \ - aligned(8))) = { \ - .self = #name, \ - .target = #dep, \ - }; + _Pragma("GCC diagnostic push") \ + _Pragma("GCC diagnostic ignored \"-Wattributes\"") \ + static struct iwd_module_depends __iwd_module__##name##_##dep \ + __attribute__((used, retain, \ + section("__iwd_module_dep"), aligned(8))) = { \ + .self = #name, \ + .target = #dep, \ + }; \ + _Pragma("GCC diagnostic pop") int iwd_modules_init(void); void iwd_modules_exit(void); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iwd-1.19/src/netconfig.c new/iwd-1.20/src/netconfig.c --- old/iwd-1.19/src/netconfig.c 2021-11-02 19:50:50.000000000 +0100 +++ new/iwd-1.20/src/netconfig.c 2021-11-18 21:21:21.000000000 +0100 @@ -50,6 +50,7 @@ #include "src/util.h" #include "src/ie.h" #include "src/netconfig.h" +#include "src/sysfs.h" struct netconfig { uint32_t ifindex; @@ -102,38 +103,6 @@ l_info("%s%s", prefix, str); } -static int write_string(const char *file, const char *value) -{ - size_t l = strlen(value); - int fd; - int r; - - fd = L_TFR(open(file, O_WRONLY)); - if (fd < 0) - return -errno; - - r = L_TFR(write(fd, value, l)); - L_TFR(close(fd)); - - return r; -} - -static int sysfs_write_ipv6_setting(const char *ifname, const char *setting, - const char *value) -{ - int r; - - L_AUTO_FREE_VAR(char *, file) = - l_strdup_printf("/proc/sys/net/ipv6/conf/%s/%s", - ifname, setting); - - r = write_string(file, value); - if (r < 0) - l_error("Unable to write %s to %s", setting, file); - - return r; -} - static void netconfig_free_settings(struct netconfig *netconfig) { l_rtnl_address_free(netconfig->v4_address); @@ -207,6 +176,36 @@ return addr_str; } +static bool netconfig_use_fils_addr(struct netconfig *netconfig, int af) +{ + if ((af == AF_INET ? netconfig->rtm_protocol : + netconfig->rtm_v6_protocol) != RTPROT_DHCP) + return false; + + if (!netconfig->fils_override) + return false; + + if (af == AF_INET) + return !!netconfig->fils_override->ipv4_addr; + + return !l_memeqzero(netconfig->fils_override->ipv6_addr, 16); +} + +static bool netconfig_use_fils_gateway(struct netconfig *netconfig, int af) +{ + if ((af == AF_INET ? netconfig->rtm_protocol : + netconfig->rtm_v6_protocol) != RTPROT_DHCP) + return false; + + if (!netconfig->fils_override) + return false; + + if (af == AF_INET) + return !!netconfig->fils_override->ipv4_gateway; + + return !l_memeqzero(netconfig->fils_override->ipv6_gateway, 16); +} + static char **netconfig_get_dns_list(struct netconfig *netconfig, int af, const uint8_t **out_dns_mac) { @@ -490,7 +489,7 @@ return gateway; case RTPROT_DHCP: - if (fils && fils->ipv4_gateway) { + if (netconfig_use_fils_gateway(netconfig, AF_INET)) { gateway = netconfig_ipv4_to_string(fils->ipv4_gateway); if (gateway && out_mac && @@ -558,10 +557,7 @@ gateway = l_settings_get_string(netconfig->active_settings, "IPv6", "Gateway"); - if (!gateway && netconfig->rtm_v6_protocol == RTPROT_DHCP && - netconfig->fils_override && - !l_memeqzero(netconfig->fils_override->ipv6_gateway, - 16)) { + if (!gateway && netconfig_use_fils_gateway(netconfig, AF_INET6)) { gateway = netconfig_ipv6_to_string( netconfig->fils_override->ipv6_gateway); @@ -729,8 +725,7 @@ ip, ifa->ifa_prefixlen); if (netconfig->rtm_v6_protocol != RTPROT_DHCP || - (netconfig->fils_override && - !l_memeqzero(netconfig->fils_override->ipv6_addr, 16))) + netconfig_use_fils_addr(netconfig, AF_INET6)) return; inet_pton(AF_INET6, ip, &in6); @@ -844,10 +839,8 @@ } } -static bool netconfig_ipv4_routes_install(struct netconfig *netconfig) +static bool netconfig_ipv4_subnet_route_install(struct netconfig *netconfig) { - L_AUTO_FREE_VAR(char *, gateway) = NULL; - const uint8_t *gateway_mac = NULL; struct in_addr in_addr; char ip[INET_ADDRSTRLEN]; char network[INET_ADDRSTRLEN]; @@ -870,10 +863,19 @@ netconfig_route_generic_cb, netconfig, NULL)) { l_error("netconfig: Failed to add subnet route."); - return false; } + return true; +} + +static bool netconfig_ipv4_gateway_route_install(struct netconfig *netconfig) +{ + L_AUTO_FREE_VAR(char *, gateway) = NULL; + const uint8_t *gateway_mac = NULL; + struct in_addr in_addr; + char ip[INET_ADDRSTRLEN]; + gateway = netconfig_ipv4_get_gateway(netconfig, &gateway_mac); if (!gateway) { l_debug("No gateway obtained from %s.", @@ -889,6 +891,10 @@ return true; } + if (!l_rtnl_address_get_address(netconfig->v4_address, ip) || + inet_pton(AF_INET, ip, &in_addr) < 1) + return false; + netconfig->route4_add_gateway_cmd_id = l_rtnl_route4_add_gateway(rtnl, netconfig->ifindex, gateway, ip, ROUTE_PRIORITY_OFFSET, @@ -902,23 +908,20 @@ return false; } - if (gateway_mac) { - /* - * Attempt to use the gateway MAC address received from the AP - * by writing the mapping directly into the netdev's ARP table - * so as to save one data frame roundtrip before first IP - * connections are established. This is very low-priority but - * print error messages just because they may indicate bigger - * problems. - */ - if (!l_rtnl_neighbor_set_hwaddr(rtnl, netconfig->ifindex, + /* + * Attempt to use the gateway MAC address received from the AP by + * writing the mapping directly into the netdev's ARP table so as + * to save one data frame roundtrip before first IP connections + * are established. This is very low-priority but print error + * messages just because they may indicate bigger problems. + */ + if (gateway_mac && !l_rtnl_neighbor_set_hwaddr(rtnl, netconfig->ifindex, AF_INET, &netconfig->fils_override->ipv4_gateway, gateway_mac, 6, netconfig_set_neighbor_entry_cb, NULL, NULL)) - l_debug("l_rtnl_neighbor_set_hwaddr failed"); - } + l_debug("l_rtnl_neighbor_set_hwaddr failed"); return true; } @@ -939,10 +942,9 @@ netconfig_gateway_to_arp(netconfig); - if (!netconfig_ipv4_routes_install(netconfig)) { - l_error("netconfig: Failed to install IPv4 routes."); + if (!netconfig_ipv4_subnet_route_install(netconfig) || + !netconfig_ipv4_gateway_route_install(netconfig)) return; - } netconfig_set_dns(netconfig); netconfig_set_domains(netconfig); @@ -1215,9 +1217,7 @@ struct netdev *netdev = netdev_find(netconfig->ifindex); bool set_address = (netconfig->rtm_protocol == RTPROT_STATIC); - if (netconfig->rtm_protocol == RTPROT_DHCP && - netconfig->fils_override && - netconfig->fils_override->ipv4_addr) { + if (netconfig_use_fils_addr(netconfig, AF_INET)) { L_AUTO_FREE_VAR(char *, addr_str) = netconfig_ipv4_to_string( netconfig->fils_override->ipv4_addr); uint8_t prefix_len = netconfig->fils_override->ipv4_prefix_len; @@ -1298,9 +1298,7 @@ sysfs_write_ipv6_setting(netdev_get_name(netdev), "disable_ipv6", "0"); - if (netconfig->rtm_v6_protocol == RTPROT_DHCP && - netconfig->fils_override && - !l_memeqzero(netconfig->fils_override->ipv6_addr, 16)) { + if (netconfig_use_fils_addr(netconfig, AF_INET6)) { uint8_t prefix_len = netconfig->fils_override->ipv6_prefix_len; L_AUTO_FREE_VAR(char *, addr_str) = netconfig_ipv6_to_string( netconfig->fils_override->ipv6_addr); @@ -1499,7 +1497,7 @@ return true; } -bool netconfig_reconfigure(struct netconfig *netconfig) +bool netconfig_reconfigure(struct netconfig *netconfig, bool set_arp_gw) { /* * Starting with kernel 4.20, ARP cache is flushed when the netdev @@ -1508,7 +1506,8 @@ * lost or delayed. Try to force the gateway into the ARP cache * to alleviate this */ - netconfig_gateway_to_arp(netconfig); + if (set_arp_gw) + netconfig_gateway_to_arp(netconfig); if (netconfig->rtm_protocol == RTPROT_DHCP) { /* TODO l_dhcp_client sending a DHCP inform request */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iwd-1.19/src/netconfig.h new/iwd-1.20/src/netconfig.h --- old/iwd-1.19/src/netconfig.h 2021-11-02 19:50:50.000000000 +0100 +++ new/iwd-1.20/src/netconfig.h 2021-11-18 21:21:21.000000000 +0100 @@ -36,7 +36,7 @@ bool netconfig_configure(struct netconfig *netconfig, netconfig_notify_func_t notify, void *user_data); -bool netconfig_reconfigure(struct netconfig *netconfig); +bool netconfig_reconfigure(struct netconfig *netconfig, bool set_arp_gw); bool netconfig_reset(struct netconfig *netconfig); char *netconfig_get_dhcp_server_ipv4(struct netconfig *netconfig); bool netconfig_get_fils_ip_req(struct netconfig *netconfig, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iwd-1.19/src/scan.c new/iwd-1.20/src/scan.c --- old/iwd-1.19/src/scan.c 2021-11-02 19:50:50.000000000 +0100 +++ new/iwd-1.20/src/scan.c 2021-11-18 21:21:21.000000000 +0100 @@ -1058,6 +1058,7 @@ { uint16_t cost_level; uint16_t cost_flags; + bool dgaf_disable; if (!bss->wpa && is_ie_wpa_ie(data, len)) { bss->wpa = l_memdup(data - 2, len + 2); @@ -1071,9 +1072,11 @@ if (is_ie_wfa_ie(data, len, IE_WFA_OI_HS20_INDICATION)) { if (ie_parse_hs20_indication_from_data(data - 2, len + 2, - &bss->hs20_version, NULL, NULL) < 0) + &bss->hs20_version, NULL, NULL, + &dgaf_disable) < 0) return; + bss->hs20_dgaf_disable = dgaf_disable; bss->hs20_capable = true; return; } @@ -1252,6 +1255,23 @@ bss->rc_ie = l_memdup(iter.data - 2, iter.len + 2); break; + + case IE_TYPE_EXTENDED_CAPABILITIES: + /* 802.11-2020 9.4.2.26 + * + * "The length of the Extended Capabilities field is + * variable. If fewer bits are received in an Extended + * Capabilities field than shown in Table 9-153, the + * rest of the Extended Capabilities field bits are + * assumed to be zero" + * + * Currently only Proxy ARP bit (12) is checked, and if + * not found, this is not a fatal error. + */ + if (iter.len < 2) + break; + + bss->proxy_arp = test_bit(iter.data, 12); } } @@ -1608,6 +1628,10 @@ { const struct scan_bss *new_bss = a, *bss = b; + if (bss->rank == new_bss->rank) + return (bss->signal_strength > + new_bss->signal_strength) ? 1 : -1; + return (bss->rank > new_bss->rank) ? 1 : -1; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iwd-1.19/src/scan.h new/iwd-1.20/src/scan.h --- old/iwd-1.19/src/scan.h 2021-11-02 19:50:50.000000000 +0100 +++ new/iwd-1.20/src/scan.h 2021-11-18 21:21:21.000000000 +0100 @@ -86,6 +86,8 @@ bool anqp_capable : 1; bool hs20_capable : 1; bool force_default_sae_group : 1; + bool proxy_arp : 1; + bool hs20_dgaf_disable : 1; uint8_t cost_level : 3; uint8_t cost_flags : 4; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iwd-1.19/src/station.c new/iwd-1.20/src/station.c --- old/iwd-1.19/src/station.c 2021-11-02 19:50:50.000000000 +0100 +++ new/iwd-1.20/src/station.c 2021-11-18 21:21:21.000000000 +0100 @@ -57,12 +57,15 @@ #include "src/anqputil.h" #include "src/diagnostic.h" #include "src/frame-xchg.h" +#include "src/sysfs.h" static struct l_queue *station_list; static uint32_t netdev_watch; static uint32_t mfp_setting; static uint32_t roam_retry_interval; static bool anqp_disabled; +static bool supports_arp_evict_nocarrier; +static bool supports_ndisc_evict_nocarrier; static struct watchlist event_watches; struct station { @@ -695,6 +698,10 @@ struct scan_bss *open = entry->data; struct ie_owe_transition_info *open_info = open->owe_trans; + /* AP does not advertise owe transition */ + if (!open_info) + continue; + /* * Check if this is an Open/Hidden pair: * @@ -1384,6 +1391,44 @@ return "invalid"; } +static void station_set_evict_nocarrier(struct station *station, bool value) +{ + char *v = value ? "1" : "0"; + + if (supports_arp_evict_nocarrier) + sysfs_write_ipv4_setting(netdev_get_name(station->netdev), + "arp_evict_nocarrier", v); + + if (supports_ndisc_evict_nocarrier) + sysfs_write_ipv6_setting(netdev_get_name(station->netdev), + "ndisc_evict_nocarrier", v); +} + +/* + * Handles dropping ARP (IPv4) and neighbor advertisements (IPv6) settings. + */ +static void station_set_drop_neighbor_discovery(struct station *station, + bool value) +{ + char *v = value ? "1" : "0"; + + sysfs_write_ipv4_setting(netdev_get_name(station->netdev), + "drop_gratuitous_arp", v); + sysfs_write_ipv6_setting(netdev_get_name(station->netdev), + "drop_unsolicited_na", v); +} + +static void station_set_drop_unicast_l2_multicast(struct station *station, + bool value) +{ + char *v = value ? "1" : "0"; + + sysfs_write_ipv4_setting(netdev_get_name(station->netdev), + "drop_unicast_in_l2_multicast", v); + sysfs_write_ipv6_setting(netdev_get_name(station->netdev), + "drop_unicast_in_l2_multicast", v); +} + static void station_enter_state(struct station *station, enum station_state state) { @@ -1431,19 +1476,46 @@ periodic_scan_stop(station); break; - case STATION_STATE_DISCONNECTED: - periodic_scan_stop(station); - break; case STATION_STATE_CONNECTED: l_dbus_object_add_interface(dbus, netdev_get_path(station->netdev), IWD_STATION_DIAGNOSTIC_INTERFACE, station); periodic_scan_stop(station); + + station_set_evict_nocarrier(station, true); + + /* + * Hotspot Specification 2.0 - Section 6.5 + * + * " - Shall drop all received {gratuitous ARP, unsolicited + * Neighbor Advertisement} messages when the Proxy ARP field + * is set to 1 in the Extended Capabilities element of the + * serving AP. + * + * - When the serving AP transmits frames containing an HS2.0 + * Indication element in which the value of the DGAF Disable + * bit subfield is set to 0, the mobile device should + * discard all received unicast IP packets that were + * decrypted using the GTK" + */ + if (station->connected_bss->proxy_arp) + station_set_drop_neighbor_discovery(station, true); + if (station->connected_bss->hs20_dgaf_disable) + station_set_drop_unicast_l2_multicast(station, true); + + break; + case STATION_STATE_DISCONNECTED: + periodic_scan_stop(station); + + station_set_evict_nocarrier(station, true); + station_set_drop_neighbor_discovery(station, false); + station_set_drop_unicast_l2_multicast(station, false); break; case STATION_STATE_DISCONNECTING: break; case STATION_STATE_ROAMING: + station_set_evict_nocarrier(station, false); break; } @@ -1833,7 +1905,8 @@ station_roam_timeout_rearm(station, roam_retry_interval); if (station->netconfig) - netconfig_reconfigure(station->netconfig); + netconfig_reconfigure(station->netconfig, + !supports_arp_evict_nocarrier); if (station->roam_freqs) { scan_freq_set_free(station->roam_freqs); @@ -4457,6 +4530,11 @@ if (!netconfig_enabled()) l_info("station: Network configuration is disabled."); + supports_arp_evict_nocarrier = sysfs_supports_ipv4_setting("all", + "arp_evict_nocarrier"); + supports_ndisc_evict_nocarrier = sysfs_supports_ipv6_setting("all", + "ndisc_evict_nocarrier"); + watchlist_init(&event_watches, NULL); return 0; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iwd-1.19/src/sysfs.c new/iwd-1.20/src/sysfs.c --- old/iwd-1.19/src/sysfs.c 1970-01-01 01:00:00.000000000 +0100 +++ new/iwd-1.20/src/sysfs.c 2021-11-18 21:21:21.000000000 +0100 @@ -0,0 +1,109 @@ +/* + * + * Wireless daemon for Linux + * + * Copyright (C) 2021 Intel Corporation. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <sys/stat.h> +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> + +#include <ell/ell.h> + +#include "src/sysfs.h" + +static int write_string(const char *file, const char *value) +{ + size_t l = strlen(value); + int fd; + int r; + + fd = L_TFR(open(file, O_WRONLY)); + if (fd < 0) + return -errno; + + r = L_TFR(write(fd, value, l)); + L_TFR(close(fd)); + + return r; +} + +static bool sysfs_supports_ip_setting(const char *ipv, const char *ifname, + const char *setting) +{ + struct stat st; + int err; + L_AUTO_FREE_VAR(char *, file) = + l_strdup_printf("/proc/sys/net/%s/conf/%s/%s", ipv, + ifname, setting); + + err = stat(file, &st); + + if (!err && S_ISREG(st.st_mode) != 0) + return true; + + return false; +} + +bool sysfs_supports_ipv6_setting(const char *ifname, const char *setting) +{ + return sysfs_supports_ip_setting("ipv6", ifname, setting); +} + +int sysfs_write_ipv6_setting(const char *ifname, const char *setting, + const char *value) +{ + int r; + + L_AUTO_FREE_VAR(char *, file) = + l_strdup_printf("/proc/sys/net/ipv6/conf/%s/%s", + ifname, setting); + + r = write_string(file, value); + if (r < 0) + l_error("Unable to write %s to %s", setting, file); + + return r; +} + +bool sysfs_supports_ipv4_setting(const char *ifname, const char *setting) +{ + return sysfs_supports_ip_setting("ipv4", ifname, setting); +} + +int sysfs_write_ipv4_setting(const char *ifname, const char *setting, + const char *value) +{ + int r; + + L_AUTO_FREE_VAR(char *, file) = + l_strdup_printf("/proc/sys/net/ipv4/conf/%s/%s", + ifname, setting); + + r = write_string(file, value); + if (r < 0) + l_error("Unable to write %s to %s", setting, file); + + return r; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/iwd-1.19/src/sysfs.h new/iwd-1.20/src/sysfs.h --- old/iwd-1.19/src/sysfs.h 1970-01-01 01:00:00.000000000 +0100 +++ new/iwd-1.20/src/sysfs.h 2021-11-18 21:21:21.000000000 +0100 @@ -0,0 +1,28 @@ +/* + * + * Wireless daemon for Linux + * + * Copyright (C) 2021 Intel Corporation. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +bool sysfs_supports_ipv6_setting(const char *ifname, const char *setting); +int sysfs_write_ipv6_setting(const char *ifname, const char *setting, + const char *value); +bool sysfs_supports_ipv4_setting(const char *ifname, const char *setting); +int sysfs_write_ipv4_setting(const char *ifname, const char *setting, + const char *value);