From patchwork Fri Jun 26 22:57:07 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Wang X-Patchwork-Id: 1318163 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2001:8b0:10b:1231::1; helo=merlin.infradead.org; envelope-from=hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=chromium.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=merlin.20170209 header.b=J91bhfnb; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=chromium.org header.i=@chromium.org header.a=rsa-sha256 header.s=google header.b=jfwJ7+nz; dkim-atps=neutral Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:8b0:10b:1231::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49tskY1K2jz9sSS for ; Sat, 27 Jun 2020 08:58:44 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=8emflAqjqLZl16sflmXYM3y3oYSeN/y2ist+RTikRxM=; b=J91bhfnbYqhN06BpKJxK79H42 1T520PHwJ83oaxLdgPohVC3jkxPigIKJ0jJwC1eprHS8WBcbepVZA6URpm761yqIZrGgLTYpRvrnV AOqL2nWiILntaB7hblsP4oUAqi80H/pV7HzjTuQbO7FETruxB8CrQQBAH4EmtaQeLG1rP2yP/G2BM /kPKbF1AKiFWn6Rw3GicP+GMkmwHTQ3xPGP/ZXSL82AS+mxKt7MJbiPfrC7ida3UyiRhGXU6k8bNG 9zdQSjCMar/wLvOvBVOA50FffHw+rcu+fdsuU+aQS7ZS43aKQ8gr4bMy2LvPptWWlW7EYDCmoGA9Q bVRfkAXQQ==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1joxHl-0004Xa-9Y; Fri, 26 Jun 2020 22:57:29 +0000 Received: from mail-pj1-x1044.google.com ([2607:f8b0:4864:20::1044]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1joxHc-0004Wh-L3 for hostap@lists.infradead.org; Fri, 26 Jun 2020 22:57:25 +0000 Received: by mail-pj1-x1044.google.com with SMTP id i4so5558473pjd.0 for ; Fri, 26 Jun 2020 15:57:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=J8u3hUUnhrwvtKWuB8Vq92VQvcQi71mYvmiPUx8FijQ=; b=jfwJ7+nz3mZC4jBv9TEkIZVu5mYu+ktBdVHUfPUOb245wGj+wTapWrFvxMHDsxNWQ7 NtIPuQ2Z7gywM8Dg9FoDlmUSgbR8Oe2ZWhvza2e6ohzQDMvX7b4SY5OOOetQvVJxZF90 BhAlEWJq7ZbVAsHkROzCqEOetZ5nJyZKApbow= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=J8u3hUUnhrwvtKWuB8Vq92VQvcQi71mYvmiPUx8FijQ=; b=NTfg3E5dMdg0GA/YanH9AQHwx2TQDpIvDTObj23LanVCiFkcGsHWuLE1Z8G7UadVrX sATgbtbsZ7a5jESA5UNeLZuY8F3VfHjcCET+gvv7mSpWqXJfldv6ITD8mV2UAvVOZY/U wyoyAmiTryTrMt2tqNhbEGMnjQJNI2GnwAw/1EbN7oSVPTRyEZ6nCG1rJgyfiaJxCJ4d 54F3aKyaU2LXc8ygKkcR9Oy5jpbKzNX+4kcZgVrGN/V1c6HBaIhfEWIqZE3AMqyPzYl4 arLJ0OPE7njYVQ3aJCHRaHfnlgIdW8CTQUIxdpUV0QQVy2Co5RlUspZcgGb4ce5MizXy KhNA== X-Gm-Message-State: AOAM531Zha2bm7aFVo3KL/q2I2KfuRO4wJabHidoFa4j4dTiv422hH/6 Y/05Nvd0h1ujfWUZgsxQy+gkcdvfOLA= X-Google-Smtp-Source: ABdhPJy1scnzIrG12aPWmVwDwyU7PWgaN4pKMuXAUM8+xsTEPXYyw/nOZCqzLMSMUVKU3RJEMp7Prg== X-Received: by 2002:a17:90a:b781:: with SMTP id m1mr5402378pjr.14.1593212238290; Fri, 26 Jun 2020 15:57:18 -0700 (PDT) Received: from localhost ([2620:15c:202:201:2b10:8627:31e7:c5ec]) by smtp.gmail.com with ESMTPSA id u19sm28557979pfk.98.2020.06.26.15.57.17 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 26 Jun 2020 15:57:17 -0700 (PDT) From: Matthew Wang To: j@w1.fi Subject: [PATCH 2/3] global parser functions return 1 when property unchanged Date: Fri, 26 Jun 2020 15:57:07 -0700 Message-Id: <20200626225708.429239-2-matthewmwang@chromium.org> X-Mailer: git-send-email 2.27.0.212.ge8ba1cc988-goog In-Reply-To: <20200626225708.429239-1-matthewmwang@chromium.org> References: <20200626225708.429239-1-matthewmwang@chromium.org> MIME-Version: 1.0 X-Spam-Note: CRM114 invocation failed X-Spam-Score: -0.2 (/) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-0.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [2607:f8b0:4864:20:0:0:0:1044 listed in] [list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 DKIMWL_WL_HIGH DKIMwl.org - Whitelisted High sender X-BeenThere: hostap@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: hostap@lists.infradead.org, Matthew Wang Sender: "Hostap" Errors-To: hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Currently, wpa_config_set, the function that sets per-network properties, returns 1 when a property it attempts to set is unchanged. Its global parallel, wpa_config_process_global, doesn't do this even though much of the code is very similar. Change this, and several of the parser functions, to resemble the per-network parser and setter functions. Signed-off-by: Matthew Wang --- src/utils/wpabuf.h | 15 ++++++ wpa_supplicant/config.c | 63 +++++++++++++++++++++++-- wpa_supplicant/ctrl_iface.c | 2 + wpa_supplicant/dbus/dbus_new_handlers.c | 8 ++-- 4 files changed, 80 insertions(+), 8 deletions(-) diff --git a/src/utils/wpabuf.h b/src/utils/wpabuf.h index 01da41b32..ecdc08f84 100644 --- a/src/utils/wpabuf.h +++ b/src/utils/wpabuf.h @@ -70,6 +70,21 @@ static inline size_t wpabuf_tailroom(const struct wpabuf *buf) return buf->size - buf->used; } +/** + * wpabuf_cmp - Check if two buffers contain the same data + * @a: wpabuf buffer + * @b: wpabuf buffer + * Returns: 0 if the two buffers contain the same data and non-zero otherwise + */ +static inline int wpabuf_cmp(const struct wpabuf *a, const struct wpabuf *b) +{ + if (a == NULL && b == NULL) + return 0; + if (a && b && wpabuf_size(a) == wpabuf_size(b)) + return os_memcmp(a->buf, b->buf, wpabuf_size(a)); + return -1; +} + /** * wpabuf_head - Get pointer to the head of the buffer data * @buf: wpabuf buffer diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index 0b4a66ad7..e4fa43ec7 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -4360,13 +4360,31 @@ void wpa_config_debug_dump_networks(struct wpa_config *config) #endif /* CONFIG_NO_STDOUT_DEBUG */ +/** + * Structure for global configuration parsing. This data is used to implement a + * generic parser for the global interface configuration. The table of variables + * is defined below in this file (global_fields[]). + */ struct global_parse_data { + /* Configuration variable name */ char *name; + + /* Parser function for this variable. The parser functions return 0 or 1 + * to indicate success. Value 0 indicates that the parameter value may + * have change while value 1 means that the value did not change. + * Error cases (failure to parse the string) are indicated by returning + * -1. */ int (*parser)(const struct global_parse_data *data, struct wpa_config *config, int line, const char *value); + + /* Getter function to print the variable in text format to buf. */ int (*get)(const char *name, struct wpa_config *config, long offset, char *buf, size_t buflen, int pretty_print); + + /* Variable specific parameters for the parser. */ void *param1, *param2, *param3; + + /* Indicates which configuration variable has changed. */ unsigned int changed_flag; }; @@ -4385,8 +4403,10 @@ static int wpa_global_config_parse_int(const struct global_parse_data *data, line, pos); return -1; } - *dst = val; + if (*dst == val) + return 1; + *dst = val; wpa_printf(MSG_DEBUG, "%s=%d", data->name, *dst); if (data->param2 && *dst < (long) data->param2) { @@ -4413,7 +4433,7 @@ static int wpa_global_config_parse_str(const struct global_parse_data *data, struct wpa_config *config, int line, const char *pos) { - size_t len; + size_t len, prev_len; char **dst, *tmp; len = os_strlen(pos); @@ -4437,11 +4457,22 @@ static int wpa_global_config_parse_str(const struct global_parse_data *data, return -1; } + dst = (char **) (((u8 *) config) + (long) data->param1); + if (*dst) + prev_len = os_strlen(*dst); + else + prev_len = 0; + + /* No change to the previously configured value */ + if ((*dst == NULL && pos == NULL) || + (*dst && pos && prev_len == len && + os_memcmp(*dst, pos, len) == 0)) + return 1; + tmp = os_strdup(pos); if (tmp == NULL) return -1; - dst = (char **) (((u8 *) config) + (long) data->param1); os_free(*dst); *dst = tmp; wpa_printf(MSG_DEBUG, "%s='%s'", data->name, *dst); @@ -4482,6 +4513,10 @@ static int wpa_global_config_parse_bin(const struct global_parse_data *data, return -1; dst = (struct wpabuf **) (((u8 *) config) + (long) data->param1); + if (wpabuf_cmp(*dst, tmp) == 0) { + wpabuf_free(tmp); + return 1; + } wpabuf_free(*dst); *dst = tmp; wpa_printf(MSG_DEBUG, "%s", data->name); @@ -4523,6 +4558,8 @@ static int wpa_global_config_parse_ipv4(const struct global_parse_data *data, return -1; dst = (u32 *) (((u8 *) config) + (long) data->param1); + if (os_memcmp(dst, &addr.u.v4.s_addr, 4) == 0) + return 1; os_memcpy(dst, &addr.u.v4.s_addr, 4); wpa_printf(MSG_DEBUG, "%s = 0x%x", data->name, WPA_GET_BE32((u8 *) dst)); @@ -4540,6 +4577,8 @@ static int wpa_config_process_country(const struct global_parse_data *data, wpa_printf(MSG_DEBUG, "Invalid country set"); return -1; } + if (pos[0] == config->country[0] && pos[1] == config->country[1]) + return 1; config->country[0] = pos[0]; config->country[1] = pos[1]; wpa_printf(MSG_DEBUG, "country='%c%c'", @@ -5158,6 +5197,19 @@ const char * wpa_config_get_global_field_name(unsigned int i, int *no_var) } +/** + * wpa_config_process_global - Set a variable in global configuration + * @config: Pointer to global configuration data + * @pos: Name and value in the format "{name}={value}" + * @line: Line number in configuration file or 0 if not used + * Returns: 0 on success with possible change in value, 1 on success with no + * change to previously configured value, or -1 on failure + * + * This function can be used to set global configuration variables based on + * both the configuration file and management interface input. The value + * parameter must be in the same format as the text-based configuration file is + * using. For example, strings are using double quotation marks. + */ int wpa_config_process_global(struct wpa_config *config, char *pos, int line) { size_t i; @@ -5170,11 +5222,14 @@ int wpa_config_process_global(struct wpa_config *config, char *pos, int line) pos[flen] != '=') continue; - if (field->parser(field, config, line, pos + flen + 1)) { + ret = field->parser(field, config, line, pos + flen + 1); + if (ret < 0) { wpa_printf(MSG_ERROR, "Line %d: failed to " "parse '%s'.", line, pos); ret = -1; } + if (ret == 1) + break; if (field->changed_flag == CFG_CHANGED_NFC_PASSWORD_TOKEN) config->wps_nfc_pw_from_config = 1; config->changed_parameters |= field->changed_flag; diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 8d2ccbae5..eea8b40f4 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -884,6 +884,8 @@ static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s, ret = wpa_config_process_global(wpa_s->conf, cmd, -1); if (ret == 0) wpa_supplicant_update_config(wpa_s); + else if (ret == 1) + ret = 0; } return ret; diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c index 93eeb30e1..18b66e303 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.c +++ b/wpa_supplicant/dbus/dbus_new_handlers.c @@ -3948,14 +3948,14 @@ dbus_bool_t wpas_dbus_setter_iface_global( return FALSE; } - if (wpa_config_process_global(wpa_s->conf, buf, -1)) { + ret = wpa_config_process_global(wpa_s->conf, buf, -1); + if (ret < 0) { dbus_set_error(error, DBUS_ERROR_INVALID_ARGS, "Failed to set interface property %s", property_desc->dbus_property); return FALSE; - } - - wpa_supplicant_update_config(wpa_s); + } else if (ret == 0) + wpa_supplicant_update_config(wpa_s); return TRUE; }