2020-03-23 15:26:05

by Johannes Berg

[permalink] [raw]
Subject: [PATCH 0/7] more wmediumd updates

Some of these fix my previous patches, but I also have a patch
for some code I just posted here:
https://lore.kernel.org/r/20200323162358.b397b1a1acef.Ice0536e34e5d96c51f97c374ea8af9551347c7e8@changeid

to make it possible to use random-scan and other stuff, adding
each MAC address from hwsim into the wmediumd "MAC".

Also sanitizer support (helped catch the use-after-free) and a
small fix for not treating management frames as noack, not sure
why that was ever done?

johannes



2020-03-23 15:26:08

by Johannes Berg

[permalink] [raw]
Subject: [PATCH 3/7] wmediumd: fix use-after-free

From: Johannes Berg <[email protected]>

When a client (vhost-user) disconnects when there's a frame from
it on the queue, we have a use-after-free on actually sending it.
Avoid this by clearing all the stations->client pointers that go
away, and removing frames where the source goes away.

Also, while at it, remove the unused frame->dest pointer.

Fixes: 5b4cebfbf6d9 ("wmediumd: add vhost-user support")
---
wmediumd/wmediumd.c | 35 ++++++++++++++++++++++++++++++++---
wmediumd/wmediumd.h | 2 +-
2 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/wmediumd/wmediumd.c b/wmediumd/wmediumd.c
index e7374d9b9639..39797e58f277 100644
--- a/wmediumd/wmediumd.c
+++ b/wmediumd/wmediumd.c
@@ -368,7 +368,6 @@ static void queue_frame(struct wmediumd *ctx, struct station *station,
target += send_time;

frame->duration = send_time;
- frame->dest = deststa ? deststa->client : NULL;
frame->src = station->client;
frame->job.start = target;
frame->job.callback = wmediumd_deliver_frame;
@@ -399,6 +398,37 @@ static void wmediumd_send_to_client(struct wmediumd *ctx,
}
}

+static void wmediumd_remove_client(struct wmediumd *ctx, struct client *client)
+{
+ struct frame *frame, *tmp;
+ struct wqueue *queue;
+ struct station *station;
+ int ac;
+
+ list_for_each_entry(station, &ctx->stations, list) {
+ if (station->client == client)
+ station->client = NULL;
+ }
+
+ list_for_each_entry(station, &ctx->stations, list) {
+ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
+ queue = &station->queues[ac];
+ list_for_each_entry_safe(frame, tmp, &queue->frames,
+ list) {
+ if (frame->src == client) {
+ list_del(&frame->list);
+ usfstl_sched_del_job(&frame->job);
+ free(frame);
+ }
+ }
+ }
+ }
+
+ if (!list_empty(&client->list))
+ list_del(&client->list);
+ free(client);
+}
+
/*
* Report transmit status to the kernel.
*/
@@ -719,8 +749,7 @@ static void wmediumd_vu_disconnected(struct usfstl_vhost_user_dev *dev)
struct client *client = dev->data;

dev->data = NULL;
- list_del(&client->list);
- free(client);
+ wmediumd_remove_client(dev->server->data, client);
}

static const struct usfstl_vhost_user_ops wmediumd_vu_ops = {
diff --git a/wmediumd/wmediumd.h b/wmediumd/wmediumd.h
index d4ce3a1df15d..06b356516a15 100644
--- a/wmediumd/wmediumd.h
+++ b/wmediumd/wmediumd.h
@@ -210,7 +210,7 @@ struct hwsim_tx_rate {
struct frame {
struct list_head list; /* frame queue list */
struct usfstl_job job;
- struct client *src, *dest;
+ struct client *src;
bool acked;
u64 cookie;
u32 freq;
--
2.25.1

2020-03-23 15:26:10

by Johannes Berg

[permalink] [raw]
Subject: [PATCH 2/7] wmediumd: pass actual signal to hwsim

From: Johannes Berg <[email protected]>

Not clear why, but despite actually having the signal, wmediumd
always passes -50 for the signal strength. Fix that and pass the
actual signal value.

---
wmediumd/wmediumd.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/wmediumd/wmediumd.c b/wmediumd/wmediumd.c
index 5e89e83ca72b..e7374d9b9639 100644
--- a/wmediumd/wmediumd.c
+++ b/wmediumd/wmediumd.c
@@ -464,7 +464,7 @@ static void send_cloned_frame_msg(struct wmediumd *ctx, struct station *dst,
nla_put(msg, HWSIM_ATTR_FRAME, data_len, data) ||
nla_put_u32(msg, HWSIM_ATTR_RX_RATE, 1) ||
nla_put_u32(msg, HWSIM_ATTR_FREQ, freq) ||
- nla_put_u32(msg, HWSIM_ATTR_SIGNAL, -50)) {
+ nla_put_u32(msg, HWSIM_ATTR_SIGNAL, signal)) {
w_logf(ctx, LOG_ERR, "%s: Failed to fill a payload\n", __func__);
goto out;
}
--
2.25.1

2020-03-23 15:26:11

by Johannes Berg

[permalink] [raw]
Subject: [PATCH 5/7] wmediumd: support compilation with asan/ubsan

From: Johannes Berg <[email protected]>

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)
--
2.25.1

2020-03-23 15:26:15

by Johannes Berg

[permalink] [raw]
Subject: [PATCH 7/7] wmediumd: don't treat management frames as noack

From: Johannes Berg <[email protected]>

It's incorrect to treat management frames as noack, they're
retransmitted just like any other frame; fix this.

---
wmediumd/wmediumd.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/wmediumd/wmediumd.c b/wmediumd/wmediumd.c
index 14ea63b6ba69..d756dc4be5b9 100644
--- a/wmediumd/wmediumd.c
+++ b/wmediumd/wmediumd.c
@@ -321,7 +321,7 @@ static void queue_frame(struct wmediumd *ctx, struct station *station,
}
frame->signal = snr + NOISE_LEVEL;

- noack = frame_is_mgmt(frame) || is_multicast_ether_addr(dest);
+ noack = is_multicast_ether_addr(dest);

double choice = drand48();

--
2.25.1

2020-03-23 15:26:28

by Johannes Berg

[permalink] [raw]
Subject: [PATCH 6/7] wmediumd: track dynamic station addresses

From: Johannes Berg <[email protected]>

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 {
--
2.25.1

2020-03-23 15:26:31

by Johannes Berg

[permalink] [raw]
Subject: [PATCH 4/7] wmediumd: add a unix-domain control socket

From: Johannes Berg <[email protected]>

Add a control socket that - right now - can be used to also
transmit/receive frames, actually carrying netlink messages;
however, for that a register/unregister is provided so that
we can extend the protocol to a pure control protocol in the
future.

---
wmediumd/api.h | 41 +++++++++++++++++
wmediumd/wmediumd.c | 110 +++++++++++++++++++++++++++++++++++++++++++-
wmediumd/wmediumd.h | 4 ++
3 files changed, 153 insertions(+), 2 deletions(-)
create mode 100644 wmediumd/api.h

diff --git a/wmediumd/api.h b/wmediumd/api.h
new file mode 100644
index 000000000000..6ecaa7bd94b9
--- /dev/null
+++ b/wmediumd/api.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2020 Intel Corporation
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef _WMEDIUMD_API_H
+#define _WMEDIUMD_API_H
+
+enum wmediumd_message {
+ /* invalid message */
+ WMEDIUMD_MSG_INVALID,
+
+ /* ACK, returned for each message for synchronisation */
+ WMEDIUMD_MSG_ACK,
+
+ /*
+ * Register/unregister for frames, this may be a pure control
+ * socket which doesn't want to see frames.
+ */
+ WMEDIUMD_MSG_REGISTER,
+ WMEDIUMD_MSG_UNREGISTER,
+
+ /*
+ * netlink message, the data is the entire netlink message,
+ * this is used to communicate frame TX/RX in the familiar
+ * netlink format, to avoid having a special format
+ */
+ WMEDIUMD_MSG_NETLINK,
+};
+
+struct wmediumd_message_header {
+ /* type of message - see enum wmediumd_message */
+ uint32_t type;
+ /* data length */
+ uint32_t data_len;
+
+ /* variable-length data according to the message type */
+ uint8_t data[];
+};
+
+#endif /* _WMEDIUMD_API_H */
diff --git a/wmediumd/wmediumd.c b/wmediumd/wmediumd.c
index 39797e58f277..a1e16defd144 100644
--- a/wmediumd/wmediumd.c
+++ b/wmediumd/wmediumd.c
@@ -39,10 +39,12 @@
#include <usfstl/sched.h>
#include <usfstl/schedctrl.h>
#include <usfstl/vhost.h>
+#include <usfstl/uds.h>

#include "wmediumd.h"
#include "ieee80211.h"
#include "config.h"
+#include "api.h"

USFSTL_SCHEDULER(scheduler);

@@ -381,6 +383,7 @@ static void wmediumd_send_to_client(struct wmediumd *ctx,
struct client *client,
struct nl_msg *msg)
{
+ struct wmediumd_message_header hdr;
size_t len;
int ret;

@@ -395,6 +398,15 @@ static void wmediumd_send_to_client(struct wmediumd *ctx,
usfstl_vhost_user_dev_notify(client->dev, HWSIM_VQ_RX,
(void *)nlmsg_hdr(msg), len);
break;
+ case CLIENT_API_SOCK:
+ len = nlmsg_total_size(nlmsg_datalen(nlmsg_hdr(msg)));
+ hdr.type = WMEDIUMD_MSG_NETLINK;
+ hdr.data_len = len;
+ write(client->loop.fd, &hdr, sizeof(hdr));
+ write(client->loop.fd, (void *)nlmsg_hdr(msg), len);
+ /* read the ACK back */
+ read(client->loop.fd, &hdr, sizeof(hdr));
+ break;
}
}

@@ -758,6 +770,93 @@ static const struct usfstl_vhost_user_ops wmediumd_vu_ops = {
.disconnected = wmediumd_vu_disconnected,
};

+static void wmediumd_api_handler(struct usfstl_loop_entry *entry)
+{
+ struct client *client = container_of(entry, struct client, loop);
+ struct wmediumd *ctx = entry->data;
+ struct wmediumd_message_header hdr;
+ enum wmediumd_message response = WMEDIUMD_MSG_ACK;
+ struct nl_msg *nlmsg;
+ unsigned char *data;
+ ssize_t len;
+
+ len = read(entry->fd, &hdr, sizeof(hdr));
+ if (len != sizeof(hdr))
+ goto disconnect;
+
+ /* safety valve */
+ if (hdr.data_len > 1024 * 1024)
+ goto disconnect;
+
+ data = malloc(hdr.data_len);
+ if (!data)
+ goto disconnect;
+
+ len = read(entry->fd, data, hdr.data_len);
+ if (len != hdr.data_len)
+ goto disconnect;
+
+ switch (hdr.type) {
+ case WMEDIUMD_MSG_REGISTER:
+ if (!list_empty(&client->list)) {
+ response = WMEDIUMD_MSG_INVALID;
+ break;
+ }
+ list_add(&client->list, &ctx->clients);
+ break;
+ case WMEDIUMD_MSG_UNREGISTER:
+ if (list_empty(&client->list)) {
+ response = WMEDIUMD_MSG_INVALID;
+ break;
+ }
+ list_del_init(&client->list);
+ break;
+ case WMEDIUMD_MSG_NETLINK:
+ if (!nlmsg_ok((const struct nlmsghdr *)data, len)) {
+ response = WMEDIUMD_MSG_INVALID;
+ break;
+ }
+
+ nlmsg = nlmsg_convert((struct nlmsghdr *)data);
+ if (!nlmsg)
+ break;
+
+ _process_messages(nlmsg, ctx, client);
+
+ nlmsg_free(nlmsg);
+ break;
+ default:
+ response = WMEDIUMD_MSG_INVALID;
+ break;
+ }
+
+ /* return a response */
+ hdr.type = response;
+ hdr.data_len = 0;
+ len = write(entry->fd, &hdr, sizeof(hdr));
+ if (len != sizeof(hdr))
+ goto disconnect;
+
+ return;
+disconnect:
+ usfstl_loop_unregister(&client->loop);
+ wmediumd_remove_client(ctx, client);
+}
+
+static void wmediumd_api_connected(int fd, void *data)
+{
+ struct wmediumd *ctx = data;
+ struct client *client;
+
+ client = calloc(1, sizeof(*client));
+ client->type = CLIENT_API_SOCK;
+ client->loop.fd = fd;
+ client->loop.data = ctx;
+ client->loop.handler = wmediumd_api_handler;
+ usfstl_loop_register(&client->loop);
+ INIT_LIST_HEAD(&client->list);
+}
+
/*
* Register with the kernel to start receiving new frames.
*/
@@ -862,6 +961,7 @@ static void print_help(int exval)
printf(" -x FILE set input PER file\n");
printf(" -t socket set the time control socket\n");
printf(" -u socket expose vhost-user socket, don't use netlink\n");
+ printf(" -a socket expose wmediumd API socket\n");
printf(" -n force netlink use even with vhost-user\n");

exit(exval);
@@ -873,7 +973,7 @@ int main(int argc, char *argv[])
struct wmediumd ctx = {};
char *config_file = NULL;
char *per_file = NULL;
- const char *time_socket = NULL;
+ const char *time_socket = NULL, *api_socket = NULL;
struct usfstl_sched_ctrl ctrl = {};
struct usfstl_vhost_user_server vusrv = {
.ops = &wmediumd_vu_ops,
@@ -896,7 +996,7 @@ int main(int argc, char *argv[])
unsigned long int parse_log_lvl;
char* parse_end_token;

- while ((opt = getopt(argc, argv, "hVc:l:x:t:u:n")) != -1) {
+ while ((opt = getopt(argc, argv, "hVc:l:x:t:u:a:n")) != -1) {
switch (opt) {
case 'h':
print_help(EXIT_SUCCESS);
@@ -934,6 +1034,9 @@ int main(int argc, char *argv[])
case 'u':
vusrv.socket = optarg;
break;
+ case 'a':
+ api_socket = optarg;
+ break;
case 'n':
force_netlink = true;
break;
@@ -1004,6 +1107,9 @@ int main(int argc, char *argv[])
w_logf(&ctx, LOG_NOTICE, "REGISTER SENT!\n");
}

+ if (api_socket)
+ usfstl_uds_create(api_socket, wmediumd_api_connected, &ctx);
+
while (1) {
if (time_socket) {
usfstl_sched_next(&scheduler);
diff --git a/wmediumd/wmediumd.h b/wmediumd/wmediumd.h
index 06b356516a15..1d0392616d83 100644
--- a/wmediumd/wmediumd.h
+++ b/wmediumd/wmediumd.h
@@ -150,6 +150,7 @@ struct station {
enum client_type {
CLIENT_NETLINK,
CLIENT_VHOST_USER,
+ CLIENT_API_SOCK,
};

struct client {
@@ -163,6 +164,9 @@ struct client {

/* for vhost-user */
struct usfstl_vhost_user_dev *dev;
+
+ /* for API socket */
+ struct usfstl_loop_entry loop;
};

struct wmediumd {
--
2.25.1

2020-03-23 15:26:33

by Johannes Berg

[permalink] [raw]
Subject: [PATCH 1/7] wmediumd: mark various functions static

From: Johannes Berg <[email protected]>

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");
--
2.25.1

2020-03-23 19:09:19

by Bob Copeland

[permalink] [raw]
Subject: Re: [PATCH 7/7] wmediumd: don't treat management frames as noack

On Mon, Mar 23, 2020 at 04:25:42PM +0100, Johannes Berg wrote:
> From: Johannes Berg <[email protected]>
>
> It's incorrect to treat management frames as noack, they're
> retransmitted just like any other frame; fix this.

I think it was just a hack to make mesh paths establish even
if snr was terrible, obviously not realistic. Thanks!

--
Bob Copeland %% https://bobcopeland.com/

2020-03-23 19:12:28

by Bob Copeland

[permalink] [raw]
Subject: Re: [PATCH 0/7] more wmediumd updates

On Mon, Mar 23, 2020 at 04:25:35PM +0100, Johannes Berg wrote:
> Some of these fix my previous patches, but I also have a patch
> for some code I just posted here:
> https://lore.kernel.org/r/20200323162358.b397b1a1acef.Ice0536e34e5d96c51f97c374ea8af9551347c7e8@changeid
>
> to make it possible to use random-scan and other stuff, adding
> each MAC address from hwsim into the wmediumd "MAC".
>
> Also sanitizer support (helped catch the use-after-free) and a
> small fix for not treating management frames as noack, not sure
> why that was ever done?

All applied, thanks.

--
Bob Copeland %% https://bobcopeland.com/

2020-03-23 20:15:33

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH 7/7] wmediumd: don't treat management frames as noack

On Mon, 2020-03-23 at 15:08 -0400, Bob Copeland wrote:
> On Mon, Mar 23, 2020 at 04:25:42PM +0100, Johannes Berg wrote:
> > From: Johannes Berg <[email protected]>
> >
> > It's incorrect to treat management frames as noack, they're
> > retransmitted just like any other frame; fix this.
>
> I think it was just a hack to make mesh paths establish even
> if snr was terrible, obviously not realistic. Thanks!

But wouldn't it be the other way around, i.e. they're *less* likely to
be established without retries (noack)?

Anyway, doesn't really matter, just caught my eye there the other day :)

johannes

2020-03-23 20:37:40

by Bob Copeland

[permalink] [raw]
Subject: Re: [PATCH 7/7] wmediumd: don't treat management frames as noack

On Mon, Mar 23, 2020 at 09:12:39PM +0100, Johannes Berg wrote:
> But wouldn't it be the other way around, i.e. they're *less* likely to
> be established without retries (noack)?
>
> Anyway, doesn't really matter, just caught my eye there the other day :)

Oh, yeah, well, dunno :)

--
Bob Copeland %% https://bobcopeland.com/