public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
* [RFC] allow device to stop packet mirror behaviour
@ 2007-08-07  8:25 Johannes Berg
       [not found] ` <1186475155.4067.17.camel-YfaajirXv214zXjbi5bjpg@public.gmane.org>
  2007-08-08  1:06 ` David Miller
  0 siblings, 2 replies; 6+ messages in thread
From: Johannes Berg @ 2007-08-07  8:25 UTC (permalink / raw)
  To: netdev; +Cc: Andy Green, David Miller, linux-wireless

In the wireless code, we have special 802.11+radiotap framed virtual
interfaces, mostly used to monitor traffic on the air. They also show
outgoing packets from other virtual interfaces associated with the same
PHY because you can't receive packets while sending. Due to the design
of the virtual interfaces, the packets don't pass through those
802.11+radiotap framed interfaces.

This whole setup has the additional advantage that we are able to
indicate the transmission status parameters via radiotap as well,
meaning that we can tell (in userspace) by looking at the radiotap
header whether a packet was acknowledged by the receiver, whether
RTS/CTS was used etc. This is required for implementing more things in
userspace which we plan to do in order to not have the high-complexity
MLME in the kernel.

Now, however, we run into the situation that somebody is actually
sending frames down the 802.11+radiotap framed interface. This could be
the userspace MLME implementation, for example, sending association
requests or whatever. These will now show up twice on the monitoring
interface that the userspace MLME is using, once via
dev_queue_xmit_nit() because they were sent on that interface and once
via our own mirror mechanism that also shows the transmission status
indication.

Andy has written a patch that suppresses our own mirror mechanism from
becoming effective for packets that were already mirrored out by
dev_queue_xmit_nit(), however this is not very desirable because it
makes such packets special, their transmission status information will
not be available; however, in some circumstances this information is
required (for example when implementing an MLME using 802.11+radiotap
framed interfaces.) [Also, the current implementation means that on yet
another monitor interface you don't see those frames at all.]

The only way to solve this problem therefore seems to be to suppress the
mirroring out of the packet by dev_queue_xmit_nit(). The patch below
does that by way of adding a new netdev flag.

Comments welcome.

johannes

---
Tested with three monitor interfaces and a trivial injection program on
bcm43xx-mac80211. I'll send the mac80211 patch I used as a follow-up.

 include/linux/if.h |    2 ++
 net/core/dev.c     |    4 ++--
 2 files changed, 4 insertions(+), 2 deletions(-)

--- wireless-dev.orig/include/linux/if.h	2007-08-06 21:02:55.868164177 +0200
+++ wireless-dev/include/linux/if.h	2007-08-06 21:03:05.458164177 +0200
@@ -50,6 +50,8 @@
 #define IFF_LOWER_UP	0x10000		/* driver signals L1 up		*/
 #define IFF_DORMANT	0x20000		/* driver signals dormant	*/
 
+#define IFF_NO_MIRROR	0x40000		/* driver will mirror packets	*/
+
 #define IFF_VOLATILE	(IFF_LOOPBACK|IFF_POINTOPOINT|IFF_BROADCAST|\
 		IFF_MASTER|IFF_SLAVE|IFF_RUNNING|IFF_LOWER_UP|IFF_DORMANT)
 
--- wireless-dev.orig/net/core/dev.c	2007-08-06 21:02:55.898164177 +0200
+++ wireless-dev/net/core/dev.c	2007-08-06 21:04:58.218164177 +0200
@@ -1417,7 +1417,7 @@ static int dev_gso_segment(struct sk_buf
 int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	if (likely(!skb->next)) {
-		if (!list_empty(&ptype_all))
+		if (!list_empty(&ptype_all) && !(dev->flags & IFF_NO_MIRROR))
 			dev_queue_xmit_nit(skb, dev);
 
 		if (netif_needs_gso(dev, skb)) {
@@ -2829,7 +2829,7 @@ int dev_change_flags(struct net_device *
 			       IFF_DYNAMIC | IFF_MULTICAST | IFF_PORTSEL |
 			       IFF_AUTOMEDIA)) |
 		     (dev->flags & (IFF_UP | IFF_VOLATILE | IFF_PROMISC |
-				    IFF_ALLMULTI));
+				    IFF_ALLMULTI | IFF_NO_MIRROR));
 
 	/*
 	 *	Load in the correct multicast list now the flags have changed.



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

* Re: [RFC] allow device to stop packet mirror behaviour
       [not found] ` <1186475155.4067.17.camel-YfaajirXv214zXjbi5bjpg@public.gmane.org>
@ 2007-08-07  8:27   ` Johannes Berg
  0 siblings, 0 replies; 6+ messages in thread
From: Johannes Berg @ 2007-08-07  8:27 UTC (permalink / raw)
  To: netdev; +Cc: Andy Green, David Miller, linux-wireless

This is the corresponding patch to mac80211.

It marks all monitor type interfaces with IFF_NO_MIRROR the reasons for
which I explained in the previous mail; it also marks the master device
with IFF_NO_MIRROR so you don't see *any* packets on the master device
(right now you see outgoing frames with 802.11 header.) We want to get
rid of it anyway so making it a bit more useless yet seems like a good
idea.

johannes

---
 net/mac80211/ieee80211.c       |    1 +
 net/mac80211/ieee80211_iface.c |    2 ++
 2 files changed, 3 insertions(+)

--- wireless-dev.orig/net/mac80211/ieee80211_iface.c	2007-08-06 21:14:37.398164177 +0200
+++ wireless-dev/net/mac80211/ieee80211_iface.c	2007-08-06 21:15:02.078164177 +0200
@@ -158,6 +158,7 @@ void ieee80211_if_set_type(struct net_de
 	int oldtype = sdata->type;
 
 	dev->hard_start_xmit = ieee80211_subif_start_xmit;
+	dev->flags &= ~IFF_NO_MIRROR;
 
 	sdata->type = type;
 	switch (type) {
@@ -216,6 +217,7 @@ void ieee80211_if_set_type(struct net_de
 	case IEEE80211_IF_TYPE_MNTR:
 		dev->type = ARPHRD_IEEE80211_RADIOTAP;
 		dev->hard_start_xmit = ieee80211_monitor_start_xmit;
+		dev->flags |= IFF_NO_MIRROR;
 		break;
 	default:
 		printk(KERN_WARNING "%s: %s: Unknown interface type 0x%x",
--- wireless-dev.orig/net/mac80211/ieee80211.c	2007-08-06 21:15:01.898164177 +0200
+++ wireless-dev/net/mac80211/ieee80211.c	2007-08-06 21:15:02.088164177 +0200
@@ -5138,6 +5138,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(
 	mdev->stop = ieee80211_master_stop;
 	mdev->type = ARPHRD_IEEE80211;
 	mdev->hard_header_parse = header_parse_80211;
+	mdev->flags |= IFF_NO_MIRROR;
 
 	sdata->type = IEEE80211_IF_TYPE_AP;
 	sdata->dev = mdev;

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

* Re: [RFC] allow device to stop packet mirror behaviour
  2007-08-07  8:25 [RFC] allow device to stop packet mirror behaviour Johannes Berg
       [not found] ` <1186475155.4067.17.camel-YfaajirXv214zXjbi5bjpg@public.gmane.org>
@ 2007-08-08  1:06 ` David Miller
       [not found]   ` <20070807.180607.116354128.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
  1 sibling, 1 reply; 6+ messages in thread
From: David Miller @ 2007-08-08  1:06 UTC (permalink / raw)
  To: johannes; +Cc: netdev, andy, linux-wireless

From: Johannes Berg <johannes@sipsolutions.net>
Date: Tue, 07 Aug 2007 10:25:55 +0200

> The only way to solve this problem therefore seems to be to suppress the
> mirroring out of the packet by dev_queue_xmit_nit(). The patch below
> does that by way of adding a new netdev flag.

Multicast packets also get looped back in a similar manner in the ipv4
code.  These will also be seen twice due to this issue.

There are probably many other examples as well, dev_queue_xmit_nit()
is just the tip of the iceberg.

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

* Re: [RFC] allow device to stop packet mirror behaviour
       [not found]   ` <20070807.180607.116354128.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
@ 2007-08-08  9:14     ` Johannes Berg
       [not found]       ` <1186564441.11717.5.camel-YfaajirXv214zXjbi5bjpg@public.gmane.org>
  0 siblings, 1 reply; 6+ messages in thread
From: Johannes Berg @ 2007-08-08  9:14 UTC (permalink / raw)
  To: David Miller
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, andy-/Zus8d0mwwtBDgjK7y7TUQ,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA

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

On Tue, 2007-08-07 at 18:06 -0700, David Miller wrote:
> From: Johannes Berg <johannes-cdvu00un1VgdHxzADdlk8Q@public.gmane.org>
> Date: Tue, 07 Aug 2007 10:25:55 +0200
> 
> > The only way to solve this problem therefore seems to be to suppress the
> > mirroring out of the packet by dev_queue_xmit_nit(). The patch below
> > does that by way of adding a new netdev flag.
> 
> Multicast packets also get looped back in a similar manner in the ipv4
> code.  These will also be seen twice due to this issue.

I don't think these other places are of any interest because of the
radiotap+802.11 framing on the devices where it is relevant to us; you
can't actually add an IP route to a monitor interface as far as I can
tell.

johannes

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

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

* Re: [RFC] allow device to stop packet mirror behaviour
       [not found]       ` <1186564441.11717.5.camel-YfaajirXv214zXjbi5bjpg@public.gmane.org>
@ 2007-08-08 10:17         ` David Miller
       [not found]           ` <20070808.031755.91441405.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
  0 siblings, 1 reply; 6+ messages in thread
From: David Miller @ 2007-08-08 10:17 UTC (permalink / raw)
  To: johannes-cdvu00un1VgdHxzADdlk8Q
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, andy-/Zus8d0mwwtBDgjK7y7TUQ,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA

From: Johannes Berg <johannes-cdvu00un1VgdHxzADdlk8Q@public.gmane.org>
Date: Wed, 08 Aug 2007 11:14:01 +0200

> On Tue, 2007-08-07 at 18:06 -0700, David Miller wrote:
> > From: Johannes Berg <johannes-cdvu00un1VgdHxzADdlk8Q@public.gmane.org>
> > Date: Tue, 07 Aug 2007 10:25:55 +0200
> > 
> > > The only way to solve this problem therefore seems to be to suppress the
> > > mirroring out of the packet by dev_queue_xmit_nit(). The patch below
> > > does that by way of adding a new netdev flag.
> > 
> > Multicast packets also get looped back in a similar manner in the ipv4
> > code.  These will also be seen twice due to this issue.
> 
> I don't think these other places are of any interest because of the
> radiotap+802.11 framing on the devices where it is relevant to us; you
> can't actually add an IP route to a monitor interface as far as I can
> tell.

Then I don't understand your problem.  If they are specific 802.11
protocol packets, the radio stack is in a much better situation to
filter out things like this.

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

* Re: [RFC] allow device to stop packet mirror behaviour
       [not found]           ` <20070808.031755.91441405.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
@ 2007-08-08 10:32             ` Johannes Berg
  0 siblings, 0 replies; 6+ messages in thread
From: Johannes Berg @ 2007-08-08 10:32 UTC (permalink / raw)
  To: David Miller
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, andy-/Zus8d0mwwtBDgjK7y7TUQ,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA

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

On Wed, 2007-08-08 at 03:17 -0700, David Miller wrote:

> Then I don't understand your problem.  If they are specific 802.11
> protocol packets, the radio stack is in a much better situation to
> filter out things like this.

What do you mean by radio stack? You can't really send any frames into
the monitor devices *except* raw radiotap+802.11 frames, and these are
exactly the problem because they're mirrored out right away. But because
we have a different radiotap header on outgoing than on incoming frames
to allow userspace to see the transmission indication (was the packet
ACKed by the other side etc) we ourselves mirror them out as well.

We also mirror out packets from other virtual devices associated with
the same PHY as the virtual monitor.

So think of it this way:

[ monitor interface (radiotap+802.11) ]  [ STA mode interface (802.3) ]
                                  |       |
                                  \       /
                                   \     /
                                    \   /
                                     \ /
                                [ mac80211 ]
                                      |
                                   [ PHY ]
                                      |
                             [ wireless medium ]

Now for packets that come in on the right path, they get mirrored out
back to the STA mode interface as well. That's fine. For packets that
come from the bottom, they get cloned and sent to both devices at the
top with different framing.

Additionally, packets that come in via any interface on the top are
redirected to all monitor interfaces *after* their transmission via the
PHY and are amended by a radiotap header that indicates whether the
transmission was successful. So if you run tcpdump on both interfaces
above you'll see the IPv4 multicast packet sent to the STA mode
interface come up on the STA mode interface right away, and you'll also
see it on the monitor interface after it was transmitted by the PHY.

The problem now comes in when you actually transmit a 802.11 framed
packet down the monitor device. Because the mac80211 code mirrors all
transmitted packets up to all monitor interfaces, and the generic code
mirrors the packet as soon as it was sent to the device (via
dev_queue_xmit_nit) you see it twice.

johannes

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

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

end of thread, other threads:[~2007-08-08 10:32 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-08-07  8:25 [RFC] allow device to stop packet mirror behaviour Johannes Berg
     [not found] ` <1186475155.4067.17.camel-YfaajirXv214zXjbi5bjpg@public.gmane.org>
2007-08-07  8:27   ` Johannes Berg
2007-08-08  1:06 ` David Miller
     [not found]   ` <20070807.180607.116354128.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
2007-08-08  9:14     ` Johannes Berg
     [not found]       ` <1186564441.11717.5.camel-YfaajirXv214zXjbi5bjpg@public.gmane.org>
2007-08-08 10:17         ` David Miller
     [not found]           ` <20070808.031755.91441405.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
2007-08-08 10:32             ` Johannes Berg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox