summaryrefslogtreecommitdiff
path: root/mac80211.c
diff options
context:
space:
mode:
authorDaniel Borkmann <dborkman@redhat.com>2013-05-21 14:05:59 +0200
committerDaniel Borkmann <dborkman@redhat.com>2013-05-21 14:05:59 +0200
commit18d49f2b1ca529d881b8e1064da57b372698a0cd (patch)
treedb7ad5393ce7593a04a9ceb22eca93705b8da1fe /mac80211.c
parent0b0f90c1bbd69e45e4de9f0cce99ac7bb5eca2ec (diff)
mac802.11: only wait for nl ack if unfinished
Jon reported that the setup via netlink of a raw 802.11 mon device fails with: root~/gencfg# trafgen --in beacon.cfg --rfraw --out wlan0 Waiting for netlink ack failed! Let us only wait for it, if really needed. Reported-by: Jon Schipp <jonschipp@gmail.com> Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Diffstat (limited to 'mac80211.c')
-rw-r--r--mac80211.c44
1 files changed, 37 insertions, 7 deletions
diff --git a/mac80211.c b/mac80211.c
index 14bcc93..0b46679 100644
--- a/mac80211.c
+++ b/mac80211.c
@@ -100,11 +100,29 @@ static void nl80211_cleanup(struct nl80211_state *state)
nl_socket_free(state->nl_sock);
}
+static int nl80211_wait_handler(struct nl_msg *msg, void *arg)
+{
+ int *finished = arg;
+
+ *finished = 1;
+
+ return NL_STOP;
+}
+
+static int nl80211_error_handler(struct sockaddr_nl *nla,
+ struct nlmsgerr *err,
+ void *arg)
+{
+ panic("nl80211 returned with error %d\n", err->error);
+}
+
static int nl80211_add_mon_if(struct nl80211_state *state, const char *device,
const char *mondevice)
{
int ifindex, ret;
struct nl_msg *msg;
+ struct nl_cb *cb = NULL;
+ int finished = 0;
ifindex = device_ifindex(device);
@@ -127,16 +145,28 @@ static int nl80211_add_mon_if(struct nl80211_state *state, const char *device,
panic("Cannot send_auto_complete!\n");
}
- ret = nl_wait_for_ack(state->nl_sock);
- if (ret < 0) {
- if (ret == -ENFILE) {
- nlmsg_free(msg);
- return -EBUSY;
- }
+ cb = nl_cb_alloc(NL_CB_CUSTOM);
+ if (!cb)
+ panic("Cannot alloc nl_cb!\n");
- panic("Waiting for netlink ack failed!\n");
+ nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, nl80211_wait_handler, &finished);
+ nl_cb_err(cb, NL_CB_CUSTOM, nl80211_error_handler, NULL);
+
+ nl_recvmsgs(state->nl_sock, cb);
+
+ if (!finished) {
+ ret = nl_wait_for_ack(state->nl_sock);
+ if (ret < 0) {
+ if (ret == -ENFILE) {
+ nlmsg_free(msg);
+ return -EBUSY;
+ }
+
+ panic("Waiting for netlink ack failed!\n");
+ }
}
+ nl_cb_put(cb);
nlmsg_free(msg);
return 0;