radiotap.netbsd.org archive mirror
 help / color / mirror / Atom feed
* [Proposal]TX flags
@ 2009-04-15  0:33 Gábor Stefanik
       [not found] ` <69e28c910904141733m72ce521ap8f1865bec991fff7-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  0 siblings, 1 reply; 11+ messages in thread
From: Gábor Stefanik @ 2009-04-15  0:33 UTC (permalink / raw)
  To: radiotap-sUITvd46vNxg9hUCZPvPmw, Johannes Berg; +Cc: linux-wireless

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

I propose the following suggested Radiotap features to be standardised:

* A new, 16-bit wide "TX flags" field (field number 15), containing
the following flags:
   - TX failed due to excessive retries,
   - CTS-to-self protection,
   - RTS/CTS-handshake,
   - Frame shall not be ACKed ("No-ACK"), and
   - Sequence number shall not be recalculated ("No-Seq").

Rationale for these changes:

     1. The "excessive retries" flag can be used by the drivers to
indicate that despite numerous retransmissions, the frame was never
acknowledged. This is useful for drivers that can't return the number
of retransmissions used, e.g. when retransmissions are handled by
hardware, with no feedback about the retries used to the driver. This
should never be set together with the No-ACK flag. It only makes sense
to use this on feedback of transmitted frames. This is currently
implemented in the Linux kernel.
     2. The CTS-to-self protection flag is useful both when frames are
sent and for feedback of transmissions. The userspace can send a frame
with this flag set, to request the driver to transmit the frame with
CTS-to-self protection (this is not implemented anywhere yet). On
feedback, the driver can indicate that it automatically transmitted
the frame using CTS-to-self protection, useful if the driver can't
return the actual CTS frame (this is implemented in Linux).
     3. The RTS/CTS handshake flag can be used the same way as the
CTS-to-self flag, to request/feedback the use of RTS/CTS handshakes
for transmitting frames. The feedback part is implemented in Linux.
     4. The No-ACK flag indicates that the frame being sent shall not
be ACKed, and as such, should only be transmitted once, with no
retransmissions. This only makes sense when sending frames from
userspace, and is useful for sending frames that are not to be ACKed
according to the IEEE 802.11 specification (e.g. multicasts, ACKs,
beacons, malformed/non-standard frames).
     5. The No-Seq flag is used when sending frames from the
userspace, to indicate that the frame already has its sequence number
preconfigured, and should not be renumbered by the low-level. This is
useful for sending fragments of a frame one-by-one (fragments need to
have the same sequence number to allow correct reassembly).

This can be accomplished with the following Radiotap changes:
* Define a new field, TX flags, at number 15, with the following parameters:
   - Field contents: an unsigned 16-bit integer,
   - Field alignment: 2;
   - Define bit 0 (mask 0x0001) of this field as "TX failed due to
excessive retries",
   - Define bit 1 (mask 0x0002) as "CTS-to-self protection",
   - Define bit 2 (mask 0x0004) as "RTS/CTS handshake",
   - Define bit 3 (mask 0x0008) as "Frame shall not be ACKed",
   - Define bit 4 (mask 0x0010) as "Pre-calculated sequence number",
   - Reserve all other bits in this field (mask 0xffe0) for future use.

Two patches have been attached to implement these changes in:
 * the Linux mac80211 wireless stack (already implements the field
with bits 0, 1 and 2 for feedback only). The attached patch implements
bits 3 and 4 for sending.
 * the Wireshark network traffic analyzer, allowing dissection of the
entire field.

If no one objects to this proposal in 7 days, I will resubmit it as a
formal RFA, to allow eventual adoption.

--Gábor Stefanik

[-- Attachment #2: wireshark-radiotap-txflags.patch --]
[-- Type: text/x-patch, Size: 6366 bytes --]

 packet-radiotap.c |   84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 84 insertions(+)

Index: epan/dissectors/packet-radiotap.c
===================================================================
--- epan/dissectors/packet-radiotap.c	(revision 28045)
+++ epan/dissectors/packet-radiotap.c	(working copy)
@@ -105,6 +105,7 @@
     IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
     IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
     IEEE80211_RADIOTAP_FCS = 14,
+    IEEE80211_RADIOTAP_TX_FLAGS = 15,
     IEEE80211_RADIOTAP_XCHANNEL = 18,
     IEEE80211_RADIOTAP_EXT = 31
 };
@@ -168,6 +169,15 @@
 #define	IEEE80211_RADIOTAP_F_BADFCS	0x40	/* does not pass FCS check */
 #define	IEEE80211_RADIOTAP_F_SHORTGI	0x80	/* HT short GI */
 
+/* For IEEE80211_RADIOTAP_TX_FLAGS */
+#define IEEE80211_RADIOTAP_F_TX_FAIL	0x0001	/* failed due to excessive
+						 * retries */
+#define IEEE80211_RADIOTAP_F_TX_CTS	0x0002	/* used cts 'protection' */
+#define IEEE80211_RADIOTAP_F_TX_RTS	0x0004	/* used rts/cts handshake */
+#define IEEE80211_RADIOTAP_F_TX_NOACK	0x0008	/* frame should not be ACKed */
+#define IEEE80211_RADIOTAP_F_TX_NOSEQ	0x0010	/* sequence number handled
+						 * by userspace */
+
 /* XXX need max array size */
 static const int ieee80211_htrates[16] = {
 	13,		/* IFM_IEEE80211_MCS0 */
@@ -211,6 +221,12 @@
 static int hf_radiotap_channel_flags_sturbo = -1;
 static int hf_radiotap_channel_flags_half = -1;
 static int hf_radiotap_channel_flags_quarter = -1;
+static int hf_radiotap_txflags = -1;
+static int hf_radiotap_txflags_fail = -1;
+static int hf_radiotap_txflags_cts = -1;
+static int hf_radiotap_txflags_rts = -1;
+static int hf_radiotap_txflags_noack = -1;
+static int hf_radiotap_txflags_noseq = -1;
 static int hf_radiotap_xchannel = -1;
 static int hf_radiotap_xchannel_frequency = -1;
 static int hf_radiotap_xchannel_flags = -1;
@@ -260,6 +276,7 @@
 static int hf_radiotap_present_db_antsignal = -1;
 static int hf_radiotap_present_db_antnoise = -1;
 static int hf_radiotap_present_fcs = -1;
+static int hf_radiotap_present_txflags = -1;
 static int hf_radiotap_present_xchannel = -1;
 static int hf_radiotap_present_ext = -1;
 
@@ -282,6 +299,7 @@
 static gint ett_radiotap_present = -1;
 static gint ett_radiotap_flags = -1;
 static gint ett_radiotap_channel_flags = -1;
+static gint ett_radiotap_txflags = -1;
 static gint ett_radiotap_xchannel_flags = -1;
 
 static dissector_handle_t ieee80211_handle;
@@ -451,6 +469,7 @@
 #define RADIOTAP_MASK_DB_ANTSIGNAL          0x00001000
 #define RADIOTAP_MASK_DB_ANTNOISE           0x00002000
 #define RADIOTAP_MASK_FCS                   0x00004000
+#define RADIOTAP_MASK_TXFLAGS               0x00008000
 #define RADIOTAP_MASK_XCHANNEL              0x00040000
 #define RADIOTAP_MASK_EXT                   0x80000000
 
@@ -530,6 +549,11 @@
 	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_FCS,
 	"Specifies if the FCS field is present", HFILL } },
 
+    { &hf_radiotap_present_txflags,
+      { "TX Flags", "radiotap.present.txflags",
+	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_TXFLAGS,
+	"Specifies if the TX flags field is present", HFILL } },
+
     { &hf_radiotap_present_xchannel,
       { "Channel+", "radiotap.present.xchannel",
 	FT_BOOLEAN, 32, NULL, RADIOTAP_MASK_XCHANNEL,
@@ -653,6 +677,35 @@
        { "Quarter Rate Channel (5MHz Channel Width)", "radiotap.channel.type.quarter",
 	 FT_BOOLEAN, 16, NULL, 0x8000, "Channel Type Quarter Rate", HFILL } },
 
+    { &hf_radiotap_txflags,
+      { "TX flags", "radiotap.txflags",
+	FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL } },
+
+    { &hf_radiotap_txflags_fail,
+      { "Excessive retries", "radiotap.txflags.fail",
+	FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_F_TX_FAIL,
+	"Frame TX failed due to excessive retries", HFILL } },
+
+    { &hf_radiotap_txflags_cts,
+      { "CTS-to-self", "radiotap.txflags.cts",
+	FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_F_TX_CTS,
+	"Frame used CTS-to-self protection", HFILL } },
+
+    { &hf_radiotap_txflags_rts,
+      { "RTS/CTS", "radiotap.txflags.rts",
+	FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_F_TX_RTS,
+	"Frame was transmitted with an RTS/CTS-handshake", HFILL } },
+
+    { &hf_radiotap_txflags_noack,
+      { "No ACK expected", "radiotap.txflags.noack",
+	FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_F_TX_NOACK,
+	"Frame was transmitted once with no waiting for an ACK", HFILL } },
+
+    { &hf_radiotap_txflags_noseq,
+      { "No sequence counter", "radiotap.txflags.noseq",
+	FT_BOOLEAN, 16, NULL, IEEE80211_RADIOTAP_F_TX_NOSEQ,
+	"Frame had its sequence number configured by userspace", HFILL } },
+
     { &hf_radiotap_xchannel,
       { "Channel number", "radiotap.xchannel",
 	FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL } },
@@ -780,6 +833,7 @@
     &ett_radiotap_present,
     &ett_radiotap_flags,
     &ett_radiotap_channel_flags,
+    &ett_radiotap_txflags,
     &ett_radiotap_xchannel_flags
   };
 
@@ -896,6 +950,8 @@
 	    tvb, 4, 4, TRUE);
 	proto_tree_add_item(present_tree, hf_radiotap_present_fcs,
 	    tvb, 4, 4, TRUE);
+	proto_tree_add_item(present_tree, hf_radiotap_present_txflags,
+	    tvb, 4, 4, TRUE);
 	proto_tree_add_item(present_tree, hf_radiotap_present_xchannel,
 	    tvb, 4, 4, TRUE);
 	proto_tree_add_item(present_tree, hf_radiotap_present_ext,
@@ -1242,6 +1298,34 @@
 	    offset+=4;
 	    length_remaining-=4;
 	    break;
+	case IEEE80211_RADIOTAP_TX_FLAGS: {
+	    proto_item *it;
+
+	    align_offset = ALIGN_OFFSET(offset, 2);
+	    offset += align_offset;
+	    length_remaining -= align_offset;
+	    if (length_remaining < 2)
+		break;
+	    if (tree) {
+		flags = tvb_get_letohs(tvb, offset);
+		it = proto_tree_add_uint(radiotap_tree, hf_radiotap_txflags,
+			tvb, offset, 2, flags);
+		flags_tree = proto_item_add_subtree(it, ett_radiotap_txflags);
+		proto_tree_add_boolean(flags_tree, hf_radiotap_txflags_fail,
+			tvb, offset, 1, flags);
+		proto_tree_add_boolean(flags_tree, hf_radiotap_txflags_cts,
+			tvb, offset, 1, flags);
+		proto_tree_add_boolean(flags_tree, hf_radiotap_txflags_rts,
+			tvb, offset, 1, flags);
+		proto_tree_add_boolean(flags_tree, hf_radiotap_txflags_noack,
+			tvb, offset, 1, flags);
+		proto_tree_add_boolean(flags_tree, hf_radiotap_txflags_noseq,
+			tvb, offset, 1, flags);
+		}
+		offset+=2;
+	        length_remaining-=2;
+	    break;
+	}
 	default:
 	    /*
 	     * This indicates a field whose size we do not

[-- Attachment #3: linux-radiotap-txflags.patch --]
[-- Type: text/x-patch, Size: 4488 bytes --]

 Documentation/networking/mac80211-injection.txt |   12 +++++++++++-
 include/net/ieee80211_radiotap.h                |    3 +++
 net/mac80211/tx.c                               |   21 ++++++++++++++++-----
 3 files changed, 30 insertions(+), 6 deletions(-)

diff --git a/Documentation/networking/mac80211-injection.txt b/Documentation/networking/mac80211-injection.txt
index 84906ef..cd80f4a 100644
--- a/Documentation/networking/mac80211-injection.txt
+++ b/Documentation/networking/mac80211-injection.txt
@@ -36,10 +36,20 @@ radiotap headers and used to control injection:
    IEEE80211_RADIOTAP_F_FCS: FCS will be removed and recalculated
    IEEE80211_RADIOTAP_F_WEP: frame will be encrypted if key available
    IEEE80211_RADIOTAP_F_FRAG: frame will be fragmented if longer than the
-			      current fragmentation threshold. Note that
+			      current fragmentation threshold. (Note that
 			      this flag is only reliable when software
 			      fragmentation is enabled)
 
+
+ * IEEE80211_RADIOTAP_TX_FLAGS
+
+   IEEE80211_RADIOTAP_F_TX_NOACK: frame will be considered one that is not
+				  expected to be ACKed, and will only be
+				  transmitted once, with no retransmissions.
+   IEEE80211_RADIOTAP_F_TX_NOSEQ: frame will have its sequence number retained
+				  as handed to mac80211 by userspace, useful
+				  when injecting fragments of a single packet.
+
 The injection code can also skip all other currently defined radiotap fields
 facilitating replay of captured radiotap headers directly.
 
diff --git a/include/net/ieee80211_radiotap.h b/include/net/ieee80211_radiotap.h
index 23c3f3d..210dbd9 100644
--- a/include/net/ieee80211_radiotap.h
+++ b/include/net/ieee80211_radiotap.h
@@ -240,6 +240,9 @@ enum ieee80211_radiotap_type {
 						 * retries */
 #define IEEE80211_RADIOTAP_F_TX_CTS	0x0002	/* used cts 'protection' */
 #define IEEE80211_RADIOTAP_F_TX_RTS	0x0004	/* used rts/cts handshake */
+#define IEEE80211_RADIOTAP_F_TX_NOACK	0x0008	/* frame should not be ACKed */
+#define IEEE80211_RADIOTAP_F_TX_NOSEQ	0x0010	/* sequence number handled
+						 * by userspace */
 
 /* Ugly macro to convert literal channel numbers into their mhz equivalents
  * There are certianly some conditions that will break this (like feeding it '30')
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 3fb04a8..b47435d 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -650,6 +650,10 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
 	u8 *qc;
 	int tid;
 
+	if (unlikely(!(info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)))
+		return TX_CONTINUE;
+	info->flags &= ~IEEE80211_TX_CTL_ASSIGN_SEQ;
+
 	/*
 	 * Packet injection may want to control the sequence
 	 * number, if we have no matching interface then we
@@ -901,6 +905,7 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
 	struct ieee80211_radiotap_header *rthdr =
 		(struct ieee80211_radiotap_header *) skb->data;
 	struct ieee80211_supported_band *sband;
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
 	int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len);
 
 	sband = tx->local->hw.wiphy->bands[tx->channel->band];
@@ -947,6 +952,13 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
 			if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG)
 				tx->flags |= IEEE80211_TX_FRAGMENTED;
 			break;
+		case IEEE80211_RADIOTAP_TX_FLAGS:
+			if (*iterator.this_arg & IEEE80211_RADIOTAP_F_TX_NOACK)
+				info->flags |= IEEE80211_TX_CTL_NO_ACK;
+			if (*iterator.this_arg & IEEE80211_RADIOTAP_F_TX_NOSEQ)
+				info->flags &= ~IEEE80211_TX_CTL_ASSIGN_SEQ;
+			break;
+
 
 		/*
 		 * Please update the file
@@ -999,6 +1011,8 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
 	 * it will be cleared/left by radiotap as desired.
 	 */
 	tx->flags |= IEEE80211_TX_FRAGMENTED;
+	/* Same here, controlled by radiotap and the stack */
+	info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ;
 
 	/* process and remove the injection radiotap header */
 	sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -1062,13 +1076,10 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
 			return TX_QUEUED;
 	}
 
-	if (is_multicast_ether_addr(hdr->addr1)) {
-		tx->flags &= ~IEEE80211_TX_UNICAST;
+	if (is_multicast_ether_addr(hdr->addr1))
 		info->flags |= IEEE80211_TX_CTL_NO_ACK;
-	} else {
+	else
 		tx->flags |= IEEE80211_TX_UNICAST;
-		info->flags &= ~IEEE80211_TX_CTL_NO_ACK;
-	}
 
 	if (tx->flags & IEEE80211_TX_FRAGMENTED) {
 		if ((tx->flags & IEEE80211_TX_UNICAST) &&

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

end of thread, other threads:[~2009-04-17  9:50 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-04-15  0:33 [Proposal]TX flags Gábor Stefanik
     [not found] ` <69e28c910904141733m72ce521ap8f1865bec991fff7-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2009-04-16 15:37   ` David Young
2009-04-16 17:28   ` Johannes Berg
     [not found]     ` <1239902910.26575.14.camel-YfaajirXv2244ywRPIzf9A@public.gmane.org>
2009-04-16 18:47       ` Gábor Stefanik
     [not found]         ` <69e28c910904161147h5a68d3b5nd054b043d6ad2719-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2009-04-16 18:59           ` Johannes Berg
     [not found]             ` <1239908374.26575.20.camel-YfaajirXv2244ywRPIzf9A@public.gmane.org>
2009-04-16 19:10               ` Michael Buesch
     [not found]                 ` <200904162110.05150.mb-fseUSCV1ubazQB+pC5nmwQ@public.gmane.org>
2009-04-16 20:48                   ` David Young
     [not found]                     ` <20090416204806.GD25412-eZodSLrBbDpBDgjK7y7TUQ@public.gmane.org>
2009-04-17  1:24                       ` Gábor Stefanik
     [not found]                         ` <69e28c910904161824t7af6860dxebf3a13069b924d5-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2009-04-17  9:50                           ` Johannes Berg
2009-04-16 20:33               ` David Young
     [not found]                 ` <20090416203353.GC25412-eZodSLrBbDpBDgjK7y7TUQ@public.gmane.org>
2009-04-16 20:48                   ` Johannes Berg

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).