Re: [RFC] mac80211: add extap functionality

2016-02-22 Thread Grzegorz Bajorski
2016-02-19 17:24 GMT+01:00 Felix Fietkau :
> On 2016-02-19 13:05, Grzegorz Bajorski wrote:
>> 2016-02-18 15:08 GMT+01:00 Felix Fietkau :
>>> On 2016-02-18 14:36, Grzegorz Bajorski wrote:
>>>> 2016-02-17 17:55 GMT+01:00 Felix Fietkau :
>>>>> On 2016-02-17 12:55, Grzegorz Bajorski wrote:
>>>>>> Client interface briding was only possible when 4addr frames were used 
>>>>>> with
>>>>>> a 4addr/WDS aware AP. It was not possible to do it otherwise due to 3addr
>>>>>> frame limitation.
>>>>>>
>>>>>> The extap logic introduces a smart MAC address masking/translation
>>>>>> (including modyfing packets beyond SA/DA, e.g. DHCP broadcast flag is 
>>>>>> set).
>>>>>>
>>>>>> There are still some unsolved problems and bugs:
>>>>>>  - due to bridge port routing and sk_buff payload sharing skb_copy() is
>>>>>>performed; this ideally should be reworked
>>>>>>  - ipv6 support is still not finished
>>>>>>  - extap is enabled by default currently; it should be configurable via
>>>>>>nl80211 the same way 4addr is
>>>>>>
>>>>>> There's also an idea to move this as a generic link driver (just like
>>>>>> macvlan, et al) which would allow unmodified cfg80211 drivers to enjoy 
>>>>>> the
>>>>>> extap functionality. Thoughts?
>>>>>>
>>>>>> Note: This changes cfg80211 file in this single patch only for reviewing
>>>>>> convienence.
>>>>>>
>>>>>> This is an early draft to solicit comments on the design.
>>>>>>
>>>>>> Signed-off-by: Grzegorz Bajorski 
>>>>> You can get a lot of the same effect (sharing the same subnet between
>>>>> hosts behind multiple interfaces and having forwarding between them)
>>>>> without any changes to mac80211.
>>>>>
>>>>> OpenWrt uses a daemon called 'relayd' which I wrote some years ago. It
>>>>> does ARP translation, DHCP packet mangling and sets up policy routing to
>>>>> forward packets between multiple interfaces.
>>>>>
>>>>> You can find it here:
>>>>> http://git.openwrt.org/?p=project/relayd.git;a=summary
>>>>> git://git.openwrt.org/project/relayd.git
>>>>>
>>>>> Since you can cover the same use cases with user space code, I don't
>>>>> think it's a good idea to put bridge emulation hacks in the kernel's
>>>>> wireless stack.
>>>>
>>>> What about performance? Quick test show that is slow ~ 100-120 mbps
>>>> (UDP tests) and procesor is overloaded. Am I missing something? I
>>>> would expect it to be greater. (4 x 4 antena setup VHT80)
>>> What platform are you testing it on, and what kind of UDP test are you
>>> running?
>>
>> My setup it is as follows:
>> [laptop1] --eth-- [EA6500 AP] ~~rf~~ [AP148 STA w/ QCA99X0] --eth--
>> [laptop2]. I run UDP traffic between Laptop1 and Laptop2 using iperf.
>> Laptop1: iperf -s -i1 -u
>> Laptop2: iperf -i1 -c 192.168.1.108 -b 200M -t100 -u -P5 (without -P5,
>> I got similar results)
> So what kind of kernel are you running? Maybe you should use perf to
> figure out why routing is so slow.

Kernel 3.14.43 with some patches on top.

Grzegorz
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] mac80211: add extap functionality

2016-02-19 Thread Grzegorz Bajorski
2016-02-18 15:08 GMT+01:00 Felix Fietkau :
> On 2016-02-18 14:36, Grzegorz Bajorski wrote:
>> 2016-02-17 17:55 GMT+01:00 Felix Fietkau :
>>> On 2016-02-17 12:55, Grzegorz Bajorski wrote:
>>>> Client interface briding was only possible when 4addr frames were used with
>>>> a 4addr/WDS aware AP. It was not possible to do it otherwise due to 3addr
>>>> frame limitation.
>>>>
>>>> The extap logic introduces a smart MAC address masking/translation
>>>> (including modyfing packets beyond SA/DA, e.g. DHCP broadcast flag is set).
>>>>
>>>> There are still some unsolved problems and bugs:
>>>>  - due to bridge port routing and sk_buff payload sharing skb_copy() is
>>>>performed; this ideally should be reworked
>>>>  - ipv6 support is still not finished
>>>>  - extap is enabled by default currently; it should be configurable via
>>>>nl80211 the same way 4addr is
>>>>
>>>> There's also an idea to move this as a generic link driver (just like
>>>> macvlan, et al) which would allow unmodified cfg80211 drivers to enjoy the
>>>> extap functionality. Thoughts?
>>>>
>>>> Note: This changes cfg80211 file in this single patch only for reviewing
>>>> convienence.
>>>>
>>>> This is an early draft to solicit comments on the design.
>>>>
>>>> Signed-off-by: Grzegorz Bajorski 
>>> You can get a lot of the same effect (sharing the same subnet between
>>> hosts behind multiple interfaces and having forwarding between them)
>>> without any changes to mac80211.
>>>
>>> OpenWrt uses a daemon called 'relayd' which I wrote some years ago. It
>>> does ARP translation, DHCP packet mangling and sets up policy routing to
>>> forward packets between multiple interfaces.
>>>
>>> You can find it here:
>>> http://git.openwrt.org/?p=project/relayd.git;a=summary
>>> git://git.openwrt.org/project/relayd.git
>>>
>>> Since you can cover the same use cases with user space code, I don't
>>> think it's a good idea to put bridge emulation hacks in the kernel's
>>> wireless stack.
>>
>> What about performance? Quick test show that is slow ~ 100-120 mbps
>> (UDP tests) and procesor is overloaded. Am I missing something? I
>> would expect it to be greater. (4 x 4 antena setup VHT80)
> What platform are you testing it on, and what kind of UDP test are you
> running?

My setup it is as follows:
[laptop1] --eth-- [EA6500 AP] ~~rf~~ [AP148 STA w/ QCA99X0] --eth--
[laptop2]. I run UDP traffic between Laptop1 and Laptop2 using iperf.
Laptop1: iperf -s -i1 -u
Laptop2: iperf -i1 -c 192.168.1.108 -b 200M -t100 -u -P5 (without -P5,
I got similar results)

 /Grzegorz
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC] mac80211: add extap functionality

2016-02-18 Thread Grzegorz Bajorski
2016-02-17 17:55 GMT+01:00 Felix Fietkau :
> On 2016-02-17 12:55, Grzegorz Bajorski wrote:
>> Client interface briding was only possible when 4addr frames were used with
>> a 4addr/WDS aware AP. It was not possible to do it otherwise due to 3addr
>> frame limitation.
>>
>> The extap logic introduces a smart MAC address masking/translation
>> (including modyfing packets beyond SA/DA, e.g. DHCP broadcast flag is set).
>>
>> There are still some unsolved problems and bugs:
>>  - due to bridge port routing and sk_buff payload sharing skb_copy() is
>>performed; this ideally should be reworked
>>  - ipv6 support is still not finished
>>  - extap is enabled by default currently; it should be configurable via
>>nl80211 the same way 4addr is
>>
>> There's also an idea to move this as a generic link driver (just like
>> macvlan, et al) which would allow unmodified cfg80211 drivers to enjoy the
>> extap functionality. Thoughts?
>>
>> Note: This changes cfg80211 file in this single patch only for reviewing
>> convienence.
>>
>> This is an early draft to solicit comments on the design.
>>
>> Signed-off-by: Grzegorz Bajorski 
> You can get a lot of the same effect (sharing the same subnet between
> hosts behind multiple interfaces and having forwarding between them)
> without any changes to mac80211.
>
> OpenWrt uses a daemon called 'relayd' which I wrote some years ago. It
> does ARP translation, DHCP packet mangling and sets up policy routing to
> forward packets between multiple interfaces.
>
> You can find it here:
> http://git.openwrt.org/?p=project/relayd.git;a=summary
> git://git.openwrt.org/project/relayd.git
>
> Since you can cover the same use cases with user space code, I don't
> think it's a good idea to put bridge emulation hacks in the kernel's
> wireless stack.

What about performance? Quick test show that is slow ~ 100-120 mbps
(UDP tests) and procesor is overloaded. Am I missing something? I
would expect it to be greater. (4 x 4 antena setup VHT80)

/Grzegorz
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC] mac80211: add extap functionality

2016-02-17 Thread Grzegorz Bajorski
Client interface briding was only possible when 4addr frames were used with
a 4addr/WDS aware AP. It was not possible to do it otherwise due to 3addr
frame limitation.

The extap logic introduces a smart MAC address masking/translation
(including modyfing packets beyond SA/DA, e.g. DHCP broadcast flag is set).

There are still some unsolved problems and bugs:
 - due to bridge port routing and sk_buff payload sharing skb_copy() is
   performed; this ideally should be reworked
 - ipv6 support is still not finished
 - extap is enabled by default currently; it should be configurable via
   nl80211 the same way 4addr is

There's also an idea to move this as a generic link driver (just like
macvlan, et al) which would allow unmodified cfg80211 drivers to enjoy the
extap functionality. Thoughts?

Note: This changes cfg80211 file in this single patch only for reviewing
convienence.

This is an early draft to solicit comments on the design.

Signed-off-by: Grzegorz Bajorski 
---
 net/mac80211/Makefile  |   3 +-
 net/mac80211/extap.c   | 440 +
 net/mac80211/extap.h   |  31 
 net/mac80211/ieee80211_i.h |   2 +
 net/mac80211/iface.c   |   3 +
 net/mac80211/rx.c  |   5 +
 net/mac80211/tx.c  |  11 ++
 net/wireless/core.c|   2 +
 8 files changed, 496 insertions(+), 1 deletion(-)
 create mode 100644 net/mac80211/extap.c
 create mode 100644 net/mac80211/extap.h

diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile
index f9137a8..e3d7fd7 100644
--- a/net/mac80211/Makefile
+++ b/net/mac80211/Makefile
@@ -30,7 +30,8 @@ mac80211-y := \
chan.o \
trace.o mlme.o \
tdls.o \
-   ocb.o
+   ocb.o \
+   extap.o
 
 mac80211-$(CONFIG_MAC80211_LEDS) += led.o
 mac80211-$(CONFIG_MAC80211_DEBUGFS) += \
diff --git a/net/mac80211/extap.c b/net/mac80211/extap.c
new file mode 100644
index 000..852f2a0
--- /dev/null
+++ b/net/mac80211/extap.c
@@ -0,0 +1,440 @@
+ /*
+  * Copyright (c) 2016, Qualcomm Atheros Inc.
+  *
+  * Permission to use, copy, modify, and/or distribute this software for any
+  * purpose with or without fee is hereby granted, provided that the above
+  * copyright notice and this permission notice appear in all copies.
+  *
+  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+  */
+
+#include "extap.h"
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define EXPIRY_SEC 600
+#define UDP_DST_PORT 67
+#define IPV4_ADDR_LEN 4
+#define IPV6_ADDR_LEN 16
+
+#define DHCP_MSG_BOOTREQ 1
+#define DHCP_FLAG_BCAST 0x8000
+#define DHCP_COOKIE 0x63825363
+#define EXTAP_MAX_ENTRIES 512
+
+struct ip4arp {
+   struct arphdr hdr;
+   u8 ar_sha[ETH_ALEN];
+   u8 ar_sip[4];
+   u8 ar_dha[ETH_ALEN];
+   u8 ar_tip[4];
+} __packed;
+
+struct dhcphdr {
+   u8 dhcp_msg_type;
+   u8 dhcp_hw_type;
+   u8 dhcp_hw_addr_len;
+   u8 dhcp_num_hops;
+   __be32 dhcp_transc_id;
+   __be16 dhcp_secs_elapsed;
+   __be16 dhcp_flags;
+   __be32 dhcp_ciaddr;
+   __be32 dhcp_yiaddr;
+   __be32 dhcp_siaddr_nip;
+   __be32 dhcp_gateway_nip;
+   u8 dhcp_chaddr[16];
+   u8 dhcp_sname[64];
+   u8 dhcp_file[128];
+   __be32 dhcp_cookie;
+} __packed;
+
+static int extap_arp_has_ip4(struct arphdr *arp)
+{
+   return arp->ar_hln == ETH_ALEN && arp->ar_pln == IPV4_ADDR_LEN;
+}
+
+static struct ip4arp *extap_ip4arp(struct sk_buff *skb)
+{
+   struct arphdr *arp = arp_hdr(skb);
+
+   if (!arp)
+   return NULL;
+
+   if (!extap_arp_has_ip4(arp))
+   return NULL;
+
+   return (void *)arp;
+}
+
+static void extap_dhcp_hack(struct sk_buff *skb)
+{
+   struct iphdr *ip = ip_hdr(skb);
+   struct udphdr *udp = udp_hdr(skb);
+   struct dhcphdr *dhcp;
+
+   if (!ip)
+   return;
+
+   if (!udp)
+   return;
+
+   if (ip->protocol != IPPROTO_UDP)
+   return;
+
+   if (udp->dest != cpu_to_be16(UDP_DST_PORT))
+   return;
+
+   dhcp = (void *)udp + sizeof(*udp);
+
+   if (WARN_ON_ONCE(dhcp->dhcp_cookie != cpu_to_be32(DHCP_COOKIE)))
+   return;
+
+   if (dhcp->dhcp_msg_type != DHCP_MSG_BOOTREQ)
+   return;
+
+   dhcp->dhcp_flags |= cpu_to_be16(DHCP_FLAG_BCAST);
+
+   udp->ch

[PATCHv2] mac80211: allow drivers to report (non-)monitor frames

2015-12-11 Thread Grzegorz Bajorski
Some drivers offload some frames internally (e.g.
AddBa). Reporting such frames to mac80211 would
only confuse MLME. However it would be useful to
be able to pass such frames to monitor interfaces
for sniffing purposes, e.g. when running AP +
monitor.

To do that allow drivers to tell mac80211 whether
a given frame should be:
 - processed but not delivered to any monitor vif
 - not processed but delievered to monitor vifs
   only

Signed-off-by: Grzegorz Bajorski 
---

Notes:
v2:
 * fix commit log [Johannes]

 include/net/mac80211.h | 11 +++
 net/mac80211/rx.c  |  5 +++--
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 7c30faf..a35e584 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1014,6 +1014,14 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info 
*info)
  * @RX_FLAG_AMPDU_DELIM_CRC_KNOWN: The delimiter CRC field is known (the CRC
  * is stored in the @ampdu_delimiter_crc field)
  * @RX_FLAG_LDPC: LDPC was used
+ * @RX_FLAG_ONLY_MONITOR: Report frame only to monitor interfaces without
+ * processing it in any regular way.
+ * This is useful if drivers offload some frames but still want to report
+ * them for sniffing purposes.
+ * @RX_FLAG_SKIP_MONITOR: Process and report frame to all interfaces except
+ * monitor interfaces.
+ * This is useful if drivers offload some frames but still want to report
+ * them for sniffing purposes.
  * @RX_FLAG_STBC_MASK: STBC 2 bit bitmask. 1 - Nss=1, 2 - Nss=2, 3 - Nss=3
  * @RX_FLAG_10MHZ: 10 MHz (half channel) was used
  * @RX_FLAG_5MHZ: 5 MHz (quarter channel) was used
@@ -1054,6 +1062,8 @@ enum mac80211_rx_flags {
RX_FLAG_MACTIME_END = BIT(21),
RX_FLAG_VHT = BIT(22),
RX_FLAG_LDPC= BIT(23),
+   RX_FLAG_ONLY_MONITOR= BIT(24),
+   RX_FLAG_SKIP_MONITOR= BIT(25),
RX_FLAG_STBC_MASK   = BIT(26) | BIT(27),
RX_FLAG_10MHZ   = BIT(28),
RX_FLAG_5MHZ= BIT(29),
@@ -1072,6 +1082,7 @@ enum mac80211_rx_flags {
  * @RX_VHT_FLAG_160MHZ: 160 MHz was used
  * @RX_VHT_FLAG_BF: packet was beamformed
  */
+
 enum mac80211_rx_vht_flags {
RX_VHT_FLAG_80MHZ   = BIT(0),
RX_VHT_FLAG_160MHZ  = BIT(1),
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 1f82753..43ad7a5 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -122,7 +122,8 @@ static inline bool should_drop_frame(struct sk_buff *skb, 
int present_fcs_len,
hdr = (void *)(skb->data + rtap_vendor_space);
 
if (status->flag & (RX_FLAG_FAILED_FCS_CRC |
-   RX_FLAG_FAILED_PLCP_CRC))
+   RX_FLAG_FAILED_PLCP_CRC |
+   RX_FLAG_ONLY_MONITOR))
return true;
 
if (unlikely(skb->len < 16 + present_fcs_len + rtap_vendor_space))
@@ -507,7 +508,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct 
sk_buff *origskb,
return NULL;
}
 
-   if (!local->monitors) {
+   if (!local->monitors || (status->flag & RX_FLAG_SKIP_MONITOR)) {
if (should_drop_frame(origskb, present_fcs_len,
  rtap_vendor_space)) {
dev_kfree_skb(origskb);
-- 
2.3.7

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] ath10k: deliver mgmt frames from htt to monitor vifs only

2015-12-01 Thread Grzegorz Bajorski
2015-11-30 20:44 GMT+01:00 Peter Oh :
>
> On 11/30/2015 04:56 AM, Grzegorz Bajorski wrote:
>>
>> Until now only WMI originating mgmt frames were
>> reported to mac80211. Management frames on HTT
>> were basically dropped (except frames which looked
>> like management but had FCS error).
>>
>> To allow sniffing all frames (including offloaded
>> frames) without interfering with mac80211
>> operation and states a new rx_flag was introduced
>> and is not being used to distinguish frames and
>> classify them for mac80211.
>
> Does this change valid for all the firmware 10.1, 10.2, 10.4, and etc.?

Yes.

>
>>
>> Signed-off-by: Grzegorz Bajorski 
>> ---
>> depends on:
>> mac80211: allow drivers to report (non-)monitor frames
>>
>>   drivers/net/wireless/ath/ath10k/htt_rx.c | 70
>> 
>>   drivers/net/wireless/ath/ath10k/wmi.c|  6 +++
>>   2 files changed, 40 insertions(+), 36 deletions(-)
>>
>> diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c
>> b/drivers/net/wireless/ath/ath10k/htt_rx.c
>> index 396645b..898eff0 100644
>> --- a/drivers/net/wireless/ath/ath10k/htt_rx.c
>> +++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
>> @@ -1076,20 +1076,25 @@ static void ath10k_htt_rx_h_undecap_raw(struct
>> ath10k *ar,
>> hdr = (void *)msdu->data;
>> /* Tail */
>> -   skb_trim(msdu, msdu->len - ath10k_htt_rx_crypto_tail_len(ar,
>> enctype));
>> +   if (status->flag & RX_FLAG_IV_STRIPPED)
>> +   skb_trim(msdu, msdu->len -
>> +ath10k_htt_rx_crypto_tail_len(ar, enctype));
>> /* MMIC */
>> -   if (!ieee80211_has_morefrags(hdr->frame_control) &&
>> +   if ((status->flag & RX_FLAG_MMIC_STRIPPED) &&
>> +   !ieee80211_has_morefrags(hdr->frame_control) &&
>> enctype == HTT_RX_MPDU_ENCRYPT_TKIP_WPA)
>> skb_trim(msdu, msdu->len - 8);
>> /* Head */
>> -   hdr_len = ieee80211_hdrlen(hdr->frame_control);
>> -   crypto_len = ath10k_htt_rx_crypto_param_len(ar, enctype);
>> +   if (status->flag & RX_FLAG_IV_STRIPPED) {
>> +   hdr_len = ieee80211_hdrlen(hdr->frame_control);
>> +   crypto_len = ath10k_htt_rx_crypto_param_len(ar, enctype);
>>   - memmove((void *)msdu->data + crypto_len,
>> -   (void *)msdu->data, hdr_len);
>> -   skb_pull(msdu, crypto_len);
>> +   memmove((void *)msdu->data + crypto_len,
>> +   (void *)msdu->data, hdr_len);
>> +   skb_pull(msdu, crypto_len);
>> +   }
>>   }
>> static void ath10k_htt_rx_h_undecap_nwifi(struct ath10k *ar,
>> @@ -1330,6 +1335,7 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
>> bool has_tkip_err;
>> bool has_peer_idx_invalid;
>> bool is_decrypted;
>> +   bool is_mgmt;
>> u32 attention;
>> if (skb_queue_empty(amsdu))
>> @@ -1338,6 +1344,9 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
>> first = skb_peek(amsdu);
>> rxd = (void *)first->data - sizeof(*rxd);
>>   + is_mgmt = !!(rxd->attention.flags &
>> +__cpu_to_le32(RX_ATTENTION_FLAGS_MGMT_TYPE));
>> +
>> enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0),
>>  RX_MPDU_START_INFO0_ENCRYPT_TYPE);
>>   @@ -1379,6 +1388,7 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k
>> *ar,
>>   RX_FLAG_MMIC_ERROR |
>>   RX_FLAG_DECRYPTED |
>>   RX_FLAG_IV_STRIPPED |
>> + RX_FLAG_ONLY_MONITOR |
>>   RX_FLAG_MMIC_STRIPPED);
>> if (has_fcs_err)
>> @@ -1387,10 +1397,21 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k
>> *ar,
>> if (has_tkip_err)
>> status->flag |= RX_FLAG_MMIC_ERROR;
>>   - if (is_decrypted)
>> -   status->flag |= RX_FLAG_DECRYPTED |
>> -   RX_FLAG_IV_STRIPPED |
>> -   RX_FLAG_MMIC_STRIPPED;
>> +   /* Firmware reports all necessary management frames via WMI
>> already.
>> +* They are not reported to monitor interfaces at all so pass the
>> ones
>> +* coming via HTT to monitor interfaces instead. This simplifies
>> +* matters a lot.
>> +   

Re: [PATCH] mac80211: allow drivers to report (non-)monitor frames

2015-12-01 Thread Grzegorz Bajorski
already sent in [PATCH] ath10k: deliver mgmt frames from htt to
monitor vifs only.

2015-11-30 14:14 GMT+01:00 Johannes Berg :
> On Mon, 2015-11-30 at 13:54 +0100, Grzegorz Bajorski wrote:
>> This allows drivers to tell mac80211 whether given
>> frame is to be processed regularly but skip
>> monitor interface delivery or vice versa.
>>
> Can you give an example, and perhaps a corresponding driver patch?
>
> johannes



-- 
Pozdrawiam / Best Regards
Grzegorz Bajorski
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] ath10k: deliver mgmt frames from htt to monitor vifs only

2015-11-30 Thread Grzegorz Bajorski
Until now only WMI originating mgmt frames were
reported to mac80211. Management frames on HTT
were basically dropped (except frames which looked
like management but had FCS error).

To allow sniffing all frames (including offloaded
frames) without interfering with mac80211
operation and states a new rx_flag was introduced
and is not being used to distinguish frames and
classify them for mac80211.

Signed-off-by: Grzegorz Bajorski 
---
depends on:
mac80211: allow drivers to report (non-)monitor frames

 drivers/net/wireless/ath/ath10k/htt_rx.c | 70 
 drivers/net/wireless/ath/ath10k/wmi.c|  6 +++
 2 files changed, 40 insertions(+), 36 deletions(-)

diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c 
b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 396645b..898eff0 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -1076,20 +1076,25 @@ static void ath10k_htt_rx_h_undecap_raw(struct ath10k 
*ar,
hdr = (void *)msdu->data;
 
/* Tail */
-   skb_trim(msdu, msdu->len - ath10k_htt_rx_crypto_tail_len(ar, enctype));
+   if (status->flag & RX_FLAG_IV_STRIPPED)
+   skb_trim(msdu, msdu->len -
+ath10k_htt_rx_crypto_tail_len(ar, enctype));
 
/* MMIC */
-   if (!ieee80211_has_morefrags(hdr->frame_control) &&
+   if ((status->flag & RX_FLAG_MMIC_STRIPPED) &&
+   !ieee80211_has_morefrags(hdr->frame_control) &&
enctype == HTT_RX_MPDU_ENCRYPT_TKIP_WPA)
skb_trim(msdu, msdu->len - 8);
 
/* Head */
-   hdr_len = ieee80211_hdrlen(hdr->frame_control);
-   crypto_len = ath10k_htt_rx_crypto_param_len(ar, enctype);
+   if (status->flag & RX_FLAG_IV_STRIPPED) {
+   hdr_len = ieee80211_hdrlen(hdr->frame_control);
+   crypto_len = ath10k_htt_rx_crypto_param_len(ar, enctype);
 
-   memmove((void *)msdu->data + crypto_len,
-   (void *)msdu->data, hdr_len);
-   skb_pull(msdu, crypto_len);
+   memmove((void *)msdu->data + crypto_len,
+   (void *)msdu->data, hdr_len);
+   skb_pull(msdu, crypto_len);
+   }
 }
 
 static void ath10k_htt_rx_h_undecap_nwifi(struct ath10k *ar,
@@ -1330,6 +1335,7 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
bool has_tkip_err;
bool has_peer_idx_invalid;
bool is_decrypted;
+   bool is_mgmt;
u32 attention;
 
if (skb_queue_empty(amsdu))
@@ -1338,6 +1344,9 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
first = skb_peek(amsdu);
rxd = (void *)first->data - sizeof(*rxd);
 
+   is_mgmt = !!(rxd->attention.flags &
+__cpu_to_le32(RX_ATTENTION_FLAGS_MGMT_TYPE));
+
enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0),
 RX_MPDU_START_INFO0_ENCRYPT_TYPE);
 
@@ -1379,6 +1388,7 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
  RX_FLAG_MMIC_ERROR |
  RX_FLAG_DECRYPTED |
  RX_FLAG_IV_STRIPPED |
+ RX_FLAG_ONLY_MONITOR |
  RX_FLAG_MMIC_STRIPPED);
 
if (has_fcs_err)
@@ -1387,10 +1397,21 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
if (has_tkip_err)
status->flag |= RX_FLAG_MMIC_ERROR;
 
-   if (is_decrypted)
-   status->flag |= RX_FLAG_DECRYPTED |
-   RX_FLAG_IV_STRIPPED |
-   RX_FLAG_MMIC_STRIPPED;
+   /* Firmware reports all necessary management frames via WMI already.
+* They are not reported to monitor interfaces at all so pass the ones
+* coming via HTT to monitor interfaces instead. This simplifies
+* matters a lot.
+*/
+   if (is_mgmt)
+   status->flag |= RX_FLAG_ONLY_MONITOR;
+
+   if (is_decrypted) {
+   status->flag |= RX_FLAG_DECRYPTED;
+
+   if (likely(!is_mgmt))
+   status->flag |= RX_FLAG_IV_STRIPPED |
+   RX_FLAG_MMIC_STRIPPED;
+}
 
skb_queue_walk(amsdu, msdu) {
ath10k_htt_rx_h_csum_offload(msdu);
@@ -1403,6 +1424,8 @@ static void ath10k_htt_rx_h_mpdu(struct ath10k *ar,
 */
if (!is_decrypted)
continue;
+   if (is_mgmt)
+   continue;
 
hdr = (void *)msdu->data;
hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED);
@@ -1503,14 +1526,6 @@ static bool ath10k_htt_rx_amsdu_allowed(struct ath10k 
*ar,
struct sk_buff_head *amsdu,
struct ieee80211_rx_status *rx_status)
 {
- 

[PATCH] mac80211: allow drivers to report (non-)monitor frames

2015-11-30 Thread Grzegorz Bajorski
This allows drivers to tell mac80211 whether given
frame is to be processed regularly but skip
monitor interface delivery or vice versa.

Signed-off-by: Grzegorz Bajorski 
---
 include/net/mac80211.h | 11 +++
 net/mac80211/rx.c  |  5 +++--
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 7c30faf..a35e584 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1014,6 +1014,14 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info 
*info)
  * @RX_FLAG_AMPDU_DELIM_CRC_KNOWN: The delimiter CRC field is known (the CRC
  * is stored in the @ampdu_delimiter_crc field)
  * @RX_FLAG_LDPC: LDPC was used
+ * @RX_FLAG_ONLY_MONITOR: Report frame only to monitor interfaces without
+ * processing it in any regular way.
+ * This is useful if drivers offload some frames but still want to report
+ * them for sniffing purposes.
+ * @RX_FLAG_SKIP_MONITOR: Process and report frame to all interfaces except
+ * monitor interfaces.
+ * This is useful if drivers offload some frames but still want to report
+ * them for sniffing purposes.
  * @RX_FLAG_STBC_MASK: STBC 2 bit bitmask. 1 - Nss=1, 2 - Nss=2, 3 - Nss=3
  * @RX_FLAG_10MHZ: 10 MHz (half channel) was used
  * @RX_FLAG_5MHZ: 5 MHz (quarter channel) was used
@@ -1054,6 +1062,8 @@ enum mac80211_rx_flags {
RX_FLAG_MACTIME_END = BIT(21),
RX_FLAG_VHT = BIT(22),
RX_FLAG_LDPC= BIT(23),
+   RX_FLAG_ONLY_MONITOR= BIT(24),
+   RX_FLAG_SKIP_MONITOR= BIT(25),
RX_FLAG_STBC_MASK   = BIT(26) | BIT(27),
RX_FLAG_10MHZ   = BIT(28),
RX_FLAG_5MHZ= BIT(29),
@@ -1072,6 +1082,7 @@ enum mac80211_rx_flags {
  * @RX_VHT_FLAG_160MHZ: 160 MHz was used
  * @RX_VHT_FLAG_BF: packet was beamformed
  */
+
 enum mac80211_rx_vht_flags {
RX_VHT_FLAG_80MHZ   = BIT(0),
RX_VHT_FLAG_160MHZ  = BIT(1),
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 1f82753..43ad7a5 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -122,7 +122,8 @@ static inline bool should_drop_frame(struct sk_buff *skb, 
int present_fcs_len,
hdr = (void *)(skb->data + rtap_vendor_space);
 
if (status->flag & (RX_FLAG_FAILED_FCS_CRC |
-   RX_FLAG_FAILED_PLCP_CRC))
+   RX_FLAG_FAILED_PLCP_CRC |
+   RX_FLAG_ONLY_MONITOR))
return true;
 
if (unlikely(skb->len < 16 + present_fcs_len + rtap_vendor_space))
@@ -507,7 +508,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct 
sk_buff *origskb,
return NULL;
}
 
-   if (!local->monitors) {
+   if (!local->monitors || (status->flag & RX_FLAG_SKIP_MONITOR)) {
if (should_drop_frame(origskb, present_fcs_len,
  rtap_vendor_space)) {
dev_kfree_skb(origskb);
-- 
2.3.7

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html