+++ /dev/null
---- a/Makefile
-+++ b/Makefile
-@@ -3,7 +3,7 @@
- MAKEFLAGS += --no-print-directory
-
- PREFIX ?= /usr
--BINDIR ?= $(PREFIX)/bin
-+SBINDIR ?= $(PREFIX)/sbin
- MANDIR ?= $(PREFIX)/share/man
- PKG_CONFIG ?= pkg-config
-
-@@ -85,8 +85,8 @@ check:
-
- install: iw iw.8.gz
- @$(NQ) ' INST iw'
-- $(Q)$(MKDIR) $(DESTDIR)$(BINDIR)
-- $(Q)$(INSTALL) -m 755 -t $(DESTDIR)$(BINDIR) iw
-+ $(Q)$(MKDIR) $(DESTDIR)$(SBINDIR)
-+ $(Q)$(INSTALL) -m 755 -t $(DESTDIR)$(SBINDIR) iw
- @$(NQ) ' INST iw.8'
- $(Q)$(MKDIR) $(DESTDIR)$(MANDIR)/man8/
- $(Q)$(INSTALL) -m 644 -t $(DESTDIR)$(MANDIR)/man8/ iw.8.gz
---- a/iw.c
-+++ b/iw.c
-@@ -223,9 +223,12 @@ static int phy_lookup(char *name)
- if (fd < 0)
- return -1;
- pos = read(fd, buf, sizeof(buf) - 1);
-- if (pos < 0)
-+ if (pos < 0) {
-+ close(fd);
- return -1;
-+ }
- buf[pos] = '\0';
-+ close(fd);
- return atoi(buf);
- }
-
---- a/nl80211.h
-+++ b/nl80211.h
-@@ -262,6 +262,9 @@
- * reasons, for this the %NL80211_ATTR_DISCONNECTED_BY_AP and
- * %NL80211_ATTR_REASON_CODE attributes are used.
- *
-+ * @NL80211_CMD_SET_WIPHY_NETNS: Set a wiphy's netns. Note that all devices
-+ * associated with this wiphy must be down and will follow.
-+ *
- * @NL80211_CMD_MAX: highest used command number
- * @__NL80211_CMD_AFTER_LAST: internal use
- */
-@@ -336,6 +339,8 @@ enum nl80211_commands {
- NL80211_CMD_ROAM,
- NL80211_CMD_DISCONNECT,
-
-+ NL80211_CMD_SET_WIPHY_NETNS,
-+
- /* add new commands above here */
-
- /* used to define NL80211_CMD_MAX below */
-@@ -475,10 +480,6 @@ enum nl80211_commands {
- * @NL80211_ATTR_SCAN_FREQUENCIES: nested attribute with frequencies (in MHz)
- * @NL80211_ATTR_SCAN_SSIDS: nested attribute with SSIDs, leave out for passive
- * scanning and include a zero-length SSID (wildcard) for wildcard scan
-- * @NL80211_ATTR_SCAN_GENERATION: the scan generation increases whenever the
-- * scan result list changes (BSS expired or added) so that applications
-- * can verify that they got a single, consistent snapshot (when all dump
-- * messages carried the same generation number)
- * @NL80211_ATTR_BSS: scan result BSS
- *
- * @NL80211_ATTR_REG_INITIATOR: indicates who requested the regulatory domain
-@@ -573,6 +574,16 @@ enum nl80211_commands {
- * and join_ibss(), key information is in a nested attribute each
- * with %NL80211_KEY_* sub-attributes
- *
-+ * @NL80211_ATTR_PID: Process ID of a network namespace.
-+ *
-+ * @NL80211_ATTR_GENERATION: Used to indicate consistent snapshots for
-+ * dumps. This number increases whenever the object list being
-+ * dumped changes, and as such userspace can verify that it has
-+ * obtained a complete and consistent snapshot by verifying that
-+ * all dump messages contain the same generation number. If it
-+ * changed then the list changed and the dump should be repeated
-+ * completely from scratch.
-+ *
- * @NL80211_ATTR_MAX: highest attribute number currently defined
- * @__NL80211_ATTR_AFTER_LAST: internal use
- */
-@@ -644,7 +655,7 @@ enum nl80211_attrs {
-
- NL80211_ATTR_SCAN_FREQUENCIES,
- NL80211_ATTR_SCAN_SSIDS,
-- NL80211_ATTR_SCAN_GENERATION,
-+ NL80211_ATTR_GENERATION, /* replaces old SCAN_GENERATION */
- NL80211_ATTR_BSS,
-
- NL80211_ATTR_REG_INITIATOR,
-@@ -701,12 +712,17 @@ enum nl80211_attrs {
- NL80211_ATTR_KEY,
- NL80211_ATTR_KEYS,
-
-+ NL80211_ATTR_PID,
-+
- /* add attributes here, update the policy in nl80211.c */
-
- __NL80211_ATTR_AFTER_LAST,
- NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1
- };
-
-+/* source-level API compatibility */
-+#define NL80211_ATTR_SCAN_GENERATION NL80211_ATTR_GENERATION
-+
- /*
- * Allow user space programs to use #ifdef on new attributes by defining them
- * here
---- a/phy.c
-+++ b/phy.c
-@@ -140,3 +140,27 @@ static int handle_rts(struct nl80211_sta
- COMMAND(set, rts, "<rts threshold|off>",
- NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_rts,
- "Set rts threshold.");
-+
-+static int handle_netns(struct nl80211_state *state,
-+ struct nl_cb *cb,
-+ struct nl_msg *msg,
-+ int argc, char **argv)
-+{
-+ char *end;
-+
-+ if (argc != 1)
-+ return 1;
-+
-+ NLA_PUT_U32(msg, NL80211_ATTR_PID,
-+ strtoul(argv[0], &end, 10));
-+
-+ if (*end != '\0')
-+ return 1;
-+
-+ return 0;
-+ nla_put_failure:
-+ return -ENOBUFS;
-+}
-+COMMAND(set, netns, "<pid>",
-+ NL80211_CMD_SET_WIPHY_NETNS, 0, CIB_PHY, handle_netns,
-+ "Put this wireless device into a different network namespace");
---- a/station.c
-+++ b/station.c
-@@ -127,7 +127,7 @@ static int print_sta_handler(struct nl_m
- printf("\n\tmesh plid:\t%d",
- nla_get_u16(sinfo[NL80211_STA_INFO_PLID]));
- if (sinfo[NL80211_STA_INFO_PLINK_STATE]) {
-- switch (nla_get_u16(sinfo[NL80211_STA_INFO_PLINK_STATE])) {
-+ switch (nla_get_u8(sinfo[NL80211_STA_INFO_PLINK_STATE])) {
- case LISTEN:
- strcpy(state_name, "LISTEN");
- break;
+++ /dev/null
---- a/interface.c
-+++ b/interface.c
-@@ -137,6 +137,20 @@ static int get_if_type(int *argc, char *
- return 2;
- }
-
-+static int parse_wds_flag(const char *value, struct nl_msg *msg)
-+{
-+ if (strcmp(value, "on") == 0)
-+ NLA_PUT_U8(msg, NL80211_ATTR_4ADDR, 1);
-+ else if (strcmp(value, "off") == 0)
-+ NLA_PUT_U8(msg, NL80211_ATTR_4ADDR, 0);
-+ else
-+ return 1;
-+ return 0;
-+
-+nla_put_failure:
-+ return 1;
-+}
-+
- static int handle_interface_add(struct nl80211_state *state,
- struct nl_cb *cb,
- struct nl_msg *msg,
-@@ -168,6 +182,15 @@ static int handle_interface_add(struct n
- mesh_id = argv[0];
- argc--;
- argv++;
-+ } else if (strcmp(argv[0], "wds") == 0) {
-+ argc--;
-+ argv++;
-+ if (parse_wds_flag(argv[0], msg)) {
-+ fprintf(stderr, "wds error\n");
-+ return 2;
-+ }
-+ argc--;
-+ argv++;
- } else if (strcmp(argv[0], "flags") == 0) {
- argc--;
- argv++;
-@@ -192,14 +215,14 @@ static int handle_interface_add(struct n
- nla_put_failure:
- return -ENOBUFS;
- }
--COMMAND(interface, add, "<name> type <type> [mesh_id <meshid>] [flags <flag>*]",
-+COMMAND(interface, add, "<name> type <type> [mesh_id <meshid>] [wds on|off] [flags <flag>*]",
- NL80211_CMD_NEW_INTERFACE, 0, CIB_PHY, handle_interface_add,
- "Add a new virtual interface with the given configuration.\n"
- IFACE_TYPES "\n\n"
- "The flags are only used for monitor interfaces, valid flags are:\n"
- VALID_FLAGS "\n\n"
- "The mesh_id is used only for mesh mode.");
--COMMAND(interface, add, "<name> type <type> [mesh_id <meshid>] [flags <flag>*]",
-+COMMAND(interface, add, "<name> type <type> [mesh_id <meshid>] [wds on|off] [flags <flag>*]",
- NL80211_CMD_NEW_INTERFACE, 0, CIB_NETDEV, handle_interface_add, NULL);
-
- static int handle_interface_del(struct nl80211_state *state,
---- a/nl80211.h
-+++ b/nl80211.h
-@@ -584,6 +584,8 @@ enum nl80211_commands {
- * changed then the list changed and the dump should be repeated
- * completely from scratch.
- *
-+ * @NL80211_ATTR_4ADDR: Use 4-address frames on a virtual interface
-+ *
- * @NL80211_ATTR_MAX: highest attribute number currently defined
- * @__NL80211_ATTR_AFTER_LAST: internal use
- */
-@@ -714,6 +716,8 @@ enum nl80211_attrs {
-
- NL80211_ATTR_PID,
-
-+ NL80211_ATTR_4ADDR,
-+
- /* add attributes here, update the policy in nl80211.c */
-
- __NL80211_ATTR_AFTER_LAST,
+++ /dev/null
---- a/station.c
-+++ b/station.c
-@@ -196,7 +196,7 @@ COMMAND(station, del, "<MAC address>",
- NL80211_CMD_DEL_STATION, 0, CIB_NETDEV, handle_station_get,
- "Remove the given station entry (use with caution!)");
-
--static int handle_station_set(struct nl80211_state *state,
-+static int handle_station_set_plink(struct nl80211_state *state,
- struct nl_cb *cb,
- struct nl_msg *msg,
- int argc, char **argv)
-@@ -241,9 +241,56 @@ static int handle_station_set(struct nl8
- return -ENOBUFS;
- }
- COMMAND(station, set, "<MAC address> plink_action <open|block>",
-- NL80211_CMD_SET_STATION, 0, CIB_NETDEV, handle_station_set,
-+ NL80211_CMD_SET_STATION, 0, CIB_NETDEV, handle_station_set_plink,
- "Set mesh peer link action for this station (peer).");
-
-+static int handle_station_set_vlan(struct nl80211_state *state,
-+ struct nl_cb *cb,
-+ struct nl_msg *msg,
-+ int argc, char **argv)
-+{
-+ unsigned char mac_addr[ETH_ALEN];
-+ unsigned long sta_vlan = 0;
-+ char *err = NULL;
-+
-+ if (argc < 3)
-+ return 1;
-+
-+ if (mac_addr_a2n(mac_addr, argv[0])) {
-+ fprintf(stderr, "invalid mac address\n");
-+ return 2;
-+ }
-+ argc--;
-+ argv++;
-+
-+ if (strcmp("vlan", argv[0]) != 0)
-+ return 1;
-+ argc--;
-+ argv++;
-+
-+ sta_vlan = strtoul(argv[0], &err, 0);
-+ if (err && *err) {
-+ fprintf(stderr, "invalid vlan id\n");
-+ return 2;
-+ }
-+ argc--;
-+ argv++;
-+
-+ if (argc)
-+ return 1;
-+
-+ NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
-+ NLA_PUT_U32(msg, NL80211_ATTR_STA_VLAN, sta_vlan);
-+
-+ return 0;
-+ nla_put_failure:
-+ return -ENOBUFS;
-+}
-+COMMAND(station, set, "<MAC address> vlan <ifindex>",
-+ NL80211_CMD_SET_STATION, 0, CIB_NETDEV, handle_station_set_vlan,
-+ "Set an AP VLAN for this station.");
-+
-+
- static int handle_station_dump(struct nl80211_state *state,
- struct nl_cb *cb,
- struct nl_msg *msg,