From patchwork Mon Mar 23 15:25:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 216213 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 601EBC54FCE for ; Mon, 23 Mar 2020 15:25:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 31E41206F8 for ; Mon, 23 Mar 2020 15:25:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727385AbgCWPZx (ORCPT ); Mon, 23 Mar 2020 11:25:53 -0400 Received: from s3.sipsolutions.net ([144.76.43.62]:49296 "EHLO sipsolutions.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727280AbgCWPZu (ORCPT ); Mon, 23 Mar 2020 11:25:50 -0400 Received: by sipsolutions.net with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.93) (envelope-from ) id 1jGOxX-002WVN-7L; Mon, 23 Mar 2020 16:25:47 +0100 From: Johannes Berg To: linux-wireless@vger.kernel.org Cc: me@bobcopeland.com, Johannes Berg Subject: [PATCH 1/7] wmediumd: mark various functions static Date: Mon, 23 Mar 2020 16:25:36 +0100 Message-Id: <20200323162245.11535025ec4d.I98f5142f6c3cfc5ddf1f31f446072b112b6f1bd5@changeid> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200323152542.68696-1-johannes@sipsolutions.net> References: <20200323152542.68696-1-johannes@sipsolutions.net> MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Johannes Berg There are a number of functions that can be static but aren't, mark them as such. --- wmediumd/wmediumd.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/wmediumd/wmediumd.c b/wmediumd/wmediumd.c index 8fb0ed49bbb1..5e89e83ca72b 100644 --- a/wmediumd/wmediumd.c +++ b/wmediumd/wmediumd.c @@ -220,7 +220,7 @@ static int get_signal_offset_by_interference(struct wmediumd *ctx, int src_idx, return (int)(milliwatt_to_dBm(intf_power) + 0.5); } -bool is_multicast_ether_addr(const u8 *addr) +static bool is_multicast_ether_addr(const u8 *addr) { return 0x01 & addr[0]; } @@ -236,8 +236,8 @@ static struct station *get_station_by_addr(struct wmediumd *ctx, u8 *addr) return NULL; } -void queue_frame(struct wmediumd *ctx, struct station *station, - struct frame *frame) +static void queue_frame(struct wmediumd *ctx, struct station *station, + struct frame *frame) { struct ieee80211_hdr *hdr = (void *)frame->data; u8 *dest = hdr->addr1; @@ -485,7 +485,7 @@ out: nlmsg_free(msg); } -void wmediumd_deliver_frame(struct usfstl_job *job) +static void wmediumd_deliver_frame(struct usfstl_job *job) { struct wmediumd *ctx = job->data; struct frame *frame = container_of(job, struct frame, job); @@ -566,7 +566,7 @@ void wmediumd_deliver_frame(struct usfstl_job *job) free(frame); } -void wmediumd_intf_update(struct usfstl_job *job) +static void wmediumd_intf_update(struct usfstl_job *job) { struct wmediumd *ctx = job->data; int i, j; @@ -732,7 +732,7 @@ static const struct usfstl_vhost_user_ops wmediumd_vu_ops = { /* * Register with the kernel to start receiving new frames. */ -int send_register_msg(struct wmediumd *ctx) +static int send_register_msg(struct wmediumd *ctx) { struct nl_sock *sock = ctx->sock; struct nl_msg *msg; @@ -815,7 +815,7 @@ static int init_netlink(struct wmediumd *ctx) /* * Print the CLI help */ -void print_help(int exval) +static void print_help(int exval) { printf("wmediumd v%s - a wireless medium simulator\n", VERSION_STR); printf("wmediumd [-h] [-V] [-l LOG_LVL] [-x FILE] -c FILE \n\n"); From patchwork Mon Mar 23 15:25:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 216215 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 91648C54FCE for ; Mon, 23 Mar 2020 15:25:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7351C206F9 for ; Mon, 23 Mar 2020 15:25:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727337AbgCWPZu (ORCPT ); Mon, 23 Mar 2020 11:25:50 -0400 Received: from s3.sipsolutions.net ([144.76.43.62]:49308 "EHLO sipsolutions.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727289AbgCWPZu (ORCPT ); Mon, 23 Mar 2020 11:25:50 -0400 Received: by sipsolutions.net with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.93) (envelope-from ) id 1jGOxY-002WVN-G0; Mon, 23 Mar 2020 16:25:48 +0100 From: Johannes Berg To: linux-wireless@vger.kernel.org Cc: me@bobcopeland.com, Johannes Berg Subject: [PATCH 5/7] wmediumd: support compilation with asan/ubsan Date: Mon, 23 Mar 2020 16:25:40 +0100 Message-Id: <20200323162245.cd34fabda35f.I5780f136bab2971b28698e2bb045387bf41add84@changeid> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200323152542.68696-1-johannes@sipsolutions.net> References: <20200323152542.68696-1-johannes@sipsolutions.net> MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Johannes Berg Use "make SANITIZE=1" to get asan/ubsan for checking for errors. --- wmediumd/Makefile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/wmediumd/Makefile b/wmediumd/Makefile index 585f488a9bd5..f75c4e8b4e3e 100644 --- a/wmediumd/Makefile +++ b/wmediumd/Makefile @@ -53,6 +53,12 @@ OBJECTS=wmediumd.o config.o per.o OBJECTS += lib/loop.o lib/sched.o lib/schedctrl.o OBJECTS += lib/uds.o lib/vhost.o lib/wallclock.o +ifeq ($(SANITIZE),1) +CFLAGS += -fsanitize=undefined,address +# apparently these have to come first for some reason +override LDFLAGS := -lasan -lubsan $(LDFLAGS) +endif + all: wmediumd wmediumd: $(OBJECTS) From patchwork Mon Mar 23 15:25:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 216214 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 26816C54FCF for ; Mon, 23 Mar 2020 15:25:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id F2C80206F8 for ; Mon, 23 Mar 2020 15:25:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727368AbgCWPZw (ORCPT ); Mon, 23 Mar 2020 11:25:52 -0400 Received: from s3.sipsolutions.net ([144.76.43.62]:49316 "EHLO sipsolutions.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727278AbgCWPZv (ORCPT ); Mon, 23 Mar 2020 11:25:51 -0400 Received: by sipsolutions.net with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.93) (envelope-from ) id 1jGOxY-002WVN-T4; Mon, 23 Mar 2020 16:25:49 +0100 From: Johannes Berg To: linux-wireless@vger.kernel.org Cc: me@bobcopeland.com, Johannes Berg Subject: [PATCH 6/7] wmediumd: track dynamic station addresses Date: Mon, 23 Mar 2020 16:25:41 +0100 Message-Id: <20200323162245.358bbb1372cb.Idd69e690298107f7d7be6c547284b6443926e5a2@changeid> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200323152542.68696-1-johannes@sipsolutions.net> References: <20200323152542.68696-1-johannes@sipsolutions.net> MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org From: Johannes Berg With newer kernels, mac80211_hwsim indicates to us when it starts and stops using a certain MAC address on a certain radio. Without that, there's a need to configure each MAC address as a station, which is not only incorrect (a station can have multiple addresses and wouldn't have a different position or different frame loss probabilities between them) but also impractical, e.g. for random scanning. Add the necessary code to track and use this information, and look up sender station by the HW address and destination by any of the used addresses. Still keep looking up by source address as well to not break any existing use cases. --- wmediumd/wmediumd.c | 97 ++++++++++++++++++++++++++++++++++++++++----- wmediumd/wmediumd.h | 22 ++++++++-- 2 files changed, 105 insertions(+), 14 deletions(-) diff --git a/wmediumd/wmediumd.c b/wmediumd/wmediumd.c index a1e16defd144..14ea63b6ba69 100644 --- a/wmediumd/wmediumd.c +++ b/wmediumd/wmediumd.c @@ -238,6 +238,32 @@ static struct station *get_station_by_addr(struct wmediumd *ctx, u8 *addr) return NULL; } +static bool station_has_addr(struct station *station, const u8 *addr) +{ + unsigned int i; + + if (memcmp(station->addr, addr, ETH_ALEN) == 0) + return true; + + for (i = 0; i < station->n_addrs; i++) { + if (memcmp(station->addrs[i].addr, addr, ETH_ALEN) == 0) + return true; + } + + return false; +} + +static struct station *get_station_by_used_addr(struct wmediumd *ctx, u8 *addr) +{ + struct station *station; + + list_for_each_entry(station, &ctx->stations, list) { + if (station_has_addr(station, addr)) + return station; + } + return NULL; +} + static void queue_frame(struct wmediumd *ctx, struct station *station, struct frame *frame) { @@ -285,7 +311,7 @@ static void queue_frame(struct wmediumd *ctx, struct station *station, if (is_multicast_ether_addr(dest)) { deststa = NULL; } else { - deststa = get_station_by_addr(ctx, dest); + deststa = get_station_by_used_addr(ctx, dest); if (deststa) { snr = ctx->get_link_snr(ctx, station, deststa) - get_signal_offset_by_interference(ctx, @@ -586,7 +612,7 @@ static void wmediumd_deliver_frame(struct usfstl_job *job) 1, signal, frame->freq); - } else if (memcmp(dest, station->addr, ETH_ALEN) == 0) { + } else if (station_has_addr(station, dest)) { if (set_interference_duration(ctx, frame->sender->index, frame->duration, frame->signal)) @@ -657,13 +683,16 @@ static void _process_messages(struct nl_msg *msg, struct station *sender; struct frame *frame; struct ieee80211_hdr *hdr; - u8 *src; + u8 *src, *hwaddr, *addr; + void *new; + unsigned int i; + + genlmsg_parse(nlh, 0, attrs, HWSIM_ATTR_MAX, NULL); - if (gnlh->cmd == HWSIM_CMD_FRAME) { - /* we get the attributes*/ - genlmsg_parse(nlh, 0, attrs, HWSIM_ATTR_MAX, NULL); + switch (gnlh->cmd) { + case HWSIM_CMD_FRAME: if (attrs[HWSIM_ATTR_ADDR_TRANSMITTER]) { - u8 *hwaddr = (u8 *)nla_data(attrs[HWSIM_ATTR_ADDR_TRANSMITTER]); + hwaddr = (u8 *)nla_data(attrs[HWSIM_ATTR_ADDR_TRANSMITTER]); unsigned int data_len = nla_len(attrs[HWSIM_ATTR_FRAME]); @@ -687,12 +716,18 @@ static void _process_messages(struct nl_msg *msg, if (data_len < 6 + 6 + 4) return; - sender = get_station_by_addr(ctx, src); + sender = get_station_by_addr(ctx, hwaddr); if (!sender) { - w_flogf(ctx, LOG_ERR, stderr, "Unable to find sender station " MAC_FMT "\n", MAC_ARGS(src)); - return; + sender = get_station_by_used_addr(ctx, src); + if (!sender) { + w_flogf(ctx, LOG_ERR, stderr, + "Unable to find sender station by src=" MAC_FMT " nor hwaddr=" MAC_FMT "\n", + MAC_ARGS(src), MAC_ARGS(hwaddr)); + return; + } + memcpy(sender->hwaddr, hwaddr, ETH_ALEN); } - memcpy(sender->hwaddr, hwaddr, ETH_ALEN); + if (!sender->client) sender->client = client; @@ -712,6 +747,46 @@ static void _process_messages(struct nl_msg *msg, min(tx_rates_len, sizeof(frame->tx_rates))); queue_frame(ctx, sender, frame); } + break; + case HWSIM_CMD_ADD_MAC_ADDR: + if (!attrs[HWSIM_ATTR_ADDR_TRANSMITTER] || + !attrs[HWSIM_ATTR_ADDR_RECEIVER]) + break; + hwaddr = (u8 *)nla_data(attrs[HWSIM_ATTR_ADDR_TRANSMITTER]); + addr = (u8 *)nla_data(attrs[HWSIM_ATTR_ADDR_RECEIVER]); + sender = get_station_by_addr(ctx, hwaddr); + if (!sender) + break; + for (i = 0; i < sender->n_addrs; i++) { + if (memcmp(sender->addrs[i].addr, addr, ETH_ALEN) == 0) + return; + } + new = realloc(sender->addrs, ETH_ALEN * (sender->n_addrs + 1)); + if (!new) + break; + sender->addrs = new; + memcpy(sender->addrs[sender->n_addrs].addr, addr, ETH_ALEN); + sender->n_addrs += 1; + break; + case HWSIM_CMD_DEL_MAC_ADDR: + if (!attrs[HWSIM_ATTR_ADDR_TRANSMITTER] || + !attrs[HWSIM_ATTR_ADDR_RECEIVER]) + break; + hwaddr = (u8 *)nla_data(attrs[HWSIM_ATTR_ADDR_TRANSMITTER]); + addr = (u8 *)nla_data(attrs[HWSIM_ATTR_ADDR_RECEIVER]); + sender = get_station_by_addr(ctx, hwaddr); + if (!sender) + break; + for (i = 0; i < sender->n_addrs; i++) { + if (memcmp(sender->addrs[i].addr, addr, ETH_ALEN)) + continue; + sender->n_addrs -= 1; + memmove(sender->addrs[i].addr, + sender->addrs[sender->n_addrs].addr, + ETH_ALEN); + break; + } + break; } } diff --git a/wmediumd/wmediumd.h b/wmediumd/wmediumd.h index 1d0392616d83..e201788b9b52 100644 --- a/wmediumd/wmediumd.h +++ b/wmediumd/wmediumd.h @@ -29,9 +29,19 @@ #define HWSIM_TX_CTL_NO_ACK (1 << 1) #define HWSIM_TX_STAT_ACK (1 << 2) -#define HWSIM_CMD_REGISTER 1 -#define HWSIM_CMD_FRAME 2 -#define HWSIM_CMD_TX_INFO_FRAME 3 +enum { + HWSIM_CMD_UNSPEC, + HWSIM_CMD_REGISTER, + HWSIM_CMD_FRAME, + HWSIM_CMD_TX_INFO_FRAME, + HWSIM_CMD_NEW_RADIO, + HWSIM_CMD_DEL_RADIO, + HWSIM_CMD_GET_RADIO, + HWSIM_CMD_ADD_MAC_ADDR, + HWSIM_CMD_DEL_MAC_ADDR, + __HWSIM_CMD_MAX, +}; +#define HWSIM_CMD_MAX (_HWSIM_CMD_MAX - 1) /** * enum hwsim_attrs - hwsim netlink attributes @@ -135,6 +145,10 @@ struct wqueue { int cw_max; }; +struct addr { + u8 addr[ETH_ALEN]; +}; + struct station { int index; u8 addr[ETH_ALEN]; /* virtual interface mac address */ @@ -145,6 +159,8 @@ struct station { struct wqueue queues[IEEE80211_NUM_ACS]; struct list_head list; struct client *client; + unsigned int n_addrs; + struct addr *addrs; }; enum client_type {