netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/10] d80211: bugfixes and reducing number of interfaces
@ 2006-04-21 20:53 Jiri Benc
  2006-04-21 20:53 ` [PATCH 1/10] d80211: fix SIOCGIWESSID ioctl Jiri Benc
                   ` (9 more replies)
  0 siblings, 10 replies; 18+ messages in thread
From: Jiri Benc @ 2006-04-21 20:53 UTC (permalink / raw)
  To: netdev

Following patches can be also obtained from:
git://git.kernel.org/pub/scm/linux/kernel/git/jbenc/dscape.git master

The main purpose of these patches is to reduce the number of network
interfaces presented to userspace; there are also some important bugfixes
among them (mainly 3rd patch).


Jiri Benc:
      d80211: fix SIOCGIWESSID ioctl
      d80211: use is_multicast_ether_addr
      d80211: fix Oops caused by packets sent directly to master device
      d80211: don't use pointer in ieee80211_tx_control
      d80211: per-interface SSID
      d80211: per-interface generic_elem
      d80211: get rid of default AP interface
      d80211: get rid of default management interface
      d80211: rename master interface
      d80211: add one default interface

 include/net/d80211.h         |   35 +--
 net/d80211/ieee80211.c       |  436 ++++++++++++++++++++++++-------------------
 net/d80211/ieee80211_i.h     |   34 ++-
 net/d80211/ieee80211_iface.c |   96 ++++++++-
 net/d80211/ieee80211_ioctl.c |   95 +++++----
 net/d80211/ieee80211_proc.c  |    9 
 net/d80211/ieee80211_sta.c   |    3 
 net/d80211/ieee80211_sysfs.c |    3 
 net/d80211/wme.c             |    3 
 9 files changed, 430 insertions(+), 284 deletions(-)

-- 
Jiri Benc
SUSE Labs

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 1/10] d80211: fix SIOCGIWESSID ioctl
  2006-04-21 20:53 [PATCH 0/10] d80211: bugfixes and reducing number of interfaces Jiri Benc
@ 2006-04-21 20:53 ` Jiri Benc
  2006-04-21 20:53 ` [PATCH 2/10] d80211: use is_multicast_ether_addr Jiri Benc
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 18+ messages in thread
From: Jiri Benc @ 2006-04-21 20:53 UTC (permalink / raw)
  To: netdev

Flags for SIOCGIWESSID ioctl were not set, thus SSID was never displayed by
iwconfig.

Signed-off-by: Jiri Benc <jbenc@suse.cz>

---

 net/d80211/ieee80211_ioctl.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

56d18689a4964cc2e906cfb5164b31649735774a
diff --git a/net/d80211/ieee80211_ioctl.c b/net/d80211/ieee80211_ioctl.c
index dfa0ef7..792fcf4 100644
--- a/net/d80211/ieee80211_ioctl.c
+++ b/net/d80211/ieee80211_ioctl.c
@@ -1782,8 +1782,11 @@ static int ieee80211_ioctl_giwessid(stru
 	if (sdata->type == IEEE80211_IF_TYPE_STA ||
 	    sdata->type == IEEE80211_IF_TYPE_IBSS) {
 		int res = ieee80211_sta_get_ssid(dev, ssid, &len);
-		if (res == 0)
+		if (res == 0) {
 			data->length = len;
+			data->flags = 1;
+		} else
+			data->flags = 0;
 		return res;
 	}
 
@@ -1792,6 +1795,7 @@ static int ieee80211_ioctl_giwessid(stru
 		len = IW_ESSID_MAX_SIZE;
 	memcpy(ssid, local->conf.ssid, len);
 	data->length = len;
+	data->flags = 1;
 	return 0;
 }
 
-- 
1.3.0


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 2/10] d80211: use is_multicast_ether_addr
  2006-04-21 20:53 [PATCH 0/10] d80211: bugfixes and reducing number of interfaces Jiri Benc
  2006-04-21 20:53 ` [PATCH 1/10] d80211: fix SIOCGIWESSID ioctl Jiri Benc
@ 2006-04-21 20:53 ` Jiri Benc
  2006-04-21 20:53 ` [PATCH 3/10] d80211: fix Oops caused by packets sent directly to master device Jiri Benc
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 18+ messages in thread
From: Jiri Benc @ 2006-04-21 20:53 UTC (permalink / raw)
  To: netdev

Replace custom MULTICAST_ADDR macro with is_multicast_ether_addr function.

Signed-off-by: Jiri Benc <jbenc@suse.cz>

---

 net/d80211/ieee80211.c   |   29 +++++++++++++++--------------
 net/d80211/ieee80211_i.h |    2 --
 2 files changed, 15 insertions(+), 16 deletions(-)

f01885676fc8b7adb838b110b4f6449cbb17dae5
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index 64cc66f..eb701ac 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -731,7 +731,7 @@ ieee80211_tx_h_misc(struct ieee80211_txr
 	u16 dur;
 	struct ieee80211_tx_control *control = tx->u.tx.control;
 
-	if (!MULTICAST_ADDR(hdr->addr1)) {
+	if (!is_multicast_ether_addr(hdr->addr1)) {
 		if (tx->skb->len >= tx->local->rts_threshold &&
 		    tx->local->rts_threshold < IEEE80211_MAX_RTS_THRESHOLD) {
 			control->use_rts_cts = 1;
@@ -766,7 +766,7 @@ ieee80211_tx_h_misc(struct ieee80211_txr
 	/* Setup duration field for the first fragment of the frame. Duration
 	 * for remaining fragments will be updated when they are being sent
 	 * to low-level driver in ieee80211_tx(). */
-	dur = ieee80211_duration(tx, MULTICAST_ADDR(hdr->addr1),
+	dur = ieee80211_duration(tx, is_multicast_ether_addr(hdr->addr1),
 				 tx->fragmented ? tx->u.tx.extra_frag[0]->len :
 				 0);
 	hdr->duration_id = cpu_to_le16(dur);
@@ -1072,8 +1072,8 @@ static void inline ieee80211_tx_prepare(
 	tx->fc = le16_to_cpu(hdr->frame_control);
         control->power_level = local->conf.power_level;
 	tx->u.tx.control = control;
-        tx->u.tx.unicast = !MULTICAST_ADDR(hdr->addr1);
-        control->no_ack = MULTICAST_ADDR(hdr->addr1);
+        tx->u.tx.unicast = !is_multicast_ether_addr(hdr->addr1);
+        control->no_ack = is_multicast_ether_addr(hdr->addr1);
 	tx->fragmented = local->fragmentation_threshold <
 		IEEE80211_MAX_FRAG_THRESHOLD && tx->u.tx.unicast &&
 		skb->len + 4 /* FCS */ > local->fragmentation_threshold &&
@@ -2229,7 +2229,7 @@ ieee80211_rx_h_data(struct ieee80211_txr
 
 	if (local->bridge_packets && (sdata->type == IEEE80211_IF_TYPE_AP
 	    || sdata->type == IEEE80211_IF_TYPE_VLAN)) {
-		if (MULTICAST_ADDR(skb->data)) {
+		if (is_multicast_ether_addr(skb->data)) {
 			/* send multicast frames both to higher layers in
 			 * local net stack and back to the wireless media */
 			skb2 = skb_copy(skb, GFP_ATOMIC);
@@ -2659,7 +2659,8 @@ ieee80211_rx_h_defragment(struct ieee802
 	frag = WLAN_GET_SEQ_FRAG(sc);
 
 	if (likely((!(rx->fc & WLAN_FC_MOREFRAG) && frag == 0) ||
-		   (rx->skb)->len < 24 || MULTICAST_ADDR(hdr->addr1))) {
+		   (rx->skb)->len < 24 ||
+		   is_multicast_ether_addr(hdr->addr1))) {
 		/* not fragmented */
 		goto out;
 	}
@@ -2747,7 +2748,7 @@ ieee80211_rx_h_defragment(struct ieee802
  out:
 	if (rx->sta)
 		rx->sta->rx_packets++;
-	if (MULTICAST_ADDR(hdr->addr1))
+	if (is_multicast_ether_addr(hdr->addr1))
 		rx->local->dot11MulticastReceivedFrameCount++;
 #ifdef IEEE80211_LEDS
         else
@@ -2778,7 +2779,7 @@ ieee80211_rx_h_check(struct ieee80211_tx
 	hdr = (struct ieee80211_hdr *) rx->skb->data;
 
 	/* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */
-	if (rx->sta && !MULTICAST_ADDR(hdr->addr1)) {
+	if (rx->sta && !is_multicast_ether_addr(hdr->addr1)) {
 		if (unlikely(rx->fc & WLAN_FC_RETRY &&
 			     rx->sta->last_seq_ctrl[rx->u.rx.queue] ==
 			     hdr->seq_ctrl)) {
@@ -2900,7 +2901,7 @@ ieee80211_rx_h_sta_process(struct ieee80
 		if (memcmp(bssid, rx->sdata->u.sta.bssid, ETH_ALEN) == 0)
 			sta->last_rx = jiffies;
 	} else
-	if (!MULTICAST_ADDR(hdr->addr1) ||
+	if (!is_multicast_ether_addr(hdr->addr1) ||
 	    rx->sdata->type == IEEE80211_IF_TYPE_STA) {
 		/* Update last_rx only for unicast frames in order to prevent
 		 * the Probe Request frames (the only broadcast frames from a
@@ -3415,7 +3416,7 @@ ieee80211_tx_h_load_stats(struct ieee802
 		hdrtime = CHAN_UTIL_HDR_LONG;
 
 	load = hdrtime;
-	if (!MULTICAST_ADDR(hdr->addr1))
+	if (!is_multicast_ether_addr(hdr->addr1))
 		load += hdrtime;
 
 	if (tx->u.tx.control->use_rts_cts)
@@ -3481,7 +3482,7 @@ ieee80211_rx_h_load_stats(struct ieee802
 		hdrtime = CHAN_UTIL_HDR_LONG;
 
 	load = hdrtime;
-	if (!MULTICAST_ADDR(hdr->addr1))
+	if (!is_multicast_ether_addr(hdr->addr1))
 		load += hdrtime;
 
 	load += skb->len * rate->rate_inv;
@@ -3792,7 +3793,7 @@ #endif /* IEEE80211_LEDS */
         if (status->ack) {
 		if (frag == 0) {
 			local->dot11TransmittedFrameCount++;
-			if (MULTICAST_ADDR(hdr->addr1))
+			if (is_multicast_ether_addr(hdr->addr1))
 				local->dot11MulticastTransmittedFrameCount++;
 			if (status->retry_count > 0)
 				local->dot11RetryCount++;
@@ -3804,8 +3805,8 @@ #endif /* IEEE80211_LEDS */
 		 * with an individual address in the address 1 field or an MPDU
 		 * with a multicast address in the address 1 field of type Data
 		 * or Management. */
-		if (!MULTICAST_ADDR(hdr->addr1) || type == WLAN_FC_TYPE_DATA ||
-		    type == WLAN_FC_TYPE_MGMT)
+		if (!is_multicast_ether_addr(hdr->addr1) ||
+		    type == WLAN_FC_TYPE_DATA || type == WLAN_FC_TYPE_MGMT)
 			local->dot11TransmittedFragmentCount++;
         } else {
 		if (frag == 0)
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index 2dbb132..400c675 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -50,8 +50,6 @@ #define MAC2STR(a) ((a)[0] & 0xff), ((a)
 		   ((a)[3] & 0xff), ((a)[4] & 0xff), ((a)[5] & 0xff)
 #define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
 
-#define MULTICAST_ADDR(a) ((a)[0] & 0x01)
-
 
 /* IEEE 802.11 (Ch. 9.5 Defragmentation) requires support for concurrent
  * reception of at least three fragmented frames. This limit can be increased
-- 
1.3.0


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 3/10] d80211: fix Oops caused by packets sent directly to master device
  2006-04-21 20:53 [PATCH 0/10] d80211: bugfixes and reducing number of interfaces Jiri Benc
  2006-04-21 20:53 ` [PATCH 1/10] d80211: fix SIOCGIWESSID ioctl Jiri Benc
  2006-04-21 20:53 ` [PATCH 2/10] d80211: use is_multicast_ether_addr Jiri Benc
@ 2006-04-21 20:53 ` Jiri Benc
  2006-04-21 20:53 ` [PATCH 4/10] d80211: don't use pointer in ieee80211_tx_control Jiri Benc
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 18+ messages in thread
From: Jiri Benc @ 2006-04-21 20:53 UTC (permalink / raw)
  To: netdev

Sending packets to master interface directly causes dereferencing of pointer
containing random data. The same problem happens when originating virtual
interface is removed while a packet is queued.

We really shouldn't store pointer to ieee80211_sub_if_data in skb->cb. Store
ifindex there instead.

Also, there is no need for internal ieee80211_tx_packet_data structure to be
declared in d80211.h. As this patch touches this structure anyway, let's
move it to ieee80211_i.h.

Signed-off-by: Jiri Benc <jbenc@suse.cz>

---

 include/net/d80211.h       |   11 -----
 net/d80211/ieee80211.c     |   89 +++++++++++++++++++++++++++++++++++---------
 net/d80211/ieee80211_i.h   |   12 ++++++
 net/d80211/ieee80211_sta.c |    3 +
 net/d80211/wme.c           |    2 -
 5 files changed, 85 insertions(+), 32 deletions(-)

8d3a2dea3e4cefad23f3dad3e2eeeb5bdcff3dbb
diff --git a/include/net/d80211.h b/include/net/d80211.h
index 23bcbfa..e44e21c 100644
--- a/include/net/d80211.h
+++ b/include/net/d80211.h
@@ -188,17 +188,6 @@ struct ieee80211_tx_control {
 	struct ieee80211_sub_if_data *sdata; /* internal */
 };
 
-/* Stored in sk_buff->cb */
-struct ieee80211_tx_packet_data {
-        struct ieee80211_sub_if_data *sdata;
-	unsigned long jiffies;
-	unsigned int req_tx_status:1;
-	unsigned int do_not_encrypt:1;
-	unsigned int pkt_probe_resp:1;
-	unsigned int requeue:1;
-	unsigned int queue:4;
-};
-
 #define RX_FLAG_MMIC_ERROR       0x1
 #define RX_FLAG_DECRYPTED        0x2
 #define RX_FLAG_XR_DOUBLE_CHIRP  0x4
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index eb701ac..f768de5 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -1051,23 +1051,21 @@ ieee80211_tx_h_ps_buf(struct ieee80211_t
 }
 
 
-static void inline ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
-					struct sk_buff *skb,
-					struct net_device *dev,
-					struct ieee80211_tx_control *control)
+static void inline
+__ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
+		       struct sk_buff *skb,
+		       struct net_device *dev,
+		       struct ieee80211_tx_control *control)
 {
 	struct ieee80211_local *local = dev->priv;
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
-        struct ieee80211_tx_packet_data *pkt_data;
 	int hdrlen;
 
-        pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
-
 	memset(tx, 0, sizeof(*tx));
 	tx->skb = skb;
-	tx->dev = pkt_data->sdata->dev; /* use original interface */
+	tx->dev = dev; /* use original interface */
 	tx->local = local;
-        tx->sdata = pkt_data->sdata;
+	tx->sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 	tx->sta = sta_info_get(local, hdr->addr1);
 	tx->fc = le16_to_cpu(hdr->frame_control);
         control->power_level = local->conf.power_level;
@@ -1095,6 +1093,37 @@ static void inline ieee80211_tx_prepare(
 
 }
 
+/* FIXME: This is not nice but currently there doesn't exist more elegant way */
+static int inline is_ieee80211_device(struct net_device *dev)
+{
+	return (dev->wireless_handlers ==
+		(struct iw_handler_def *) &ieee80211_iw_handler_def);
+}
+
+/* Device in tx->dev has a reference added; use dev_put(tx->dev) when
+ * finished with it. */
+static void inline ieee80211_tx_prepare(struct ieee80211_txrx_data *tx,
+					struct sk_buff *skb,
+					struct net_device *mdev,
+					struct ieee80211_tx_control *control)
+{
+	struct ieee80211_tx_packet_data *pkt_data;
+	struct net_device *dev;
+
+	pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
+	dev = dev_get_by_index(pkt_data->ifindex);
+	if (unlikely(dev && !is_ieee80211_device(dev))) {
+		dev_put(dev);
+		dev = NULL;
+	}
+	if (unlikely(!dev)) {
+		printk(KERN_WARNING "%s: NULL ifindex in pkt_data\n",
+		       mdev->name);
+		dev = mdev;
+		dev_hold(dev);
+	}
+	__ieee80211_tx_prepare(tx, skb, dev, control);
+}
 
 static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
 			struct ieee80211_tx_control *control, int mgmt)
@@ -1111,7 +1140,7 @@ static int ieee80211_tx(struct net_devic
 		return 0;
 	}
 
-	ieee80211_tx_prepare(&tx, skb, dev, control);
+	__ieee80211_tx_prepare(&tx, skb, dev, control);
 	sta = tx.sta;
 	tx.u.tx.mgmt_interface = mgmt;
 
@@ -1136,8 +1165,8 @@ static int ieee80211_tx(struct net_devic
 		return 0;
 	}
 
-	ieee80211_dump_frame(dev->name, "TX to low-level driver", skb);
-	ret = local->hw->tx(dev, skb, control);
+	ieee80211_dump_frame(local->mdev->name, "TX to low-level driver", skb);
+	ret = local->hw->tx(local->mdev, skb, control);
 #ifdef IEEE80211_LEDS
 	if (!ret && local->tx_led_counter++ == 0) {
                 ieee80211_tx_led(1, dev);
@@ -1177,9 +1206,9 @@ #endif /* IEEE80211_LEDS */
 			dur = ieee80211_duration(&tx, 0, next_len);
 			hdr->duration_id = cpu_to_le16(dur);
 
-			ieee80211_dump_frame(dev->name,
+			ieee80211_dump_frame(local->mdev->name,
 					     "TX to low-level driver", skb);
-			ret = local->hw->tx(dev, tx.u.tx.extra_frag[i],
+			ret = local->hw->tx(local->mdev, tx.u.tx.extra_frag[i],
 					    control);
 			if (ret > 0)
 				goto drop;
@@ -1212,6 +1241,7 @@ static int ieee80211_master_start_xmit(s
 {
 	struct ieee80211_tx_control control;
 	struct ieee80211_tx_packet_data *pkt_data;
+	struct net_device *odev = NULL;
 	struct ieee80211_sub_if_data *sdata;
 	int ret;
 
@@ -1222,7 +1252,23 @@ static int ieee80211_master_start_xmit(s
 	 */
 	pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
 	memset(&control, 0, sizeof(struct ieee80211_tx_control));
-	control.sdata = pkt_data->sdata;
+
+	if (pkt_data->ifindex)
+		odev = dev_get_by_index(pkt_data->ifindex);
+	if (unlikely(odev && !is_ieee80211_device(odev))) {
+		dev_put(odev);
+		odev = NULL;
+	}
+	if (unlikely(!odev)) {
+#ifdef CONFIG_D80211_VERBOSE_DEBUG
+		printk(KERN_DEBUG "%s: Discarded packet with nonexistent "
+		       "originating device\n", dev->name);
+#endif
+		dev_kfree_skb(skb);
+		return 0;
+	}
+
+	control.sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 	control.req_tx_status = pkt_data->req_tx_status;
 	control.do_not_encrypt = pkt_data->do_not_encrypt;
 	control.pkt_type =
@@ -1230,8 +1276,9 @@ static int ieee80211_master_start_xmit(s
 	control.requeue = pkt_data->requeue;
 	control.queue = pkt_data->queue;
 
-	ret = ieee80211_tx(dev, skb, &control,
+	ret = ieee80211_tx(odev, skb, &control,
 			   control.sdata->type == IEEE80211_IF_TYPE_MGMT);
+	dev_put(odev);
 
         return ret;
 }
@@ -1401,7 +1448,8 @@ #endif
 
 	pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
 	memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data));
-	pkt_data->sdata = sdata;
+	pkt_data->ifindex = sdata->dev->ifindex;
+	pkt_data->mgmt_iface = (sdata->type == IEEE80211_IF_TYPE_MGMT);
 	pkt_data->do_not_encrypt = no_encrypt;
 
 	skb->dev = sdata->master;
@@ -1452,7 +1500,8 @@ ieee80211_mgmt_start_xmit(struct sk_buff
 
 	pkt_data = (struct ieee80211_tx_packet_data *) skb->cb;
 	memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data));
-        pkt_data->sdata = sdata;
+        pkt_data->ifindex = sdata->dev->ifindex;
+	pkt_data->mgmt_iface = (sdata->type == IEEE80211_IF_TYPE_MGMT);
 
 	if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT &&
 	    WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_RESP)
@@ -1680,6 +1729,7 @@ ieee80211_get_buffered_bc(struct net_dev
 		if (res == TXRX_DROP || res == TXRX_QUEUED)
 			break;
 	}
+	dev_put(tx.dev);
 
 	if (res == TXRX_DROP) {
 		I802_DEBUG_INC(local->tx_handlers_drop);
@@ -3644,7 +3694,8 @@ static void ieee80211_remove_tx_extra(st
 	struct ieee80211_tx_packet_data *pkt_data;
 
 	pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
-	pkt_data->sdata = control->sdata;
+	pkt_data->ifindex = control->sdata->dev->ifindex;
+	pkt_data->mgmt_iface = (control->sdata->type == IEEE80211_IF_TYPE_MGMT);
 	pkt_data->req_tx_status = control->req_tx_status;
 	pkt_data->do_not_encrypt = control->do_not_encrypt;
 	pkt_data->pkt_probe_resp = (control->pkt_type == PKT_PROBE_RESP);
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index 400c675..b29a5e8 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -143,6 +143,18 @@ #ifdef CONFIG_HOSTAPD_WPA_TESTING
 #endif /* CONFIG_HOSTAPD_WPA_TESTING */
 };
 
+/* Stored in sk_buff->cb */
+struct ieee80211_tx_packet_data {
+	int ifindex;
+	unsigned long jiffies;
+	unsigned int req_tx_status:1;
+	unsigned int do_not_encrypt:1;
+	unsigned int pkt_probe_resp:1;
+	unsigned int requeue:1;
+	unsigned int queue:4;
+	unsigned int mgmt_iface:1;
+};
+
 struct ieee80211_passive_scan {
         unsigned int in_scan:1; /* this must be cleared before calling
 				 * netif_oper(WAKEUP) */
diff --git a/net/d80211/ieee80211_sta.c b/net/d80211/ieee80211_sta.c
index d9c3d67..2720f1d 100644
--- a/net/d80211/ieee80211_sta.c
+++ b/net/d80211/ieee80211_sta.c
@@ -399,7 +399,8 @@ static void ieee80211_sta_tx(struct net_
 
 	pkt_data = (struct ieee80211_tx_packet_data *) skb->cb;
 	memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data));
-	pkt_data->sdata = sdata;
+	pkt_data->ifindex = sdata->dev->ifindex;
+	pkt_data->mgmt_iface = (sdata->type == IEEE80211_IF_TYPE_MGMT);
 	pkt_data->do_not_encrypt = !encrypt;
 	if (probe_resp)
 		pkt_data->pkt_probe_resp = 1;
diff --git a/net/d80211/wme.c b/net/d80211/wme.c
index 51a197a..f20d3e0 100644
--- a/net/d80211/wme.c
+++ b/net/d80211/wme.c
@@ -190,7 +190,7 @@ static inline int classify80211(struct s
 		return IEEE80211_TX_QUEUE_DATA0;
 	}
 
-	if (unlikely(pkt_data->sdata->type == IEEE80211_IF_TYPE_MGMT)) {
+	if (unlikely(pkt_data->mgmt_iface)) {
 		/* Data frames from hostapd (mainly, EAPOL) use AC_VO
 		* and they will include QoS control fields if
 		* the target STA is using WME. */
-- 
1.3.0


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 4/10] d80211: don't use pointer in ieee80211_tx_control
  2006-04-21 20:53 [PATCH 0/10] d80211: bugfixes and reducing number of interfaces Jiri Benc
                   ` (2 preceding siblings ...)
  2006-04-21 20:53 ` [PATCH 3/10] d80211: fix Oops caused by packets sent directly to master device Jiri Benc
@ 2006-04-21 20:53 ` Jiri Benc
  2006-04-21 20:53 ` [PATCH 5/10] d80211: per-interface SSID Jiri Benc
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 18+ messages in thread
From: Jiri Benc @ 2006-04-21 20:53 UTC (permalink / raw)
  To: netdev

A problem similar to the one with ieee80211_sub_if_data and skb->cb happens
to ieee80211_sub_if_data and ieee80211_tx_control. When originating
interface is removed while packet is sent to the driver, bad things will
happen. Use ifindex instead.

Signed-off-by: Jiri Benc <jbenc@suse.cz>

---

 include/net/d80211.h   |    3 ++-
 net/d80211/ieee80211.c |   12 +++++++-----
 2 files changed, 9 insertions(+), 6 deletions(-)

2f1956069a10abdc9a1d4f38ba413ae511428224
diff --git a/include/net/d80211.h b/include/net/d80211.h
index e44e21c..3943e30 100644
--- a/include/net/d80211.h
+++ b/include/net/d80211.h
@@ -185,7 +185,8 @@ struct ieee80211_tx_control {
 			     * struct ieee80211_rate). To be used to limit
 			     * packet dropping when probing higher rates, if hw
 			     * supports multiple retry rates. -1 = not used */
-	struct ieee80211_sub_if_data *sdata; /* internal */
+	int type;	/* internal */
+	int ifindex;	/* internal */
 };
 
 #define RX_FLAG_MMIC_ERROR       0x1
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index f768de5..425bd51 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -1242,7 +1242,7 @@ static int ieee80211_master_start_xmit(s
 	struct ieee80211_tx_control control;
 	struct ieee80211_tx_packet_data *pkt_data;
 	struct net_device *odev = NULL;
-	struct ieee80211_sub_if_data *sdata;
+	struct ieee80211_sub_if_data *sdata, *osdata;
 	int ret;
 
 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -1267,8 +1267,10 @@ #endif
 		dev_kfree_skb(skb);
 		return 0;
 	}
+	osdata = IEEE80211_DEV_TO_SUB_IF(odev);
 
-	control.sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	control.ifindex = odev->ifindex;
+	control.type = osdata->type;
 	control.req_tx_status = pkt_data->req_tx_status;
 	control.do_not_encrypt = pkt_data->do_not_encrypt;
 	control.pkt_type =
@@ -1277,7 +1279,7 @@ #endif
 	control.queue = pkt_data->queue;
 
 	ret = ieee80211_tx(odev, skb, &control,
-			   control.sdata->type == IEEE80211_IF_TYPE_MGMT);
+			   control.type == IEEE80211_IF_TYPE_MGMT);
 	dev_put(odev);
 
         return ret;
@@ -3694,8 +3696,8 @@ static void ieee80211_remove_tx_extra(st
 	struct ieee80211_tx_packet_data *pkt_data;
 
 	pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;
-	pkt_data->ifindex = control->sdata->dev->ifindex;
-	pkt_data->mgmt_iface = (control->sdata->type == IEEE80211_IF_TYPE_MGMT);
+	pkt_data->ifindex = control->ifindex;
+	pkt_data->mgmt_iface = (control->type == IEEE80211_IF_TYPE_MGMT);
 	pkt_data->req_tx_status = control->req_tx_status;
 	pkt_data->do_not_encrypt = control->do_not_encrypt;
 	pkt_data->pkt_probe_resp = (control->pkt_type == PKT_PROBE_RESP);
-- 
1.3.0


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 5/10] d80211: per-interface SSID
  2006-04-21 20:53 [PATCH 0/10] d80211: bugfixes and reducing number of interfaces Jiri Benc
                   ` (3 preceding siblings ...)
  2006-04-21 20:53 ` [PATCH 4/10] d80211: don't use pointer in ieee80211_tx_control Jiri Benc
@ 2006-04-21 20:53 ` Jiri Benc
  2006-04-21 20:53 ` [PATCH 6/10] d80211: per-interface generic_elem Jiri Benc
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 18+ messages in thread
From: Jiri Benc @ 2006-04-21 20:53 UTC (permalink / raw)
  To: netdev

Allow SSID to be set independently for each interface.

Signed-off-by: Jiri Benc <jbenc@suse.cz>

---

 include/net/d80211.h         |    9 ++++++--
 net/d80211/ieee80211.c       |    6 ++++-
 net/d80211/ieee80211_i.h     |    3 +++
 net/d80211/ieee80211_ioctl.c |   47 +++++++++++++++++++++++++-----------------
 4 files changed, 43 insertions(+), 22 deletions(-)

41fbbdfe8770f3492f888fcd459b2f9d2d615b0b
diff --git a/include/net/d80211.h b/include/net/d80211.h
index 3943e30..065b34c 100644
--- a/include/net/d80211.h
+++ b/include/net/d80211.h
@@ -251,8 +251,6 @@ struct ieee80211_conf {
 
         /* these fields are used by low level drivers for hardware
          * that generate beacons independently */
-        u8 *ssid;
-	size_t ssid_len;
 	u8 *generic_elem;
 	size_t generic_elem_len;
 
@@ -344,6 +342,11 @@ struct ieee80211_if_init_conf {
  *	during the live of the interface; this field is present only for
  *	convenience.
  * @bssid: BSSID of the network we are associated to/creating.
+ * @ssid: used (together with @ssid_len) by drivers for hardware that
+ *	generate beacons independently. The pointer is valid only during
+ *	config_interface() callback (so copy the value somewhere if you need
+ *	it).
+ * @ssid_len: length of the @ssid field.
  *
  * This structure is passed to config_interface() callback of
  * &struct ieee80211_hw.
@@ -351,6 +354,8 @@ struct ieee80211_if_init_conf {
 struct ieee80211_if_conf {
 	int type;
 	u8 *bssid;
+	u8 *ssid;
+	size_t ssid_len;
 };
 
 typedef enum { ALG_NONE, ALG_WEP, ALG_TKIP, ALG_CCMP, ALG_NULL }
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index 425bd51..984c2b0 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -1762,6 +1762,11 @@ int ieee80211_if_config(struct net_devic
 	if (sdata->type == IEEE80211_IF_TYPE_STA ||
 	    sdata->type == IEEE80211_IF_TYPE_IBSS) {
 		conf.bssid = sdata->u.sta.bssid;
+		conf.ssid = sdata->u.sta.ssid;
+		conf.ssid_len = sdata->u.sta.ssid_len;
+	} else if (sdata->type == IEEE80211_IF_TYPE_AP) {
+		conf.ssid = sdata->u.ap.ssid;
+		conf.ssid_len = sdata->u.ap.ssid_len;
 	}
 	return local->hw->config_interface(local->mdev, dev->ifindex, &conf);
 }
@@ -4337,7 +4342,6 @@ void ieee80211_unregister_hw(struct net_
 		kfree(local->basic_rates[i]);
         }
 
-	kfree(local->conf.ssid);
 	kfree(local->conf.generic_elem);
 
 	ieee80211_proc_deinit_interface(local);
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index b29a5e8..e78beb2 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -192,6 +192,9 @@ struct ieee80211_if_ap {
 	u8 *beacon_head, *beacon_tail;
 	int beacon_head_len, beacon_tail_len;
 
+	u8 ssid[IEEE80211_MAX_SSID_LEN];
+	size_t ssid_len;
+
 	/* TODO: sta_aid could be replaced by 2008-bit large bitfield of
 	 * that could be used in TIM element generation. This would also
 	 * make TIM element generation a bit faster. */
diff --git a/net/d80211/ieee80211_ioctl.c b/net/d80211/ieee80211_ioctl.c
index 792fcf4..6b73e27 100644
--- a/net/d80211/ieee80211_ioctl.c
+++ b/net/d80211/ieee80211_ioctl.c
@@ -1746,7 +1746,6 @@ static int ieee80211_ioctl_siwessid(stru
 				    struct iw_request_info *info,
 				    struct iw_point *data, char *ssid)
 {
-	struct ieee80211_local *local = dev->priv;
 	struct ieee80211_sub_if_data *sdata;
         size_t len = data->length;
 
@@ -1759,14 +1758,14 @@ static int ieee80211_ioctl_siwessid(stru
 	    sdata->type == IEEE80211_IF_TYPE_IBSS)
 		return ieee80211_sta_set_ssid(dev, ssid, len);
 
-	kfree(local->conf.ssid);
-	local->conf.ssid = kmalloc(len + 1, GFP_KERNEL);
-	if (local->conf.ssid == NULL)
-		return -ENOMEM;
-	memcpy(local->conf.ssid, ssid, len);
-	local->conf.ssid[len] = '\0';
-	local->conf.ssid_len = len;
-	return ieee80211_hw_config(dev);
+	if (sdata->type == IEEE80211_IF_TYPE_AP) {
+		memcpy(sdata->u.ap.ssid, ssid, len);
+		memset(sdata->u.ap.ssid + len, 0,
+		       IEEE80211_MAX_SSID_LEN - len);
+		sdata->u.ap.ssid_len = len;
+		return ieee80211_if_config(dev);
+	}
+	return -EOPNOTSUPP;
 }
 
 
@@ -1774,7 +1773,6 @@ static int ieee80211_ioctl_giwessid(stru
 				    struct iw_request_info *info,
 				    struct iw_point *data, char *ssid)
 {
-	struct ieee80211_local *local = dev->priv;
 	size_t len;
 
 	struct ieee80211_sub_if_data *sdata;
@@ -1790,13 +1788,16 @@ static int ieee80211_ioctl_giwessid(stru
 		return res;
 	}
 
-	len = local->conf.ssid_len;
-	if (len > IW_ESSID_MAX_SIZE)
-		len = IW_ESSID_MAX_SIZE;
-	memcpy(ssid, local->conf.ssid, len);
-	data->length = len;
-	data->flags = 1;
-	return 0;
+	if (sdata->type == IEEE80211_IF_TYPE_AP) {
+		len = sdata->u.ap.ssid_len;
+		if (len > IW_ESSID_MAX_SIZE)
+			len = IW_ESSID_MAX_SIZE;
+		memcpy(ssid, sdata->u.ap.ssid, len);
+		data->length = len;
+		data->flags = 1;
+		return 0;
+	}
+	return -EOPNOTSUPP;
 }
 
 
@@ -1848,12 +1849,20 @@ static int ieee80211_ioctl_siwscan(struc
 				   struct iw_point *data, char *extra)
 {
 	struct ieee80211_local *local = dev->priv;
+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 	u8 *ssid = NULL;
 	size_t ssid_len = 0;
 
 	if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) {
-		ssid = local->conf.ssid;
-		ssid_len = local->conf.ssid_len;
+		if (sdata->type == IEEE80211_IF_TYPE_STA ||
+		    sdata->type == IEEE80211_IF_TYPE_IBSS) {
+			ssid = sdata->u.sta.ssid;
+			ssid_len = sdata->u.sta.ssid_len;
+		} else if (sdata == IEEE80211_IF_TYPE_AP) {
+			ssid = sdata->u.ap.ssid;
+			ssid_len = sdata->u.ap.ssid_len;
+		} else
+			return -EINVAL;
 	}
 	return ieee80211_sta_req_scan(dev, ssid, ssid_len);
 }
-- 
1.3.0


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 6/10] d80211: per-interface generic_elem
  2006-04-21 20:53 [PATCH 0/10] d80211: bugfixes and reducing number of interfaces Jiri Benc
                   ` (4 preceding siblings ...)
  2006-04-21 20:53 ` [PATCH 5/10] d80211: per-interface SSID Jiri Benc
@ 2006-04-21 20:53 ` Jiri Benc
  2006-04-21 20:53 ` [PATCH 7/10] d80211: get rid of default AP interface Jiri Benc
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 18+ messages in thread
From: Jiri Benc @ 2006-04-21 20:53 UTC (permalink / raw)
  To: netdev

Allow generic element to be set independently for each interface.

Signed-off-by: Jiri Benc <jbenc@suse.cz>

---

 include/net/d80211.h         |   12 +++++++-----
 net/d80211/ieee80211.c       |    6 ++++--
 net/d80211/ieee80211_i.h     |    2 ++
 net/d80211/ieee80211_iface.c |    1 +
 net/d80211/ieee80211_ioctl.c |   19 ++++++++++---------
 5 files changed, 24 insertions(+), 16 deletions(-)

330ee7fb14673a5c69000a2c31c83830d7c6c456
diff --git a/include/net/d80211.h b/include/net/d80211.h
index 065b34c..4bdbdbe 100644
--- a/include/net/d80211.h
+++ b/include/net/d80211.h
@@ -249,11 +249,6 @@ struct ieee80211_conf {
 	int short_slot_time:1;		/* use IEEE 802.11g Short Slot Time */
         int ssid_hidden:1;		/* do not broadcast the ssid */
 
-        /* these fields are used by low level drivers for hardware
-         * that generate beacons independently */
-	u8 *generic_elem;
-	size_t generic_elem_len;
-
         u8 power_level;			/* transmit power limit for current
 					 * regulatory domain; in dBm */
         u8 antenna_max;			/* maximum antenna gain */
@@ -347,6 +342,11 @@ struct ieee80211_if_init_conf {
  *	config_interface() callback (so copy the value somewhere if you need
  *	it).
  * @ssid_len: length of the @ssid field.
+ * @generic_elem: used (together with @generic_elem_len) by drivers for
+ *	hardware that generate beacons independently. The pointer is valid
+ *	only during config_interface() callback (so copy the value somewhere
+ *	if you need it).
+ * @generic_elem_len: length of the generic element.
  *
  * This structure is passed to config_interface() callback of
  * &struct ieee80211_hw.
@@ -356,6 +356,8 @@ struct ieee80211_if_conf {
 	u8 *bssid;
 	u8 *ssid;
 	size_t ssid_len;
+	u8 *generic_elem;
+	size_t generic_elem_len;
 };
 
 typedef enum { ALG_NONE, ALG_WEP, ALG_TKIP, ALG_CCMP, ALG_NULL }
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index 984c2b0..ad63bab 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -1764,9 +1764,13 @@ int ieee80211_if_config(struct net_devic
 		conf.bssid = sdata->u.sta.bssid;
 		conf.ssid = sdata->u.sta.ssid;
 		conf.ssid_len = sdata->u.sta.ssid_len;
+		conf.generic_elem = sdata->u.sta.extra_ie;
+		conf.generic_elem_len = sdata->u.sta.extra_ie_len;
 	} else if (sdata->type == IEEE80211_IF_TYPE_AP) {
 		conf.ssid = sdata->u.ap.ssid;
 		conf.ssid_len = sdata->u.ap.ssid_len;
+		conf.generic_elem = sdata->u.ap.generic_elem;
+		conf.generic_elem_len = sdata->u.ap.generic_elem_len;
 	}
 	return local->hw->config_interface(local->mdev, dev->ifindex, &conf);
 }
@@ -4342,8 +4346,6 @@ void ieee80211_unregister_hw(struct net_
 		kfree(local->basic_rates[i]);
         }
 
-	kfree(local->conf.generic_elem);
-
 	ieee80211_proc_deinit_interface(local);
 
 	if (skb_queue_len(&local->skb_queue)
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index e78beb2..98c30ff 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -194,6 +194,8 @@ struct ieee80211_if_ap {
 
 	u8 ssid[IEEE80211_MAX_SSID_LEN];
 	size_t ssid_len;
+	u8 *generic_elem;
+	size_t generic_elem_len;
 
 	/* TODO: sta_aid could be replaced by 2008-bit large bitfield of
 	 * that could be used in TIM element generation. This would also
diff --git a/net/d80211/ieee80211_iface.c b/net/d80211/ieee80211_iface.c
index dd809c2..42ea643 100644
--- a/net/d80211/ieee80211_iface.c
+++ b/net/d80211/ieee80211_iface.c
@@ -175,6 +175,7 @@ #endif
 
 		kfree(sdata->u.ap.beacon_head);
 		kfree(sdata->u.ap.beacon_tail);
+		kfree(sdata->u.ap.generic_elem);
 
 		if (dev != local->mdev) {
 			struct sk_buff *skb;
diff --git a/net/d80211/ieee80211_ioctl.c b/net/d80211/ieee80211_ioctl.c
index 6b73e27..3eaad0a 100644
--- a/net/d80211/ieee80211_ioctl.c
+++ b/net/d80211/ieee80211_ioctl.c
@@ -1137,7 +1137,6 @@ #endif
 
 static int ieee80211_set_gen_ie(struct net_device *dev, u8 *ie, size_t len)
 {
-	struct ieee80211_local *local = dev->priv;
 	struct ieee80211_sub_if_data *sdata;
 
 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -1145,14 +1144,16 @@ static int ieee80211_set_gen_ie(struct n
 	    sdata->type == IEEE80211_IF_TYPE_IBSS)
 		return ieee80211_sta_set_extra_ie(dev, ie, len);
 
-	kfree(local->conf.generic_elem);
-	local->conf.generic_elem = kmalloc(len, GFP_KERNEL);
-	if (local->conf.generic_elem == NULL)
-		return -ENOMEM;
-	memcpy(local->conf.generic_elem, ie, len);
-	local->conf.generic_elem_len = len;
-
-	return ieee80211_hw_config(dev);
+	if (sdata->type == IEEE80211_IF_TYPE_AP) {
+		kfree(sdata->u.ap.generic_elem);
+		sdata->u.ap.generic_elem = kmalloc(len, GFP_KERNEL);
+		if (sdata->u.ap.generic_elem == NULL)
+			return -ENOMEM;
+		memcpy(sdata->u.ap.generic_elem, ie, len);
+		sdata->u.ap.generic_elem_len = len;
+		return ieee80211_if_config(dev);
+	}
+	return -EOPNOTSUPP;
 }
 
 
-- 
1.3.0


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 7/10] d80211: get rid of default AP interface
  2006-04-21 20:53 [PATCH 0/10] d80211: bugfixes and reducing number of interfaces Jiri Benc
                   ` (5 preceding siblings ...)
  2006-04-21 20:53 ` [PATCH 6/10] d80211: per-interface generic_elem Jiri Benc
@ 2006-04-21 20:53 ` Jiri Benc
  2006-04-21 20:53 ` [PATCH 8/10] d80211: get rid of default management interface Jiri Benc
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 18+ messages in thread
From: Jiri Benc @ 2006-04-21 20:53 UTC (permalink / raw)
  To: netdev

There is no need for default non-removable AP interface (wlanX), it just
confuses users. This patch removes it and renames master interface from
wlanX.11 to wlanX.

Signed-off-by: Jiri Benc <jbenc@suse.cz>

---

 net/d80211/ieee80211.c       |   78 +++++++++---------------------------------
 net/d80211/ieee80211_i.h     |    3 +-
 net/d80211/ieee80211_iface.c |    3 +-
 net/d80211/ieee80211_ioctl.c |   12 +++---
 net/d80211/ieee80211_proc.c  |    8 ++--
 5 files changed, 27 insertions(+), 77 deletions(-)

11da4bbdb5dd3f83a991f9e8df2d2356606b87b4
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index ad63bab..2386454 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -2032,7 +2032,7 @@ static int ieee80211_open(struct net_dev
 		struct net_device *ndev = nsdata->dev;
 
 		if (ndev != dev && ndev != local->mdev &&
-		    ndev != local->wdev && ndev != local->apdev &&
+		    ndev != local->apdev &&
 		    netif_running(ndev) &&
 		    memcmp(dev->dev_addr, ndev->dev_addr, ETH_ALEN) == 0 &&
 		    !identical_mac_addr_allowed(sdata->type, nsdata->type)) {
@@ -3684,7 +3684,7 @@ static void ieee80211_tasklet_handler(un
 			break;
 		default: /* should never get here! */
 			printk(KERN_ERR "%s: Unknown message type (%d)\n",
-			       local->wdev->name, skb->pkt_type);
+			       local->mdev->name, skb->pkt_type);
 			dev_kfree_skb(skb);
 			break;
                 }
@@ -3979,7 +3979,7 @@ static void ieee80211_if_init(struct net
 }
 
 
-/* Must not be called for wdev, mdev and apdev */
+/* Must not be called for mdev and apdev */
 void ieee80211_if_setup(struct net_device *dev)
 {
 	ether_setup(dev);
@@ -4018,7 +4018,7 @@ static void ieee80211_precalc_rates(stru
 struct net_device *ieee80211_alloc_hw(size_t priv_data_len,
 				      void (*setup)(struct net_device *))
 {
-	struct net_device *dev, *apdev, *mdev;
+	struct net_device *apdev, *mdev;
         struct ieee80211_local *local;
         struct ieee80211_sub_if_data *sdata;
 	int alloc_size;
@@ -4042,10 +4042,6 @@ struct net_device *ieee80211_alloc_hw(si
          * 17c0 *****************
          *      * sub_if        *
 	 *      *****************
-	 *      * master net_dev*
-	 *      *****************
-	 *      * sub_if        *
-         *      *****************
          */
         alloc_size = sizeof(struct net_device) +
                 sizeof(struct ieee80211_sub_if_data) + 3 +
@@ -4053,8 +4049,6 @@ struct net_device *ieee80211_alloc_hw(si
                 priv_data_len + 3 +
                 sizeof(struct net_device) + 3 +
 		sizeof(struct ieee80211_sub_if_data) + 3 +
-                sizeof(struct net_device) + 3 +
-		sizeof(struct ieee80211_sub_if_data) + 3 +
 		4096;
         mdev = (struct net_device *) kzalloc(alloc_size, GFP_KERNEL);
 	if (mdev == NULL)
@@ -4069,29 +4063,14 @@ struct net_device *ieee80211_alloc_hw(si
 		((char *) local + ((sizeof(struct ieee80211_local) + 3) & ~3));
 	apdev = (struct net_device *)
 		((char *) local->hw_priv + ((priv_data_len + 3) & ~3));
-        dev = (struct net_device *)
-		((char *) apdev +
-		 ((sizeof(struct net_device) + 3) & ~3) +
-		 ((sizeof(struct ieee80211_sub_if_data) + 3) & ~3));
-        dev->priv = local;
 
-	ether_setup(dev);
-	memcpy(dev->name, "wlan%d", 7);
+	ether_setup(mdev);
+	memcpy(mdev->name, "wlan%d", 7);
 
-        dev->hard_start_xmit = ieee80211_subif_start_xmit;
-	dev->wireless_handlers =
-		(struct iw_handler_def *) &ieee80211_iw_handler_def;
-        dev->do_ioctl = ieee80211_ioctl;
-	dev->change_mtu = ieee80211_change_mtu;
-        dev->tx_timeout = ieee80211_tx_timeout;
-        dev->get_stats = ieee80211_get_stats;
-        dev->open = ieee80211_open;
-        dev->stop = ieee80211_stop;
-	dev->tx_queue_len = 0;
-	dev->set_mac_address = ieee80211_set_mac_address;
+	if (strlen(mdev->name) + 2 >= sizeof(mdev->name))
+		goto fail;
 
 	local->dev_index = -1;
-        local->wdev = dev;
 	local->mdev = mdev;
         local->rx_handlers = ieee80211_rx_handlers;
         local->tx_handlers = ieee80211_tx_handlers;
@@ -4119,22 +4098,11 @@ struct net_device *ieee80211_alloc_hw(si
 	init_timer(&local->stat_timer);
 	local->stat_timer.function = ieee80211_stat_refresh;
 	local->stat_timer.data = (unsigned long) local;
-	ieee80211_rx_bss_list_init(dev);
+	ieee80211_rx_bss_list_init(mdev);
 
         sta_info_init(local);
 
-        ieee80211_if_init(dev);
-
-        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
-        sdata->dev = dev;
-        sdata->master = mdev;
-        sdata->local = local;
-	ieee80211_if_sdata_init(sdata);
-	ieee80211_if_set_type(dev, IEEE80211_IF_TYPE_AP);
-	list_add_tail(&sdata->list, &local->sub_if_list);
-
-	if (strlen(dev->name) + 2 >= sizeof(dev->name))
-		goto fail;
+        ieee80211_if_init(mdev);
 
         apdev = (struct net_device *)
 		((char *) local->hw_priv + ((priv_data_len + 3) & ~3));
@@ -4149,7 +4117,7 @@ struct net_device *ieee80211_alloc_hw(si
 	apdev->type = ARPHRD_IEEE80211_PRISM;
         apdev->hard_header_parse = header_parse_80211;
 	apdev->tx_queue_len = 0;
-	sprintf(apdev->name, "%sap", dev->name);
+	sprintf(apdev->name, "%sap", mdev->name);
 
         sdata = IEEE80211_DEV_TO_SUB_IF(apdev);
         sdata->type = IEEE80211_IF_TYPE_MGMT;
@@ -4158,7 +4126,6 @@ struct net_device *ieee80211_alloc_hw(si
         sdata->local = local;
         list_add_tail(&sdata->list, &local->sub_if_list);
 
-	ether_setup(mdev);
 	mdev->hard_start_xmit = ieee80211_master_start_xmit;
 	mdev->wireless_handlers =
 		(struct iw_handler_def *) &ieee80211_iw_handler_def;
@@ -4170,7 +4137,6 @@ struct net_device *ieee80211_alloc_hw(si
 	mdev->stop = ieee80211_master_stop;
 	mdev->type = ARPHRD_IEEE80211;
         mdev->hard_header_parse = header_parse_80211;
-	sprintf(mdev->name, "%s.11", dev->name);
 
 	sdata = IEEE80211_DEV_TO_SUB_IF(mdev);
 	sdata->type = IEEE80211_IF_TYPE_AP;
@@ -4226,19 +4192,15 @@ int ieee80211_register_hw(struct net_dev
 
 	sta_info_start(local);
 
-	result = register_netdev(local->wdev);
-	if (result < 0)
-		goto fail_1st_dev;
-
 	result = register_netdev(local->apdev);
 	if (result < 0)
-		goto fail_2nd_dev;
+		goto fail_1st_dev;
 
 	if (hw->fraglist)
 		dev->features |= NETIF_F_FRAGLIST;
 	result = register_netdev(dev);
 	if (result < 0)
-		goto fail_3rd_dev;
+		goto fail_2nd_dev;
 
 	if (rate_control_initialize(local) < 0) {
 		printk(KERN_DEBUG "%s: Failed to initialize rate control "
@@ -4255,10 +4217,8 @@ int ieee80211_register_hw(struct net_dev
 
 fail_rate:
 	unregister_netdev(dev);
-fail_3rd_dev:
-	unregister_netdev(local->apdev);
 fail_2nd_dev:
-	unregister_netdev(local->wdev);
+	unregister_netdev(local->apdev);
 fail_1st_dev:
 	sta_info_stop(local);
 	ieee80211_unregister_sysfs(local);
@@ -4284,12 +4244,6 @@ int ieee80211_update_hw(struct net_devic
 	local->apdev->mem_start = dev->mem_start;
 	local->apdev->mem_end = dev->mem_end;
 
-        memcpy(local->wdev->dev_addr, dev->dev_addr, ETH_ALEN);
-	local->wdev->base_addr = dev->base_addr;
-	local->wdev->irq = dev->irq;
-	local->wdev->mem_start = dev->mem_start;
-	local->wdev->mem_end = dev->mem_end;
-
 	if (!hw->modes || !hw->modes->channels || !hw->modes->rates ||
 	    !hw->modes->num_channels || !hw->modes->num_rates)
 		return -1;
@@ -4470,14 +4424,14 @@ static int rate_control_initialize(struc
 		local->rate_ctrl_priv = rate_control_alloc(local);
 		if (local->rate_ctrl_priv) {
 			printk(KERN_DEBUG "%s: Selected rate control "
-			       "algorithm '%s'\n", local->wdev->name,
+			       "algorithm '%s'\n", local->mdev->name,
 			       local->rate_ctrl->name);
 			return 0;
 		}
 	}
 
 	printk(KERN_WARNING "%s: Failed to select rate control algorithm\n",
-	       local->wdev->name);
+	       local->mdev->name);
 	return -1;
 }
 
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index 98c30ff..77517c9 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -316,8 +316,7 @@ #define IEEE80211_SUB_IF_TO_DEV(sub_if) 
 struct ieee80211_local {
 	struct ieee80211_hw *hw;
 	void *hw_priv;
-	struct net_device *mdev; /* wlan#.11 - "master" 802.11 device */
-        struct net_device *wdev; /* wlan# - default Ethernet (data) devide */
+	struct net_device *mdev; /* wlan# - "master" 802.11 device */
 	struct net_device *apdev; /* wlan#ap - management frames (hostapd) */
 	int open_count;
 	int monitors;
diff --git a/net/d80211/ieee80211_iface.c b/net/d80211/ieee80211_iface.c
index 42ea643..58fd946 100644
--- a/net/d80211/ieee80211_iface.c
+++ b/net/d80211/ieee80211_iface.c
@@ -258,7 +258,6 @@ int ieee80211_if_remove(struct net_devic
 		if ((sdata->type == id || id == -1) &&
 		    strcmp(name, sdata->dev->name) == 0 &&
 		    sdata->dev != local->mdev &&
-		    sdata->dev != local->wdev &&
 		    sdata->dev != local->apdev) {
 			__ieee80211_if_del(local, sdata);
 			return 0;
@@ -271,7 +270,7 @@ void ieee80211_if_free(struct net_device
 {
 	struct ieee80211_local *local = dev->priv;
 
-	BUG_ON(dev == local->mdev || dev == local->wdev || dev == local->apdev);
+	BUG_ON(dev == local->mdev || dev == local->apdev);
 	kfree(dev);
 }
 
diff --git a/net/d80211/ieee80211_ioctl.c b/net/d80211/ieee80211_ioctl.c
index 3eaad0a..1d3f5cf 100644
--- a/net/d80211/ieee80211_ioctl.c
+++ b/net/d80211/ieee80211_ioctl.c
@@ -499,13 +499,11 @@ static int ieee80211_set_encryption(stru
 		 * must be used. This should be done automatically
 		 * based on configured station devices. For the time
 		 * being, this can be only set at compile time. */
-		if (sdata->type == IEEE80211_IF_TYPE_STA) {
-			if (0 /* FIX: more than one STA per AP */)
-				try_hwaccel = 0;
-		} else
-		if (sdata->type != IEEE80211_IF_TYPE_AP ||
-		    dev != local->wdev)
-			try_hwaccel = 0;
+		/* FIXME: There is no more anything like "default
+		 * interface". We should try hwaccel if there is just one
+		 * interface - for now, hwaccel is unconditionaly
+		 * disabled. */
+		try_hwaccel = 0;
 	} else {
 		set_tx_key = 0;
 		if (idx != 0) {
diff --git a/net/d80211/ieee80211_proc.c b/net/d80211/ieee80211_proc.c
index a886280..c9f5567 100644
--- a/net/d80211/ieee80211_proc.c
+++ b/net/d80211/ieee80211_proc.c
@@ -702,7 +702,7 @@ void ieee80211_proc_init_interface(struc
 	if (!ieee80211_proc)
 		return;
 
-	local->proc = proc_mkdir(local->wdev->name, ieee80211_proc);
+	local->proc = proc_mkdir(local->mdev->name, ieee80211_proc);
 	if (!local->proc)
 		return;
 
@@ -722,7 +722,7 @@ void ieee80211_proc_init_interface(struc
                                ieee80211_proc_debug_read, local);
 	create_proc_read_entry("info", 0, local->proc,
 			       ieee80211_proc_info_read, local);
-	ieee80211_proc_init_virtual(local->wdev);
+	ieee80211_proc_init_virtual(local->mdev);
 }
 
 
@@ -731,7 +731,7 @@ void ieee80211_proc_deinit_interface(str
 	if (!local->proc)
 		return;
 
-	ieee80211_proc_deinit_virtual(local->wdev);
+	ieee80211_proc_deinit_virtual(local->mdev);
 	remove_proc_entry("iface", local->proc);
 	remove_proc_entry("sta", local->proc);
         remove_proc_entry("counters", local->proc);
@@ -742,7 +742,7 @@ void ieee80211_proc_deinit_interface(str
 	remove_proc_entry("multicast", local->proc);
 	remove_proc_entry("info", local->proc);
 	local->proc = NULL;
-	remove_proc_entry(local->wdev->name, ieee80211_proc);
+	remove_proc_entry(local->mdev->name, ieee80211_proc);
 }
 
 
-- 
1.3.0


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 8/10] d80211: get rid of default management interface
  2006-04-21 20:53 [PATCH 0/10] d80211: bugfixes and reducing number of interfaces Jiri Benc
                   ` (6 preceding siblings ...)
  2006-04-21 20:53 ` [PATCH 7/10] d80211: get rid of default AP interface Jiri Benc
@ 2006-04-21 20:53 ` Jiri Benc
  2006-04-21 20:59   ` Johannes Berg
  2006-04-22  2:44   ` Jouni Malinen
  2006-04-21 20:53 ` [PATCH 9/10] d80211: rename master interface Jiri Benc
  2006-04-21 20:53 ` [PATCH 10/10] d80211: add one default interface Jiri Benc
  9 siblings, 2 replies; 18+ messages in thread
From: Jiri Benc @ 2006-04-21 20:53 UTC (permalink / raw)
  To: netdev

Default management interface (wlanXap) confuses users. It is only needed for
AP mode (and only until interfaces are converted to use native 802.11
frames).

This patch removes default management interface. When a new interface is
switched to AP mode, a management interface is created automatically. This
also fixes some problems with multiple AP interfaces - now you have
different management interface for each AP interface.

Signed-off-by: Jiri Benc <jbenc@suse.cz>

---

 net/d80211/ieee80211.c       |  204 +++++++++++++++++++++++++-----------------
 net/d80211/ieee80211_i.h     |    6 +
 net/d80211/ieee80211_iface.c |   73 ++++++++++++++-
 3 files changed, 193 insertions(+), 90 deletions(-)

726d59fb8b157daf368b097cef7d3d2ed8c61784
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index 2386454..31f979c 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -59,6 +59,8 @@ static int rate_control_initialize(struc
 
 static u8 * ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len);
 
+static void ieee80211_rx_michael_mic_report(struct ieee80211_txrx_data *rx,
+					    struct ieee80211_hdr *hdr);
 
 struct ieee80211_key_conf *
 ieee80211_key_data2conf(struct ieee80211_local *local,
@@ -1954,8 +1956,6 @@ static inline int identical_mac_addr_all
 {
 	return (type1 == IEEE80211_IF_TYPE_MNTR ||
 		type2 == IEEE80211_IF_TYPE_MNTR ||
-		type1 == IEEE80211_IF_TYPE_MGMT ||
-		type2 == IEEE80211_IF_TYPE_MGMT ||
 		(type1 == IEEE80211_IF_TYPE_AP &&
 		 type2 == IEEE80211_IF_TYPE_WDS) ||
 		(type1 == IEEE80211_IF_TYPE_WDS &&
@@ -1990,6 +1990,20 @@ static int ieee80211_master_stop(struct 
 	return 0;
 }
 
+static int ieee80211_ap_open(struct net_device *dev)
+{
+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+	if (!netif_running(sdata->u.ap.apdev))
+		return -EOPNOTSUPP;
+	return 0;
+}
+
+static int ieee80211_ap_stop(struct net_device *dev)
+{
+	return 0;
+}
+
 /* Check if running monitor interfaces should go to a "soft monitor" mode
  * and switch them if necessary. */
 static inline void ieee80211_start_soft_monitor(struct ieee80211_local *local)
@@ -2032,7 +2046,6 @@ static int ieee80211_open(struct net_dev
 		struct net_device *ndev = nsdata->dev;
 
 		if (ndev != dev && ndev != local->mdev &&
-		    ndev != local->apdev &&
 		    netif_running(ndev) &&
 		    memcmp(dev->dev_addr, ndev->dev_addr, ETH_ALEN) == 0 &&
 		    !identical_mac_addr_allowed(sdata->type, nsdata->type)) {
@@ -2087,7 +2100,9 @@ static int ieee80211_open(struct net_dev
 	}
         local->open_count++;
 
-	if (sdata->type == IEEE80211_IF_TYPE_MNTR)
+	if (sdata->type == IEEE80211_IF_TYPE_AP)
+		dev_open(sdata->u.ap.apdev);
+	else if (sdata->type == IEEE80211_IF_TYPE_MNTR)
 		local->monitors++;
 
 	netif_start_queue(dev);
@@ -2112,7 +2127,9 @@ static int ieee80211_stop(struct net_dev
 
         netif_stop_queue(dev);
 
-	if (sdata->type == IEEE80211_IF_TYPE_MNTR)
+	if (sdata->type == IEEE80211_IF_TYPE_AP)
+		dev_close(sdata->u.ap.apdev);
+	else if (sdata->type == IEEE80211_IF_TYPE_MNTR)
 		local->monitors--;
 
 	local->open_count--;
@@ -2356,6 +2373,7 @@ ieee80211_get_rate(struct ieee80211_loca
 }
 
 
+/* If dev is master device, skb will be sent to all AP interfaces. */
 void
 ieee80211_rx_mgmt(struct net_device *dev, struct sk_buff *skb,
 		  struct ieee80211_rx_status *status, u32 msg_type)
@@ -2363,13 +2381,15 @@ ieee80211_rx_mgmt(struct net_device *dev
         struct ieee80211_local *local = dev->priv;
         struct ieee80211_frame_info *fi;
         size_t hlen;
-        struct ieee80211_sub_if_data *sdata;
+        struct ieee80211_sub_if_data *sdata, *apsdata, *prev = NULL;
 
-	if (msg_type != ieee80211_msg_monitor)
-		dev = local->apdev;
-        skb->dev = dev;
+	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
 
-        sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	if (msg_type != ieee80211_msg_monitor &&
+	    sdata->type != IEEE80211_IF_TYPE_AP && dev != local->mdev) {
+		dev_kfree_skb(skb);
+		return;
+	}
 
 	if (skb_headroom(skb) < sizeof(struct ieee80211_frame_info)) {
 		I802_DEBUG_INC(local->rx_expand_skb_head);
@@ -2443,15 +2463,56 @@ ieee80211_rx_mgmt(struct net_device *dev
                 fi->ssi_type = htonl(ieee80211_ssi_none);
         }
 
-        sdata->stats.rx_packets++;
-        sdata->stats.rx_bytes += skb->len;
-
         skb->mac.raw = skb->data;
 	skb->ip_summed = CHECKSUM_UNNECESSARY;
 	skb->pkt_type = PACKET_OTHERHOST;
 	skb->protocol = __constant_htons(ETH_P_802_2);
 	memset(skb->cb, 0, sizeof(skb->cb));
-        netif_rx(skb);
+
+	if (msg_type == ieee80211_msg_monitor) {
+		skb->dev = dev;
+		sdata->stats.rx_packets++;
+		sdata->stats.rx_bytes += skb->len;
+		netif_rx(skb);
+		return;
+	}
+
+	if (dev == local->mdev) {
+		list_for_each_entry(sdata, &local->sub_if_list, list) {
+			if (sdata->type != IEEE80211_IF_TYPE_AP ||
+			    sdata->dev == local->mdev)
+				continue;
+			if (prev) {
+				struct sk_buff *skb_new;
+
+				skb_new = skb_copy(skb, GFP_ATOMIC);
+				if (skb_new == NULL) {
+					if (net_ratelimit()) {
+						printk(KERN_DEBUG "%s: failed "
+						       "to copy message for %s",
+						       dev->name,
+						       prev->u.ap.apdev->name);
+					}
+					continue;
+				}
+				skb_new->dev = prev->u.ap.apdev;
+				apsdata = IEEE80211_DEV_TO_SUB_IF(skb_new->dev);
+				apsdata->stats.rx_packets++;
+				apsdata->stats.rx_bytes += skb_new->len;
+				netif_rx(skb_new);
+			}
+			prev = sdata;
+		}
+		sdata = prev;
+	}
+	if (sdata) {
+		skb->dev = sdata->u.ap.apdev;
+		apsdata = IEEE80211_DEV_TO_SUB_IF(skb->dev);
+		apsdata->stats.rx_packets++;
+		apsdata->stats.rx_bytes += skb->len;
+		netif_rx(skb);
+	} else
+		dev_kfree_skb(skb);
 }
 
 
@@ -2839,6 +2900,11 @@ ieee80211_rx_h_check(struct ieee80211_tx
 	int always_sta_key;
 	hdr = (struct ieee80211_hdr *) rx->skb->data;
 
+        if ((rx->u.rx.status->flag & RX_FLAG_MMIC_ERROR)) {
+		ieee80211_rx_michael_mic_report(rx, hdr);
+		return TXRX_QUEUED;
+        }
+
 	/* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */
 	if (rx->sta && !is_multicast_ether_addr(hdr->addr1)) {
 		if (unlikely(rx->fc & WLAN_FC_RETRY &&
@@ -3207,10 +3273,8 @@ static u8 * ieee80211_get_bssid(struct i
 	return NULL;
 }
 
-static void ieee80211_rx_michael_mic_report(struct net_device *dev,
-					    struct ieee80211_hdr *hdr,
-					    struct sta_info *sta,
-					    struct ieee80211_txrx_data *rx)
+static void ieee80211_rx_michael_mic_report(struct ieee80211_txrx_data *rx,
+					    struct ieee80211_hdr *hdr)
 {
 	int keyidx, hdrlen;
 
@@ -3224,22 +3288,22 @@ static void ieee80211_rx_michael_mic_rep
 	 * frames (hw does not verify MIC for them). */
 	printk(KERN_DEBUG "%s: TKIP hwaccel reported Michael MIC "
 	       "failure from " MACSTR " to " MACSTR " keyidx=%d\n",
-	       dev->name, MAC2STR(hdr->addr2), MAC2STR(hdr->addr1), keyidx);
+	       rx->dev->name, MAC2STR(hdr->addr2), MAC2STR(hdr->addr1), keyidx);
 
-	if (sta == NULL) {
+	if (rx->sta == NULL) {
 		/* Some hardware versions seem to generate incorrect
 		 * Michael MIC reports; ignore them to avoid triggering
 		 * countermeasures. */
 		printk(KERN_DEBUG "%s: ignored spurious Michael MIC "
 		       "error for unknown address " MACSTR "\n",
-		       dev->name, MAC2STR(hdr->addr2));
+		       rx->dev->name, MAC2STR(hdr->addr2));
 		goto ignore;
 	}
 
 	if (!(rx->fc & WLAN_FC_ISWEP)) {
 		printk(KERN_DEBUG "%s: ignored spurious Michael MIC "
 		       "error for a frame with no ISWEP flag (src "
-		       MACSTR ")\n", dev->name, MAC2STR(hdr->addr2));
+		       MACSTR ")\n", rx->dev->name, MAC2STR(hdr->addr2));
 		goto ignore;
 	}
 
@@ -3253,7 +3317,8 @@ static void ieee80211_rx_michael_mic_rep
 		if (keyidx) {
 			printk(KERN_DEBUG "%s: ignored Michael MIC error for "
 			       "a frame with non-zero keyidx (%d) (src " MACSTR
-			       ")\n", dev->name, keyidx, MAC2STR(hdr->addr2));
+			       ")\n", rx->dev->name, keyidx,
+			       MAC2STR(hdr->addr2));
 			goto ignore;
 		}
 	}
@@ -3264,7 +3329,7 @@ static void ieee80211_rx_michael_mic_rep
 		printk(KERN_DEBUG "%s: ignored spurious Michael MIC "
 		       "error for a frame that cannot be encrypted "
 		       "(fc=0x%04x) (src " MACSTR ")\n",
-		       dev->name, rx->fc, MAC2STR(hdr->addr2));
+		       rx->dev->name, rx->fc, MAC2STR(hdr->addr2));
 		goto ignore;
 	}
 
@@ -3355,11 +3420,6 @@ void __ieee80211_rx(struct net_device *d
 	else
 		sta = rx.sta = NULL;
 
-        if ((status->flag & RX_FLAG_MMIC_ERROR)) {
-		ieee80211_rx_michael_mic_report(dev, hdr, sta, &rx);
-		goto end;
-        }
-
 	if (sta && !sta->assoc_ap && !(sta->flags & WLAN_STA_WDS) &&
 	    !local->iff_promiscs && !multicast) {
 		rx.dev = sta->dev;
@@ -3444,7 +3504,6 @@ void __ieee80211_rx(struct net_device *d
 			dev_kfree_skb(skb);
 	}
 
-  end:
 	if (sta)
                 sta_info_release(local, sta);
 }
@@ -3761,6 +3820,7 @@ void ieee80211_tx_status(struct net_devi
 	struct sk_buff *skb2;
         struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
         struct ieee80211_local *local = dev->priv;
+	struct net_device *odev;
 	u16 frag, type;
 	u32 msg_type;
 
@@ -3894,7 +3954,21 @@ #endif /* IEEE80211_LEDS */
 	skb = skb2;
 
         /* Send frame to hostapd */
-        ieee80211_rx_mgmt(dev, skb, NULL, msg_type);
+	odev = dev_get_by_index(status->control.ifindex);
+	if (unlikely(odev && !is_ieee80211_device(odev))) {
+		dev_put(odev);
+		odev = NULL;
+	}
+	if (unlikely(!odev)) {
+#ifdef CONFIG_D80211_VERBOSE_DEBUG
+		printk(KERN_DEBUG "%s: Discarded tx_status from nonexistent "
+		       "device\n", dev->name);
+#endif
+		dev_kfree_skb(skb);
+		return;
+	}
+	ieee80211_rx_mgmt(odev, skb, NULL, msg_type);
+	dev_put(odev);
 }
 
 
@@ -3998,6 +4072,19 @@ void ieee80211_if_setup(struct net_devic
 	dev->destructor = ieee80211_if_free;
 }
 
+void ieee80211_if_ap_setup(struct net_device *dev)
+{
+	ether_setup(dev);
+	dev->hard_start_xmit = ieee80211_mgmt_start_xmit;
+	dev->change_mtu = ieee80211_change_mtu_apdev;
+	dev->get_stats = ieee80211_get_stats;
+	dev->open = ieee80211_ap_open;
+	dev->stop = ieee80211_ap_stop;
+	dev->type = ARPHRD_IEEE80211_PRISM;
+	dev->hard_header_parse = header_parse_80211;
+	dev->tx_queue_len = 0;
+	dev->destructor = ieee80211_if_free;
+}
 
 static void ieee80211_precalc_rates(struct ieee80211_hw *hw)
 {
@@ -4018,7 +4105,7 @@ static void ieee80211_precalc_rates(stru
 struct net_device *ieee80211_alloc_hw(size_t priv_data_len,
 				      void (*setup)(struct net_device *))
 {
-	struct net_device *apdev, *mdev;
+	struct net_device *mdev;
         struct ieee80211_local *local;
         struct ieee80211_sub_if_data *sdata;
 	int alloc_size;
@@ -4038,17 +4125,11 @@ struct net_device *ieee80211_alloc_hw(si
          * 0b84 *****************
          *      * hw_priv       *
          * 1664 *****************
-         *      * ap net_dev    *
-         * 17c0 *****************
-         *      * sub_if        *
-	 *      *****************
          */
         alloc_size = sizeof(struct net_device) +
                 sizeof(struct ieee80211_sub_if_data) + 3 +
                 sizeof(struct ieee80211_local) + 3 +
                 priv_data_len + 3 +
-                sizeof(struct net_device) + 3 +
-		sizeof(struct ieee80211_sub_if_data) + 3 +
 		4096;
         mdev = (struct net_device *) kzalloc(alloc_size, GFP_KERNEL);
 	if (mdev == NULL)
@@ -4061,15 +4142,10 @@ struct net_device *ieee80211_alloc_hw(si
 	local = mdev->priv;
 	local->hw_priv = (void *)
 		((char *) local + ((sizeof(struct ieee80211_local) + 3) & ~3));
-	apdev = (struct net_device *)
-		((char *) local->hw_priv + ((priv_data_len + 3) & ~3));
 
 	ether_setup(mdev);
 	memcpy(mdev->name, "wlan%d", 7);
 
-	if (strlen(mdev->name) + 2 >= sizeof(mdev->name))
-		goto fail;
-
 	local->dev_index = -1;
 	local->mdev = mdev;
         local->rx_handlers = ieee80211_rx_handlers;
@@ -4104,28 +4180,6 @@ struct net_device *ieee80211_alloc_hw(si
 
         ieee80211_if_init(mdev);
 
-        apdev = (struct net_device *)
-		((char *) local->hw_priv + ((priv_data_len + 3) & ~3));
-        local->apdev = apdev;
-	ether_setup(apdev);
-	apdev->priv = local;
-	apdev->hard_start_xmit = ieee80211_mgmt_start_xmit;
-	apdev->change_mtu = ieee80211_change_mtu_apdev;
-	apdev->get_stats = ieee80211_get_stats;
-        apdev->open = ieee80211_open;
-        apdev->stop = ieee80211_stop;
-	apdev->type = ARPHRD_IEEE80211_PRISM;
-        apdev->hard_header_parse = header_parse_80211;
-	apdev->tx_queue_len = 0;
-	sprintf(apdev->name, "%sap", mdev->name);
-
-        sdata = IEEE80211_DEV_TO_SUB_IF(apdev);
-        sdata->type = IEEE80211_IF_TYPE_MGMT;
-        sdata->dev = apdev;
-        sdata->master = mdev;
-        sdata->local = local;
-        list_add_tail(&sdata->list, &local->sub_if_list);
-
 	mdev->hard_start_xmit = ieee80211_master_start_xmit;
 	mdev->wireless_handlers =
 		(struct iw_handler_def *) &ieee80211_iw_handler_def;
@@ -4155,10 +4209,6 @@ struct net_device *ieee80211_alloc_hw(si
 		setup(mdev);
 
 	return mdev;
-
- fail:
-	ieee80211_free_hw(mdev);
-	return NULL;
 }
 
 
@@ -4192,15 +4242,11 @@ int ieee80211_register_hw(struct net_dev
 
 	sta_info_start(local);
 
-	result = register_netdev(local->apdev);
-	if (result < 0)
-		goto fail_1st_dev;
-
 	if (hw->fraglist)
 		dev->features |= NETIF_F_FRAGLIST;
 	result = register_netdev(dev);
 	if (result < 0)
-		goto fail_2nd_dev;
+		goto fail_dev;
 
 	if (rate_control_initialize(local) < 0) {
 		printk(KERN_DEBUG "%s: Failed to initialize rate control "
@@ -4217,9 +4263,7 @@ int ieee80211_register_hw(struct net_dev
 
 fail_rate:
 	unregister_netdev(dev);
-fail_2nd_dev:
-	unregister_netdev(local->apdev);
-fail_1st_dev:
+fail_dev:
 	sta_info_stop(local);
 	ieee80211_unregister_sysfs(local);
 fail_sysfs:
@@ -4238,12 +4282,6 @@ int ieee80211_update_hw(struct net_devic
 	if (hw->queues == 0)
 		hw->queues = 1;
 
-	memcpy(local->apdev->dev_addr, dev->dev_addr, ETH_ALEN);
-	local->apdev->base_addr = dev->base_addr;
-	local->apdev->irq = dev->irq;
-	local->apdev->mem_start = dev->mem_start;
-	local->apdev->mem_end = dev->mem_end;
-
 	if (!hw->modes || !hw->modes->channels || !hw->modes->rates ||
 	    !hw->modes->num_channels || !hw->modes->num_rates)
 		return -1;
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index 77517c9..ea1d9ab 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -189,6 +189,8 @@ typedef ieee80211_txrx_result (*ieee8021
 (struct ieee80211_txrx_data *rx);
 
 struct ieee80211_if_ap {
+	struct net_device *apdev; /* wlan#ap - management frames (hostapd) */
+
 	u8 *beacon_head, *beacon_tail;
 	int beacon_head_len, beacon_tail_len;
 
@@ -317,7 +319,6 @@ struct ieee80211_local {
 	struct ieee80211_hw *hw;
 	void *hw_priv;
 	struct net_device *mdev; /* wlan# - "master" 802.11 device */
-	struct net_device *apdev; /* wlan#ap - management frames (hostapd) */
 	int open_count;
 	int monitors;
 	struct ieee80211_conf conf;
@@ -518,6 +519,7 @@ void ieee80211_prepare_rates(struct net_
 void ieee80211_tx_set_iswep(struct ieee80211_txrx_data *tx);
 int ieee80211_if_update_wds(struct net_device *dev, u8 *remote_addr);
 void ieee80211_if_setup(struct net_device *dev);
+void ieee80211_if_ap_setup(struct net_device *dev);
 
 /* ieee80211_ioctl.c */
 int ieee80211_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
@@ -586,7 +588,7 @@ int ieee80211_dev_find_index(struct ieee
 /* ieee80211_iface.c */
 int ieee80211_if_add(struct net_device *dev, const char *name,
 		     struct net_device **new_dev);
-void ieee80211_if_set_type(struct net_device *dev, int type);
+int ieee80211_if_set_type(struct net_device *dev, int type);
 void ieee80211_if_reinit(struct net_device *dev);
 void __ieee80211_if_del(struct ieee80211_local *local,
 			struct ieee80211_sub_if_data *sdata);
diff --git a/net/d80211/ieee80211_iface.c b/net/d80211/ieee80211_iface.c
index 58fd946..d71d4f9 100644
--- a/net/d80211/ieee80211_iface.c
+++ b/net/d80211/ieee80211_iface.c
@@ -87,9 +87,65 @@ int ieee80211_if_add(struct net_device *
 	return 0;
 }
 
-void ieee80211_if_set_type(struct net_device *dev, int type)
+static int ieee80211_if_add_apdev(struct net_device *dev)
+{
+	struct net_device *ndev;
+	struct ieee80211_local *local = dev->priv;
+	struct ieee80211_sub_if_data *sdata, *nsdata;
+	int alloc_size, ret;
+
+	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	ASSERT_RTNL();
+	alloc_size = sizeof(struct net_device) + 3 +
+		sizeof(struct ieee80211_sub_if_data) + 3;
+
+	ndev = (struct net_device *) kzalloc(alloc_size, GFP_KERNEL);
+	if (ndev == NULL)
+		return -ENOMEM;
+	snprintf(ndev->name, IFNAMSIZ, "%sap", dev->name);
+
+	ndev->priv = local;
+	memcpy(ndev->dev_addr, dev->dev_addr, ETH_ALEN);
+	ndev->base_addr = dev->base_addr;
+	ndev->irq = dev->irq;
+	ndev->mem_start = dev->mem_start;
+	ndev->mem_end = dev->mem_end;
+	ieee80211_if_ap_setup(ndev);
+
+	nsdata = IEEE80211_DEV_TO_SUB_IF(ndev);
+	nsdata->type = IEEE80211_IF_TYPE_AP;
+	nsdata->master = local->mdev;
+	nsdata->dev = ndev;
+	nsdata->local = local;
+	ieee80211_if_sdata_init(nsdata);
+
+	ret = register_netdevice(ndev);
+	if (ret) {
+		if (ret == -EEXIST)
+			printk(KERN_DEBUG "%s: apdev name %s already exists\n",
+			       dev->name, ndev->name);
+		kfree(ndev);
+		return ret;
+	}
+	sdata->u.ap.apdev = ndev;
+	nsdata->u.ap.apdev = dev;
+	return 0;
+}
+
+static void ieee80211_if_del_apdev(struct net_device *dev)
 {
 	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	struct net_device *apdev;
+
+	ASSERT_RTNL();
+	apdev = sdata->u.ap.apdev;
+	unregister_netdevice(apdev);
+}
+
+int ieee80211_if_set_type(struct net_device *dev, int type)
+{
+	struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+	int res = 0;
 
 	sdata->type = type;
 	switch (type) {
@@ -104,7 +160,11 @@ void ieee80211_if_set_type(struct net_de
 		sdata->u.ap.max_ratectrl_rateidx = -1;
 		skb_queue_head_init(&sdata->u.ap.ps_bc_buf);
 		sdata->bss = &sdata->u.ap;
-		break;
+		res = ieee80211_if_add_apdev(dev);
+		if (!res)
+			break;
+		sdata->type = IEEE80211_IF_TYPE_STA;
+		/* fallback to STA, but keep error value in `res' */
 	case IEEE80211_IF_TYPE_STA:
 	case IEEE80211_IF_TYPE_IBSS: {
 		struct ieee80211_sub_if_data *msdata;
@@ -131,7 +191,9 @@ void ieee80211_if_set_type(struct net_de
 	default:
 		printk(KERN_WARNING "%s: %s: Unknown interface type 0x%x",
 		       dev->name, __FUNCTION__, type);
+		res = -EINVAL;
 	}
+	return res;
 }
 
 /* Must be called with rtnl lock held. */
@@ -183,6 +245,8 @@ #endif
 				local->total_ps_buffered--;
 				dev_kfree_skb(skb);
 			}
+
+			ieee80211_if_del_apdev(dev);
 		}
 
 		break;
@@ -257,8 +321,7 @@ int ieee80211_if_remove(struct net_devic
 	list_for_each_entry_safe(sdata, n, &local->sub_if_list, list) {
 		if ((sdata->type == id || id == -1) &&
 		    strcmp(name, sdata->dev->name) == 0 &&
-		    sdata->dev != local->mdev &&
-		    sdata->dev != local->apdev) {
+		    sdata->dev != local->mdev) {
 			__ieee80211_if_del(local, sdata);
 			return 0;
 		}
@@ -270,7 +333,7 @@ void ieee80211_if_free(struct net_device
 {
 	struct ieee80211_local *local = dev->priv;
 
-	BUG_ON(dev == local->mdev || dev == local->apdev);
+	BUG_ON(dev == local->mdev);
 	kfree(dev);
 }
 
-- 
1.3.0


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 9/10] d80211: rename master interface
  2006-04-21 20:53 [PATCH 0/10] d80211: bugfixes and reducing number of interfaces Jiri Benc
                   ` (7 preceding siblings ...)
  2006-04-21 20:53 ` [PATCH 8/10] d80211: get rid of default management interface Jiri Benc
@ 2006-04-21 20:53 ` Jiri Benc
  2006-04-21 21:02   ` Stephen Hemminger
  2006-04-21 20:53 ` [PATCH 10/10] d80211: add one default interface Jiri Benc
  9 siblings, 1 reply; 18+ messages in thread
From: Jiri Benc @ 2006-04-21 20:53 UTC (permalink / raw)
  To: netdev

Rename master interface to wmasterX to better reflect its purpose.

Signed-off-by: Jiri Benc <jbenc@suse.cz>

---

 net/d80211/ieee80211.c   |    2 +-
 net/d80211/ieee80211_i.h |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

784f203467e4421aa0ecac34cb1647f4bdfe51be
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index 31f979c..1fd13dd 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -4144,7 +4144,7 @@ struct net_device *ieee80211_alloc_hw(si
 		((char *) local + ((sizeof(struct ieee80211_local) + 3) & ~3));
 
 	ether_setup(mdev);
-	memcpy(mdev->name, "wlan%d", 7);
+	memcpy(mdev->name, "wmaster%d", 10);
 
 	local->dev_index = -1;
 	local->mdev = mdev;
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index ea1d9ab..3580d1e 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -318,7 +318,7 @@ #define IEEE80211_SUB_IF_TO_DEV(sub_if) 
 struct ieee80211_local {
 	struct ieee80211_hw *hw;
 	void *hw_priv;
-	struct net_device *mdev; /* wlan# - "master" 802.11 device */
+	struct net_device *mdev; /* wmaster# - "master" 802.11 device */
 	int open_count;
 	int monitors;
 	struct ieee80211_conf conf;
-- 
1.3.0


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 10/10] d80211: add one default interface
  2006-04-21 20:53 [PATCH 0/10] d80211: bugfixes and reducing number of interfaces Jiri Benc
                   ` (8 preceding siblings ...)
  2006-04-21 20:53 ` [PATCH 9/10] d80211: rename master interface Jiri Benc
@ 2006-04-21 20:53 ` Jiri Benc
  9 siblings, 0 replies; 18+ messages in thread
From: Jiri Benc @ 2006-04-21 20:53 UTC (permalink / raw)
  To: netdev

The wireless card is useless with master interface (wmasterX) only. Adding
at least one virtual interface is necessity for every user. To save users
a lot of pain (and to maintain backward compatibility) we should add one
virtual interface by default. It is called wlanX (hopefully the name users
are used to) and set to STA mode.

Signed-off-by: Jiri Benc <jbenc@suse.cz>

---

 net/d80211/ieee80211.c       |    9 +++++++++
 net/d80211/ieee80211_i.h     |    2 +-
 net/d80211/ieee80211_iface.c |   18 ++++++++++++------
 net/d80211/ieee80211_ioctl.c |    8 ++++----
 net/d80211/ieee80211_sysfs.c |    2 +-
 5 files changed, 27 insertions(+), 12 deletions(-)

a808727dea7cd4e8bf1185246e37a2780fb58292
diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
index 1fd13dd..a03ab09 100644
--- a/net/d80211/ieee80211.c
+++ b/net/d80211/ieee80211.c
@@ -4215,6 +4215,7 @@ struct net_device *ieee80211_alloc_hw(si
 int ieee80211_register_hw(struct net_device *dev, struct ieee80211_hw *hw)
 {
         struct ieee80211_local *local = dev->priv;
+	struct net_device *sta_dev;
 	int result;
 
 	if (!hw)
@@ -4259,6 +4260,14 @@ int ieee80211_register_hw(struct net_dev
 
         ieee80211_wep_init(local);
 	ieee80211_proc_init_interface(local);
+
+	/* add one default STA interface */
+	rtnl_lock();
+	result = ieee80211_if_add(dev, "wlan%d", 1, &sta_dev);
+	if (result == 0)
+		ieee80211_if_set_type(sta_dev, IEEE80211_IF_TYPE_STA);
+	rtnl_unlock();
+
 	return 0;
 
 fail_rate:
diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
index 3580d1e..422d198 100644
--- a/net/d80211/ieee80211_i.h
+++ b/net/d80211/ieee80211_i.h
@@ -587,7 +587,7 @@ int ieee80211_dev_find_index(struct ieee
 
 /* ieee80211_iface.c */
 int ieee80211_if_add(struct net_device *dev, const char *name,
-		     struct net_device **new_dev);
+		     int format, struct net_device **new_dev);
 int ieee80211_if_set_type(struct net_device *dev, int type);
 void ieee80211_if_reinit(struct net_device *dev);
 void __ieee80211_if_del(struct ieee80211_local *local,
diff --git a/net/d80211/ieee80211_iface.c b/net/d80211/ieee80211_iface.c
index d71d4f9..4398567 100644
--- a/net/d80211/ieee80211_iface.c
+++ b/net/d80211/ieee80211_iface.c
@@ -26,7 +26,7 @@ void ieee80211_if_sdata_init(struct ieee
 
 /* Must be called with rtnl lock held. */
 int ieee80211_if_add(struct net_device *dev, const char *name,
-		     struct net_device **new_dev)
+		     int format, struct net_device **new_dev)
 {
 	struct net_device *ndev, *tmp_dev;
 	struct ieee80211_local *local = dev->priv;
@@ -54,6 +54,10 @@ int ieee80211_if_add(struct net_device *
 				break;
 			dev_put(tmp_dev);
 		} while (i < 10000);
+	} else if (format) {
+		ret = dev_alloc_name(ndev, name);
+		if (ret)
+			goto fail;
 	} else {
 		snprintf(ndev->name, IFNAMSIZ, "%s", name);
 	}
@@ -75,16 +79,18 @@ int ieee80211_if_add(struct net_device *
 	ieee80211_if_sdata_init(sdata);
 
 	ret = register_netdevice(ndev);
-	if (ret) {
-		kfree(ndev);
-		*new_dev = NULL;
-		return ret;
-	}
+	if (ret)
+		goto fail;
 
 	list_add(&sdata->list, &local->sub_if_list);
 	ieee80211_proc_init_virtual(ndev);
 
 	return 0;
+
+fail:
+	kfree(ndev);
+	*new_dev = NULL;
+	return ret;
 }
 
 static int ieee80211_if_add_apdev(struct net_device *dev)
diff --git a/net/d80211/ieee80211_ioctl.c b/net/d80211/ieee80211_ioctl.c
index 1d3f5cf..5d31a8f 100644
--- a/net/d80211/ieee80211_ioctl.c
+++ b/net/d80211/ieee80211_ioctl.c
@@ -931,7 +931,7 @@ static int ieee80211_ioctl_add_if(struct
                 if (left < sizeof(struct hostapd_if_wds))
                         return -EPROTO;
 
-		res = ieee80211_if_add(dev, param->u.if_info.name, &new_dev);
+		res = ieee80211_if_add(dev, param->u.if_info.name, 0, &new_dev);
 		if (res)
 			return res;
 		ieee80211_if_set_type(new_dev, IEEE80211_IF_TYPE_WDS);
@@ -943,7 +943,7 @@ static int ieee80211_ioctl_add_if(struct
 		if (left < sizeof(struct hostapd_if_vlan))
 			return -EPROTO;
 
-		res = ieee80211_if_add(dev, param->u.if_info.name, &new_dev);
+		res = ieee80211_if_add(dev, param->u.if_info.name, 0, &new_dev);
 		if (res)
 			return res;
 		ieee80211_if_set_type(new_dev, IEEE80211_IF_TYPE_VLAN);
@@ -960,7 +960,7 @@ #endif
                 if (left < sizeof(struct hostapd_if_bss))
                         return -EPROTO;
 
-		res = ieee80211_if_add(dev, param->u.if_info.name, &new_dev);
+		res = ieee80211_if_add(dev, param->u.if_info.name, 0, &new_dev);
 		if (res)
 			return res;
 		ieee80211_if_set_type(new_dev, IEEE80211_IF_TYPE_AP);
@@ -975,7 +975,7 @@ #endif
                 if (left < sizeof(struct hostapd_if_sta))
                         return -EPROTO;
 
-		res = ieee80211_if_add(dev, param->u.if_info.name, &new_dev);
+		res = ieee80211_if_add(dev, param->u.if_info.name, 0, &new_dev);
 		if (res)
 			return res;
 		ieee80211_if_set_type(new_dev, IEEE80211_IF_TYPE_STA);
diff --git a/net/d80211/ieee80211_sysfs.c b/net/d80211/ieee80211_sysfs.c
index 546e2b7..463f9aa 100644
--- a/net/d80211/ieee80211_sysfs.c
+++ b/net/d80211/ieee80211_sysfs.c
@@ -30,7 +30,7 @@ static ssize_t store_add_iface(struct cl
 	if (len > IFNAMSIZ)
 		return -EINVAL;
 	rtnl_lock();
-	res = ieee80211_if_add(local->mdev, buf, &new_dev);
+	res = ieee80211_if_add(local->mdev, buf, 0, &new_dev);
 	if (res == 0)
 		ieee80211_if_set_type(new_dev, IEEE80211_IF_TYPE_STA);
 	rtnl_unlock();
-- 
1.3.0


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* Re: [PATCH 8/10] d80211: get rid of default management interface
  2006-04-21 20:53 ` [PATCH 8/10] d80211: get rid of default management interface Jiri Benc
@ 2006-04-21 20:59   ` Johannes Berg
  2006-04-21 21:03     ` Jiri Benc
  2006-04-22  2:44   ` Jouni Malinen
  1 sibling, 1 reply; 18+ messages in thread
From: Johannes Berg @ 2006-04-21 20:59 UTC (permalink / raw)
  To: Jiri Benc; +Cc: netdev, Jouni Malinen

[-- Attachment #1: Type: text/plain, Size: 484 bytes --]

On Fri, 2006-04-21 at 22:53 +0200, Jiri Benc wrote:
> Default management interface (wlanXap) confuses users. It is only needed for
> AP mode (and only until interfaces are converted to use native 802.11
> frames). 

What's the management interface used for? In some small discussion
didn't we say that we'd rather move to having one netlink socket for
this?
Maybe then we can get away with not having native 802.11 devices which
seem to somewhat scare people...

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 793 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 9/10] d80211: rename master interface
  2006-04-21 20:53 ` [PATCH 9/10] d80211: rename master interface Jiri Benc
@ 2006-04-21 21:02   ` Stephen Hemminger
  2006-04-21 21:06     ` Jiri Benc
  0 siblings, 1 reply; 18+ messages in thread
From: Stephen Hemminger @ 2006-04-21 21:02 UTC (permalink / raw)
  To: Jiri Benc; +Cc: netdev

On Fri, 21 Apr 2006 22:53:29 +0200 (CEST)
Jiri Benc <jbenc@suse.cz> wrote:

> Rename master interface to wmasterX to better reflect its purpose.
> 
> Signed-off-by: Jiri Benc <jbenc@suse.cz>
> 
> ---
> 
>  net/d80211/ieee80211.c   |    2 +-
>  net/d80211/ieee80211_i.h |    2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> 784f203467e4421aa0ecac34cb1647f4bdfe51be
> diff --git a/net/d80211/ieee80211.c b/net/d80211/ieee80211.c
> index 31f979c..1fd13dd 100644
> --- a/net/d80211/ieee80211.c
> +++ b/net/d80211/ieee80211.c
> @@ -4144,7 +4144,7 @@ struct net_device *ieee80211_alloc_hw(si
>  		((char *) local + ((sizeof(struct ieee80211_local) + 3) & ~3));
>  
>  	ether_setup(mdev);
> -	memcpy(mdev->name, "wlan%d", 7);
> +	memcpy(mdev->name, "wmaster%d", 10);

Why not use strlcpy or strncpy?  and use sizeof(mdev->name) or IFNAMSIZ
rather than hard coded 10.

>  
>  	local->dev_index = -1;
>  	local->mdev = mdev;
> diff --git a/net/d80211/ieee80211_i.h b/net/d80211/ieee80211_i.h
> index ea1d9ab..3580d1e 100644
> --- a/net/d80211/ieee80211_i.h
> +++ b/net/d80211/ieee80211_i.h
> @@ -318,7 +318,7 @@ #define IEEE80211_SUB_IF_TO_DEV(sub_if) 
>  struct ieee80211_local {
>  	struct ieee80211_hw *hw;
>  	void *hw_priv;
> -	struct net_device *mdev; /* wlan# - "master" 802.11 device */
> +	struct net_device *mdev; /* wmaster# - "master" 802.11 device */
>  	int open_count;
>  	int monitors;
>  	struct ieee80211_conf conf;

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 8/10] d80211: get rid of default management interface
  2006-04-21 20:59   ` Johannes Berg
@ 2006-04-21 21:03     ` Jiri Benc
  0 siblings, 0 replies; 18+ messages in thread
From: Jiri Benc @ 2006-04-21 21:03 UTC (permalink / raw)
  To: Johannes Berg; +Cc: netdev, Jouni Malinen

On Fri, 21 Apr 2006 22:59:58 +0200, Johannes Berg wrote:
> What's the management interface used for? In some small discussion
> didn't we say that we'd rather move to having one netlink socket for
> this?

Yes, it's just a temporary solution.

> Maybe then we can get away with not having native 802.11 devices which
> seem to somewhat scare people...

We'll see :-) It's not so important now.

-- 
Jiri Benc
SUSE Labs

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 9/10] d80211: rename master interface
  2006-04-21 21:02   ` Stephen Hemminger
@ 2006-04-21 21:06     ` Jiri Benc
  0 siblings, 0 replies; 18+ messages in thread
From: Jiri Benc @ 2006-04-21 21:06 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev

On Fri, 21 Apr 2006 14:02:54 -0700, Stephen Hemminger wrote:
> On Fri, 21 Apr 2006 22:53:29 +0200 (CEST)
> Jiri Benc <jbenc@suse.cz> wrote:
> > -	memcpy(mdev->name, "wlan%d", 7);
> > +	memcpy(mdev->name, "wmaster%d", 10);
> 
> Why not use strlcpy or strncpy?  and use sizeof(mdev->name) or IFNAMSIZ
> rather than hard coded 10.

Good idea :-) Will fix it, thanks.

 Jiri

-- 
Jiri Benc
SUSE Labs

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 8/10] d80211: get rid of default management interface
  2006-04-21 20:53 ` [PATCH 8/10] d80211: get rid of default management interface Jiri Benc
  2006-04-21 20:59   ` Johannes Berg
@ 2006-04-22  2:44   ` Jouni Malinen
  2006-04-24 13:01     ` Jiri Benc
  1 sibling, 1 reply; 18+ messages in thread
From: Jouni Malinen @ 2006-04-22  2:44 UTC (permalink / raw)
  To: Jiri Benc; +Cc: netdev

On Fri, Apr 21, 2006 at 10:53:28PM +0200, Jiri Benc wrote:
> Default management interface (wlanXap) confuses users. It is only needed for
> AP mode (and only until interfaces are converted to use native 802.11
> frames).

Or when using user space MLME in client mode which is something that I
just got working as far as scanning and association is concerned. In
other words, wpa_supplicant will be needing this interface..

> This patch removes default management interface. When a new interface is
> switched to AP mode, a management interface is created automatically. This
> also fixes some problems with multiple AP interfaces - now you have
> different management interface for each AP interface.

That sounds like something that could break multi-BSSID/SSID aware
hostapd. Are you saying that there would be new wlanXap like interface
for each BSS/VLAN interface? What are the problems this is fixing with
multiple AP interfaces? So far, hostapd has been responsible for
receiving all management from a single interface and then internally
decide which BSS/multi-SSID entry to use for each.

I would assume that hostapd could be changed to process frames from
multiple interfaces (at least if this is only for multi-BSSID, not for
multi-SSID/VLAN case). There may be some special cases, where it would
be easier to just be able to use one interface. Likewise, I would expect
single interface to be closer to a design that would be using netlink
for getting management frames into user space.

-- 
Jouni Malinen                                            PGP id EFC895FA

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 8/10] d80211: get rid of default management interface
  2006-04-22  2:44   ` Jouni Malinen
@ 2006-04-24 13:01     ` Jiri Benc
  2006-04-26 18:53       ` John W. Linville
  0 siblings, 1 reply; 18+ messages in thread
From: Jiri Benc @ 2006-04-24 13:01 UTC (permalink / raw)
  To: Jouni Malinen; +Cc: netdev

On Fri, 21 Apr 2006 19:44:31 -0700, Jouni Malinen wrote:
> On Fri, Apr 21, 2006 at 10:53:28PM +0200, Jiri Benc wrote:
> > Default management interface (wlanXap) confuses users. It is only needed for
> > AP mode (and only until interfaces are converted to use native 802.11
> > frames).
> 
> Or when using user space MLME in client mode which is something that I
> just got working as far as scanning and association is concerned. In
> other words, wpa_supplicant will be needing this interface..

I think we can (and should) wait with userspace MLME until the netlink
interface is implemented.

> That sounds like something that could break multi-BSSID/SSID aware
> hostapd. Are you saying that there would be new wlanXap like interface
> for each BSS/VLAN interface? What are the problems this is fixing with
> multiple AP interfaces?

Thinking about it more, only implementation problems. I was just lazy
and implementing things the way I did seemed to be easier. My fault,
sorry, didn't realize hostapd is aware of multiple BSSes.

> So far, hostapd has been responsible for
> receiving all management from a single interface and then internally
> decide which BSS/multi-SSID entry to use for each.
> 
> I would assume that hostapd could be changed to process frames from
> multiple interfaces (at least if this is only for multi-BSSID, not for
> multi-SSID/VLAN case).

There is no point in changing hostapd as this solution is temporary only
and hostapd will need to be changed for netlink anyway.

I will fix the patch.

Thanks,

 Jiri

-- 
Jiri Benc
SUSE Labs

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 8/10] d80211: get rid of default management interface
  2006-04-24 13:01     ` Jiri Benc
@ 2006-04-26 18:53       ` John W. Linville
  0 siblings, 0 replies; 18+ messages in thread
From: John W. Linville @ 2006-04-26 18:53 UTC (permalink / raw)
  To: Jiri Benc; +Cc: Jouni Malinen, netdev

On Mon, Apr 24, 2006 at 03:01:48PM +0200, Jiri Benc wrote:
> On Fri, 21 Apr 2006 19:44:31 -0700, Jouni Malinen wrote:
> > On Fri, Apr 21, 2006 at 10:53:28PM +0200, Jiri Benc wrote:
> > > Default management interface (wlanXap) confuses users. It is only needed for
> > > AP mode (and only until interfaces are converted to use native 802.11
> > > frames).
> > 
> > Or when using user space MLME in client mode which is something that I
> > just got working as far as scanning and association is concerned. In
> > other words, wpa_supplicant will be needing this interface..
> 
> I think we can (and should) wait with userspace MLME until the netlink
> interface is implemented.
> 
> > That sounds like something that could break multi-BSSID/SSID aware
> > hostapd. Are you saying that there would be new wlanXap like interface
> > for each BSS/VLAN interface? What are the problems this is fixing with
> > multiple AP interfaces?
> 
> Thinking about it more, only implementation problems. I was just lazy
> and implementing things the way I did seemed to be easier. My fault,
> sorry, didn't realize hostapd is aware of multiple BSSes.
> 
> > So far, hostapd has been responsible for
> > receiving all management from a single interface and then internally
> > decide which BSS/multi-SSID entry to use for each.
> > 
> > I would assume that hostapd could be changed to process frames from
> > multiple interfaces (at least if this is only for multi-BSSID, not for
> > multi-SSID/VLAN case).
> 
> There is no point in changing hostapd as this solution is temporary only
> and hostapd will need to be changed for netlink anyway.
> 
> I will fix the patch.

I'm going to skip this patch for now.  I'll merge the rest.

John
-- 
John W. Linville
linville@tuxdriver.com

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2006-04-26 18:53 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-04-21 20:53 [PATCH 0/10] d80211: bugfixes and reducing number of interfaces Jiri Benc
2006-04-21 20:53 ` [PATCH 1/10] d80211: fix SIOCGIWESSID ioctl Jiri Benc
2006-04-21 20:53 ` [PATCH 2/10] d80211: use is_multicast_ether_addr Jiri Benc
2006-04-21 20:53 ` [PATCH 3/10] d80211: fix Oops caused by packets sent directly to master device Jiri Benc
2006-04-21 20:53 ` [PATCH 4/10] d80211: don't use pointer in ieee80211_tx_control Jiri Benc
2006-04-21 20:53 ` [PATCH 5/10] d80211: per-interface SSID Jiri Benc
2006-04-21 20:53 ` [PATCH 6/10] d80211: per-interface generic_elem Jiri Benc
2006-04-21 20:53 ` [PATCH 7/10] d80211: get rid of default AP interface Jiri Benc
2006-04-21 20:53 ` [PATCH 8/10] d80211: get rid of default management interface Jiri Benc
2006-04-21 20:59   ` Johannes Berg
2006-04-21 21:03     ` Jiri Benc
2006-04-22  2:44   ` Jouni Malinen
2006-04-24 13:01     ` Jiri Benc
2006-04-26 18:53       ` John W. Linville
2006-04-21 20:53 ` [PATCH 9/10] d80211: rename master interface Jiri Benc
2006-04-21 21:02   ` Stephen Hemminger
2006-04-21 21:06     ` Jiri Benc
2006-04-21 20:53 ` [PATCH 10/10] d80211: add one default interface Jiri Benc

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).