Netdev List
 help / color / mirror / Atom feed
* [PATCH 2/3] ipv6: Add infrastructure to bind inet_peer objects to routes.
From: David Miller @ 2010-11-29 21:44 UTC (permalink / raw)
  To: netdev


They are only allowed on cached ipv6 routes.

Signed-off-by: David S. Miller <davem@davemloft.net>
---
 include/net/inetpeer.h  |   10 ++++++++++
 include/net/ip6_fib.h   |    2 ++
 include/net/ip6_route.h |    3 +++
 net/ipv4/inetpeer.c     |    2 ++
 net/ipv6/route.c        |   18 ++++++++++++++++++
 5 files changed, 35 insertions(+), 0 deletions(-)

diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h
index 834f045..fb8aeb1 100644
--- a/include/net/inetpeer.h
+++ b/include/net/inetpeer.h
@@ -11,6 +11,7 @@
 #include <linux/init.h>
 #include <linux/jiffies.h>
 #include <linux/spinlock.h>
+#include <net/ipv6.h>
 #include <asm/atomic.h>
 
 typedef struct {
@@ -61,6 +62,15 @@ static inline struct inet_peer *inet_getpeer_v4(__be32 v4daddr, int create)
 	return inet_getpeer(&daddr, create);
 }
 
+static inline struct inet_peer *inet_getpeer_v6(struct in6_addr *v6daddr, int create)
+{
+	inet_peer_address_t daddr;
+
+	ipv6_addr_copy((struct in6_addr *)daddr.a6, v6daddr);
+	daddr.family = AF_INET6;
+	return inet_getpeer(&daddr, create);
+}
+
 /* can be called from BH context or outside */
 extern void inet_putpeer(struct inet_peer *p);
 
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index 062a823..708ff7c 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -21,6 +21,7 @@
 #include <net/dst.h>
 #include <net/flow.h>
 #include <net/netlink.h>
+#include <net/inetpeer.h>
 
 #ifdef CONFIG_IPV6_MULTIPLE_TABLES
 #define FIB6_TABLE_HASHSZ 256
@@ -109,6 +110,7 @@ struct rt6_info {
 	u32				rt6i_metric;
 
 	struct inet6_dev		*rt6i_idev;
+	struct inet_peer		*rt6i_peer;
 
 #ifdef CONFIG_XFRM
 	u32				rt6i_flow_cache_genid;
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index 278312c..23fed28 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -56,6 +56,9 @@ static inline unsigned int rt6_flags2srcprefs(int flags)
 	return (flags >> 3) & 7;
 }
 
+extern void			rt6_bind_peer(struct rt6_info *rt,
+					      int create);
+
 extern void			ip6_route_input(struct sk_buff *skb);
 
 extern struct dst_entry *	ip6_route_output(struct net *net,
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
index 39f18c5..a442e99 100644
--- a/net/ipv4/inetpeer.c
+++ b/net/ipv4/inetpeer.c
@@ -533,6 +533,7 @@ struct inet_peer *inet_getpeer(inet_peer_address_t *daddr, int create)
 
 	return p;
 }
+EXPORT_SYMBOL_GPL(inet_getpeer);
 
 /* Called with local BH disabled. */
 static void peer_check_expire(unsigned long dummy)
@@ -576,3 +577,4 @@ void inet_putpeer(struct inet_peer *p)
 
 	local_bh_enable();
 }
+EXPORT_SYMBOL_GPL(inet_putpeer);
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index a0c4ad1..026caef 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -188,11 +188,29 @@ static void ip6_dst_destroy(struct dst_entry *dst)
 {
 	struct rt6_info *rt = (struct rt6_info *)dst;
 	struct inet6_dev *idev = rt->rt6i_idev;
+	struct inet_peer *peer = rt->rt6i_peer;
 
 	if (idev != NULL) {
 		rt->rt6i_idev = NULL;
 		in6_dev_put(idev);
 	}
+	if (peer) {
+		BUG_ON(!(rt->rt6i_flags & RTF_CACHE));
+		rt->rt6i_peer = NULL;
+		inet_putpeer(peer);
+	}
+}
+
+void rt6_bind_peer(struct rt6_info *rt, int create)
+{
+	struct inet_peer *peer;
+
+	if (WARN_ON(!(rt->rt6i_flags & RTF_CACHE)))
+		return;
+
+	peer = inet_getpeer_v6(&rt->rt6i_dst.addr, create);
+	if (peer && cmpxchg(&rt->rt6i_peer, NULL, peer) != NULL)
+		inet_putpeer(peer);
 }
 
 static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
-- 
1.7.3.2


^ permalink raw reply related

* [PATCH 1/3] inetpeer: Support ipv6 addresses.
From: David Miller @ 2010-11-29 21:44 UTC (permalink / raw)
  To: netdev


Signed-off-by: David S. Miller <davem@davemloft.net>
---
 include/net/inetpeer.h |   21 ++++++++++++++-
 net/ipv4/inetpeer.c    |   66 ++++++++++++++++++++++++++++++++++++++++-------
 net/ipv4/ip_fragment.c |    2 +-
 net/ipv4/route.c       |    2 +-
 net/ipv4/tcp_ipv4.c    |    6 ++--
 5 files changed, 80 insertions(+), 17 deletions(-)

diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h
index fe239bf..834f045 100644
--- a/include/net/inetpeer.h
+++ b/include/net/inetpeer.h
@@ -13,10 +13,18 @@
 #include <linux/spinlock.h>
 #include <asm/atomic.h>
 
+typedef struct {
+	union {
+		__be32		a4;
+		__be32		a6[4];
+	};
+	__u16	family;
+} inet_peer_address_t;
+
 struct inet_peer {
 	/* group together avl_left,avl_right,v4daddr to speedup lookups */
 	struct inet_peer __rcu	*avl_left, *avl_right;
-	__be32			v4daddr;	/* peer's address */
+	inet_peer_address_t	daddr;
 	__u32			avl_height;
 	struct list_head	unused;
 	__u32			dtime;		/* the time of last use of not
@@ -42,7 +50,16 @@ struct inet_peer {
 void			inet_initpeers(void) __init;
 
 /* can be called with or without local BH being disabled */
-struct inet_peer	*inet_getpeer(__be32 daddr, int create);
+struct inet_peer	*inet_getpeer(inet_peer_address_t *daddr, int create);
+
+static inline struct inet_peer *inet_getpeer_v4(__be32 v4daddr, int create)
+{
+	inet_peer_address_t daddr;
+
+	daddr.a4 = v4daddr;
+	daddr.family = AF_INET;
+	return inet_getpeer(&daddr, create);
+}
 
 /* can be called from BH context or outside */
 extern void inet_putpeer(struct inet_peer *p);
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
index 9e94d7c..39f18c5 100644
--- a/net/ipv4/inetpeer.c
+++ b/net/ipv4/inetpeer.c
@@ -19,6 +19,7 @@
 #include <linux/net.h>
 #include <net/ip.h>
 #include <net/inetpeer.h>
+#include <net/ipv6.h>
 
 /*
  *  Theory of operations.
@@ -152,11 +153,53 @@ static void unlink_from_unused(struct inet_peer *p)
 	}
 }
 
+static inline bool inet_peer_addr_equal(inet_peer_address_t *a, inet_peer_address_t *b)
+{
+	if (a->family == b->family) {
+		switch (a->family) {
+		case AF_INET:
+			if (a->a4 == b->a4)
+				return true;
+			break;
+		case AF_INET6:
+			if (!ipv6_addr_cmp((struct in6_addr *)a,
+					   (struct in6_addr *)b))
+				return true;
+			break;
+		default:
+			break;
+		}
+	}
+	return false;
+}
+
+static inline u32 inet_peer_key(inet_peer_address_t *a)
+{
+	u32 key;
+
+	switch (a->family) {
+	case AF_INET:
+		key = (__force __u32) a->a4;
+		break;
+	case AF_INET6:
+		key = ((__force __u32)a->a6[0] ^
+		       (__force __u32)a->a6[1] ^
+		       (__force __u32)a->a6[2] ^
+		       (__force __u32)a->a6[3]);
+		break;
+	default:
+		key = 0;
+		break;
+	}
+	return key;
+}
+
 /*
  * Called with local BH disabled and the pool lock held.
  */
 #define lookup(_daddr, _stack) 					\
 ({								\
+	u32 key = inet_peer_key(_daddr);			\
 	struct inet_peer *u;					\
 	struct inet_peer __rcu **v;				\
 								\
@@ -165,9 +208,9 @@ static void unlink_from_unused(struct inet_peer *p)
 	for (u = rcu_dereference_protected(peers.root,		\
 			lockdep_is_held(&peers.lock));		\
 	     u != peer_avl_empty; ) {				\
-		if (_daddr == u->v4daddr)			\
+		if (inet_peer_addr_equal(_daddr, &u->daddr))	\
 			break;					\
-		if ((__force __u32)_daddr < (__force __u32)u->v4daddr)	\
+		if (key < inet_peer_key(&u->daddr))		\
 			v = &u->avl_left;			\
 		else						\
 			v = &u->avl_right;			\
@@ -185,13 +228,14 @@ static void unlink_from_unused(struct inet_peer *p)
  * But every pointer we follow is guaranteed to be valid thanks to RCU.
  * We exit from this function if number of links exceeds PEER_MAXDEPTH
  */
-static struct inet_peer *lookup_rcu_bh(__be32 daddr)
+static struct inet_peer *lookup_rcu_bh(inet_peer_address_t *daddr)
 {
 	struct inet_peer *u = rcu_dereference_bh(peers.root);
+	u32 key = inet_peer_key(daddr);
 	int count = 0;
 
 	while (u != peer_avl_empty) {
-		if (daddr == u->v4daddr) {
+		if (inet_peer_addr_equal(daddr, &u->daddr)) {
 			/* Before taking a reference, check if this entry was
 			 * deleted, unlink_from_pool() sets refcnt=-1 to make
 			 * distinction between an unused entry (refcnt=0) and
@@ -201,7 +245,7 @@ static struct inet_peer *lookup_rcu_bh(__be32 daddr)
 				u = NULL;
 			return u;
 		}
-		if ((__force __u32)daddr < (__force __u32)u->v4daddr)
+		if (key < inet_peer_key(&u->daddr))
 			u = rcu_dereference_bh(u->avl_left);
 		else
 			u = rcu_dereference_bh(u->avl_right);
@@ -353,7 +397,7 @@ static void unlink_from_pool(struct inet_peer *p)
 	if (atomic_cmpxchg(&p->refcnt, 1, -1) == 1) {
 		struct inet_peer __rcu **stack[PEER_MAXDEPTH];
 		struct inet_peer __rcu ***stackptr, ***delp;
-		if (lookup(p->v4daddr, stack) != p)
+		if (lookup(&p->daddr, stack) != p)
 			BUG();
 		delp = stackptr - 1; /* *delp[0] == p */
 		if (p->avl_left == peer_avl_empty_rcu) {
@@ -366,7 +410,7 @@ static void unlink_from_pool(struct inet_peer *p)
 			BUG_ON(rcu_dereference_protected(*stackptr[-1],
 					lockdep_is_held(&peers.lock)) != t);
 			**--stackptr = t->avl_left;
-			/* t is removed, t->v4daddr > x->v4daddr for any
+			/* t is removed, t->daddr > x->daddr for any
 			 * x in p->avl_left subtree.
 			 * Put t in the old place of p. */
 			RCU_INIT_POINTER(*delp[0], t);
@@ -433,7 +477,7 @@ static int cleanup_once(unsigned long ttl)
 }
 
 /* Called with or without local BH being disabled. */
-struct inet_peer *inet_getpeer(__be32 daddr, int create)
+struct inet_peer *inet_getpeer(inet_peer_address_t *daddr, int create)
 {
 	struct inet_peer *p;
 	struct inet_peer __rcu **stack[PEER_MAXDEPTH], ***stackptr;
@@ -467,10 +511,12 @@ struct inet_peer *inet_getpeer(__be32 daddr, int create)
 	}
 	p = create ? kmem_cache_alloc(peer_cachep, GFP_ATOMIC) : NULL;
 	if (p) {
-		p->v4daddr = daddr;
+		p->daddr = *daddr;
 		atomic_set(&p->refcnt, 1);
 		atomic_set(&p->rid, 0);
-		atomic_set(&p->ip_id_count, secure_ip_id(daddr));
+		atomic_set(&p->ip_id_count,
+			   (daddr->family == AF_INET) ?
+			   secure_ip_id(daddr->a4) : 0);
 		p->tcp_ts_stamp = 0;
 		INIT_LIST_HEAD(&p->unused);
 
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index 1684408..e6215bd 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -141,7 +141,7 @@ static void ip4_frag_init(struct inet_frag_queue *q, void *a)
 	qp->daddr = arg->iph->daddr;
 	qp->user = arg->user;
 	qp->peer = sysctl_ipfrag_max_dist ?
-		inet_getpeer(arg->iph->saddr, 1) : NULL;
+		inet_getpeer_v4(arg->iph->saddr, 1) : NULL;
 }
 
 static __inline__ void ip4_frag_free(struct inet_frag_queue *q)
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index ec2333f..3843c2d 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1289,7 +1289,7 @@ void rt_bind_peer(struct rtable *rt, int create)
 {
 	struct inet_peer *peer;
 
-	peer = inet_getpeer(rt->rt_dst, create);
+	peer = inet_getpeer_v4(rt->rt_dst, create);
 
 	if (peer && cmpxchg(&rt->peer, NULL, peer) != NULL)
 		inet_putpeer(peer);
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 69ccbc1..00285fc 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1347,7 +1347,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
 		    tcp_death_row.sysctl_tw_recycle &&
 		    (dst = inet_csk_route_req(sk, req)) != NULL &&
 		    (peer = rt_get_peer((struct rtable *)dst)) != NULL &&
-		    peer->v4daddr == saddr) {
+		    peer->daddr.a4 == saddr) {
 			inet_peer_refcheck(peer);
 			if ((u32)get_seconds() - peer->tcp_ts_stamp < TCP_PAWS_MSL &&
 			    (s32)(peer->tcp_ts - req->ts_recent) >
@@ -1778,7 +1778,7 @@ int tcp_v4_remember_stamp(struct sock *sk)
 	int release_it = 0;
 
 	if (!rt || rt->rt_dst != inet->inet_daddr) {
-		peer = inet_getpeer(inet->inet_daddr, 1);
+		peer = inet_getpeer_v4(inet->inet_daddr, 1);
 		release_it = 1;
 	} else {
 		if (!rt->peer)
@@ -1804,7 +1804,7 @@ EXPORT_SYMBOL(tcp_v4_remember_stamp);
 
 int tcp_v4_tw_remember_stamp(struct inet_timewait_sock *tw)
 {
-	struct inet_peer *peer = inet_getpeer(tw->tw_daddr, 1);
+	struct inet_peer *peer = inet_getpeer_v4(tw->tw_daddr, 1);
 
 	if (peer) {
 		const struct tcp_timewait_sock *tcptw = tcp_twsk((struct sock *)tw);
-- 
1.7.3.2


^ permalink raw reply related

* [PATCH 0/3] IPv6 inetpeer support
From: David Miller @ 2010-11-29 21:43 UTC (permalink / raw)
  To: netdev


Here is the beginning of some refactoring I've been working on.

It's a respin of my older inet-peer ipv6 support patch plus the
beginnings of what's necessary to support TCP time-wait recycling
in ipv6 too.

I also intend to investigate more deeply putting metrics into
the inet-peer cache, but nothing about that is in this series
as that is still a not so clear-and-dry issue.

Supporting the same set of TCP features in both ipv4 and ipv6
is, on the other hand, less controversial so I think we should
do the ipv6 inet-peer thing no matter what.

^ permalink raw reply

* Re: [net-next-2.6] XFRM: remove unused member in xfrm_encap_tmpl.
From: Timo Teräs @ 2010-11-29 20:35 UTC (permalink / raw)
  To: David Shwatrz; +Cc: David S. Miller, netdev
In-Reply-To: <AANLkTimfUFuJKMwp6X65z_NRE4pPKy-6_fEu19Gaqycm@mail.gmail.com>

On 11/29/2010 10:09 PM, David Shwatrz wrote:
> Timo,
> Thanks for your answer.
> 
>> Alternatively the other RFCs say that the checksum can be just
>> recalculated. That's what the linux stack does: it throws the old
>> checksum away (ignored on local receive and recalculated on send
>> forward paths).
> 
> Sorry, something here seems to me still wrong; maybe I miss something.
> We are talking about transport mode. Let's take TCP for example.
> the packet is received by another peer. It is on port 4500 because of
> NAT-T. Since it is ESP encrypted , it is it is decrypted. It reaches
> the TCP layer. In TCP (as opposed to UDP), the checksum is mandatory.
> But the checksum in that TCP header of the received
> packet will not be correct, since the IP header of that packet is
> **NOT** the original address ; the IP address was changed by the NAT.
> The NAT  cannot change the TCP checksum since it is encrypted. So
> wouldn't we have a checksum error in the case of TCP ?  It seems to me
> that the purpose of NAT-OA was to pass the
> original address, so that there will be no error in such a case.
> But again, maybe I miss something, since I did not heard that
> transport mode has any problems with NAT-T. Or maybe this was not
> tested?

Yes, it's the primary use case for NAT-OA, to allow "fast" update of the
checksum.

The Linux way works too. It's tested.

Like I said, the IPsec stack says to TCP/UDP stack part "I've already
check the checksum, do not look at it". If the packet is forwarded the
kernel (or NIC hardware) *recalculates* the proper checksum; as if it
was generating the packet in first place.

Using NAT-OA to update checksum is purely an optimisation; mostly useful
only when forwarding form one IPsec tunnel to another one which does not
happen often in transport mode (perhaps only in some very special NAT
setups).

^ permalink raw reply

* [PATCH net-next-2.6] can: add slcan driver for serial/USB-serial CAN adapters
From: Oliver Hartkopp @ 2010-11-29 20:30 UTC (permalink / raw)
  To: David Miller; +Cc: SocketCAN Core Mailing List, Linux Netdev List, Alan Cox

This patch adds support for serial/USB-serial CAN adapters implementing the
LAWICEL ASCII protocol for CAN frame transport over serial lines.

The driver implements the SLCAN line discipline and is heavily based on the
slip.c driver. Therefore the code style remains similar to slip.c to be able
to apply changes of the SLIP driver to the SLCAN driver easily.

For more details see the slcan Kconfig entry.

Signed-off-by: Oliver Hartkopp <socketcan-fJ+pQTUTwRTk1uMJSBkQmQ@public.gmane.org>

---

diff -u -r -N a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
--- a/drivers/net/can/Kconfig	2010-11-29 20:36:31.000000000 +0100
+++ b/drivers/net/can/Kconfig	2010-11-29 20:48:47.000000000 +0100
@@ -12,6 +12,27 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called vcan.
 
+config CAN_SLCAN
+	tristate "Serial / USB serial CAN Adaptors (slcan)"
+	depends on CAN
+	default N
+	---help---
+	  CAN driver for several 'low cost' CAN interfaces that are attached
+	  via serial lines or via USB-to-serial adapters using the LAWICEL
+	  ASCII protocol. The driver implements the tty linediscipline N_SLCAN.
+
+	  As only the sending and receiving of CAN frames is implemented, this
+	  driver should work with the (serial/USB) CAN hardware from:
+	  www.canusb.com / www.can232.com / www.mictronic.com / www.canhack.de
+
+	  Userspace tools to attach the SLCAN line discipline (slcan_attach,
+	  slcand) can be found in the can-utils at the SocketCAN SVN, see
+	  http://developer.berlios.de/projects/socketcan for details.
+
+	  The slcan driver supports up to 10 CAN netdevices by default which
+	  can be changed by the 'maxdev=xx' module option. This driver can
+	  also be built as a module. If so, the module will be called slcan.
+
 config CAN_DEV
 	tristate "Platform CAN drivers with Netlink support"
 	depends on CAN
diff -u -r -N a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c
--- a/drivers/net/can/slcan.c	1970-01-01 01:00:00.000000000 +0100
+++ b/drivers/net/can/slcan.c	2010-11-29 20:59:59.000000000 +0100
@@ -0,0 +1,755 @@
+/*
+ * slcan.c - serial line CAN interface driver (using tty line discipline)
+ *
+ * This file is derived from linux/drivers/net/slip.c
+ *
+ * slip.c Authors  : Laurence Culhane <loz-ft9vOCmwNo6HCRyBVyKX4rVCufUGDwFn@public.gmane.org>
+ *                   Fred N. van Kempen <waltje-exq35+CbV4/bARYX+r8/SUB+6BGkLq7r@public.gmane.org>
+ * slcan.c Author  : Oliver Hartkopp <socketcan-fJ+pQTUTwRTk1uMJSBkQmQ@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307. You can also get it
+ * at http://www.gnu.org/licenses/gpl.html
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Send feedback to <socketcan-users-0fE9KPoRgkgATYTw5x5z8w@public.gmane.org>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+
+#include <asm/system.h>
+#include <linux/uaccess.h>
+#include <linux/bitops.h>
+#include <linux/string.h>
+#include <linux/tty.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/rtnetlink.h>
+#include <linux/if_arp.h>
+#include <linux/if_ether.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/can.h>
+
+static __initdata const char banner[] =
+	KERN_INFO "slcan: serial line CAN interface driver\n";
+
+MODULE_ALIAS_LDISC(N_SLCAN);
+MODULE_DESCRIPTION("serial line CAN interface");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Oliver Hartkopp <socketcan-fJ+pQTUTwRTk1uMJSBkQmQ@public.gmane.org>");
+
+#define SLCAN_MAGIC 0x53CA
+
+static int maxdev = 10;		/* MAX number of SLCAN channels;
+				   This can be overridden with
+				   insmod slcan.ko maxdev=nnn	*/
+module_param(maxdev, int, 0);
+MODULE_PARM_DESC(maxdev, "Maximum number of slcan interfaces");
+
+/* maximum rx buffer len: extended CAN frame with timestamp */
+#define SLC_MTU (sizeof("T1111222281122334455667788EA5F\r")+1)
+
+struct slcan {
+	int			magic;
+
+	/* Various fields. */
+	struct tty_struct	*tty;		/* ptr to TTY structure	     */
+	struct net_device	*dev;		/* easy for intr handling    */
+	spinlock_t		lock;
+
+	/* These are pointers to the malloc()ed frame buffers. */
+	unsigned char		rbuff[SLC_MTU];	/* receiver buffer	     */
+	int			rcount;         /* received chars counter    */
+	unsigned char		xbuff[SLC_MTU];	/* transmitter buffer	     */
+	unsigned char		*xhead;         /* pointer to next XMIT byte */
+	int			xleft;          /* bytes left in XMIT queue  */
+
+	unsigned long		flags;		/* Flag values/ mode etc     */
+#define SLF_INUSE		0		/* Channel in use            */
+#define SLF_ERROR		1               /* Parity, etc. error        */
+
+	unsigned char		leased;
+	dev_t			line;
+	pid_t			pid;
+};
+
+static struct net_device **slcan_devs;
+
+ /************************************************************************
+  *			SLCAN ENCAPSULATION FORMAT			 *
+  ************************************************************************/
+
+/*
+ * A CAN frame has a can_id (11 bit standard frame format OR 29 bit extended
+ * frame format) a data length code (can_dlc) which can be from 0 to 8
+ * and up to <can_dlc> data bytes as payload.
+ * Additionally a CAN frame may become a remote transmission frame if the
+ * RTR-bit is set. This causes another ECU to send a CAN frame with the
+ * given can_id.
+ *
+ * The SLCAN ASCII representation of these different frame types is:
+ * <type> <id> <dlc> <data>*
+ *
+ * Extended frames (29 bit) are defined by capital characters in the type.
+ * RTR frames are defined as 'r' types - normal frames have 't' type:
+ * t => 11 bit data frame
+ * r => 11 bit RTR frame
+ * T => 29 bit data frame
+ * R => 29 bit RTR frame
+ *
+ * The <id> is 3 (standard) or 8 (extended) bytes in ASCII Hex (base64).
+ * The <dlc> is a one byte ASCII number ('0' - '8')
+ * The <data> section has at much ASCII Hex bytes as defined by the <dlc>
+ *
+ * Examples:
+ *
+ * t1230 : can_id 0x123, can_dlc 0, no data
+ * t4563112233 : can_id 0x456, can_dlc 3, data 0x11 0x22 0x33
+ * T12ABCDEF2AA55 : extended can_id 0x12ABCDEF, can_dlc 2, data 0xAA 0x55
+ * r1230 : can_id 0x123, can_dlc 0, no data, remote transmission request
+ *
+ */
+
+ /************************************************************************
+  *			STANDARD SLCAN DECAPSULATION			 *
+  ************************************************************************/
+
+static int asc2nibble(char c)
+{
+
+	if ((c >= '0') && (c <= '9'))
+		return c - '0';
+
+	if ((c >= 'A') && (c <= 'F'))
+		return c - 'A' + 10;
+
+	if ((c >= 'a') && (c <= 'f'))
+		return c - 'a' + 10;
+
+	return 16; /* error */
+}
+
+/* Send one completely decapsulated can_frame to the network layer */
+static void slc_bump(struct slcan *sl)
+{
+	struct sk_buff *skb;
+	struct can_frame cf;
+	int i, dlc_pos, tmp;
+	unsigned long ultmp;
+	char cmd = sl->rbuff[0];
+
+	if ((cmd != 't') && (cmd != 'T') && (cmd != 'r') && (cmd != 'R'))
+		return;
+
+	if (cmd & 0x20) /* tiny chars 'r' 't' => standard frame format */
+		dlc_pos = 4; /* dlc position tiiid */
+	else
+		dlc_pos = 9; /* dlc position Tiiiiiiiid */
+
+	if (!((sl->rbuff[dlc_pos] >= '0') && (sl->rbuff[dlc_pos] < '9')))
+		return;
+
+	cf.can_dlc = sl->rbuff[dlc_pos] - '0'; /* get can_dlc from ASCII val */
+
+	sl->rbuff[dlc_pos] = 0; /* terminate can_id string */
+
+	if (strict_strtoul(sl->rbuff+1, 16, &ultmp))
+		return;
+
+	cf.can_id = ultmp;
+
+	if (!(cmd & 0x20)) /* NO tiny chars => extended frame format */
+		cf.can_id |= CAN_EFF_FLAG;
+
+	if ((cmd | 0x20) == 'r') /* RTR frame */
+		cf.can_id |= CAN_RTR_FLAG;
+
+	*(u64 *) (&cf.data) = 0; /* clear payload */
+
+	for (i = 0, dlc_pos++; i < cf.can_dlc; i++) {
+
+		tmp = asc2nibble(sl->rbuff[dlc_pos++]);
+		if (tmp > 0x0F)
+			return;
+		cf.data[i] = (tmp << 4);
+		tmp = asc2nibble(sl->rbuff[dlc_pos++]);
+		if (tmp > 0x0F)
+			return;
+		cf.data[i] |= tmp;
+	}
+
+
+	skb = dev_alloc_skb(sizeof(struct can_frame));
+	if (!skb)
+		return;
+
+	skb->dev = sl->dev;
+	skb->protocol = htons(ETH_P_CAN);
+	skb->pkt_type = PACKET_BROADCAST;
+	skb->ip_summed = CHECKSUM_UNNECESSARY;
+	memcpy(skb_put(skb, sizeof(struct can_frame)),
+	       &cf, sizeof(struct can_frame));
+	netif_rx(skb);
+
+	sl->dev->stats.rx_packets++;
+	sl->dev->stats.rx_bytes += cf.can_dlc;
+}
+
+/* parse tty input stream */
+static void slcan_unesc(struct slcan *sl, unsigned char s)
+{
+
+	if ((s == '\r') || (s == '\a')) { /* CR or BEL ends the pdu */
+		if (!test_and_clear_bit(SLF_ERROR, &sl->flags) &&
+		    (sl->rcount > 4))  {
+			slc_bump(sl);
+		}
+		sl->rcount = 0;
+	} else {
+		if (!test_bit(SLF_ERROR, &sl->flags))  {
+			if (sl->rcount < SLC_MTU)  {
+				sl->rbuff[sl->rcount++] = s;
+				return;
+			} else {
+				sl->dev->stats.rx_over_errors++;
+				set_bit(SLF_ERROR, &sl->flags);
+			}
+		}
+	}
+}
+
+ /************************************************************************
+  *			STANDARD SLCAN ENCAPSULATION			 *
+  ************************************************************************/
+
+/* Encapsulate one can_frame and stuff into a TTY queue. */
+static void slc_encaps(struct slcan *sl, struct can_frame *cf)
+{
+	int actual, idx, i;
+	char cmd;
+
+	if (cf->can_id & CAN_RTR_FLAG)
+		cmd = 'R'; /* becomes 'r' in standard frame format */
+	else
+		cmd = 'T'; /* becomes 't' in standard frame format */
+
+	if (cf->can_id & CAN_EFF_FLAG)
+		sprintf(sl->xbuff, "%c%08X%d", cmd,
+			cf->can_id & CAN_EFF_MASK, cf->can_dlc);
+	else
+		sprintf(sl->xbuff, "%c%03X%d", cmd | 0x20,
+			cf->can_id & CAN_SFF_MASK, cf->can_dlc);
+
+	idx = strlen(sl->xbuff);
+
+	for (i = 0; i < cf->can_dlc; i++)
+		sprintf(&sl->xbuff[idx + 2*i], "%02X", cf->data[i]);
+
+	strcat(sl->xbuff, "\r"); /* add terminating character */
+
+	/* Order of next two lines is *very* important.
+	 * When we are sending a little amount of data,
+	 * the transfer may be completed inside the ops->write()
+	 * routine, because it's running with interrupts enabled.
+	 * In this case we *never* got WRITE_WAKEUP event,
+	 * if we did not request it before write operation.
+	 *       14 Oct 1994  Dmitry Gorodchanin.
+	 */
+	set_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
+	actual = sl->tty->ops->write(sl->tty, sl->xbuff, strlen(sl->xbuff));
+	sl->xleft = strlen(sl->xbuff) - actual;
+	sl->xhead = sl->xbuff + actual;
+	sl->dev->stats.tx_bytes += cf->can_dlc;
+}
+
+/*
+ * Called by the driver when there's room for more data.  If we have
+ * more packets to send, we send them here.
+ */
+static void slcan_write_wakeup(struct tty_struct *tty)
+{
+	int actual;
+	struct slcan *sl = (struct slcan *) tty->disc_data;
+
+	/* First make sure we're connected. */
+	if (!sl || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev))
+		return;
+
+	if (sl->xleft <= 0)  {
+		/* Now serial buffer is almost free & we can start
+		 * transmission of another packet */
+		sl->dev->stats.tx_packets++;
+		clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+		netif_wake_queue(sl->dev);
+		return;
+	}
+
+	actual = tty->ops->write(tty, sl->xhead, sl->xleft);
+	sl->xleft -= actual;
+	sl->xhead += actual;
+}
+
+/* Send a can_frame to a TTY queue. */
+static netdev_tx_t slc_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct slcan *sl = netdev_priv(dev);
+
+	if (skb->len != sizeof(struct can_frame))
+		goto out;
+
+	spin_lock(&sl->lock);
+	if (!netif_running(dev))  {
+		spin_unlock(&sl->lock);
+		printk(KERN_WARNING "%s: xmit: iface is down\n", dev->name);
+		goto out;
+	}
+	if (sl->tty == NULL) {
+		spin_unlock(&sl->lock);
+		goto out;
+	}
+
+	netif_stop_queue(sl->dev);
+	slc_encaps(sl, (struct can_frame *) skb->data); /* encaps & send */
+	spin_unlock(&sl->lock);
+
+out:
+	kfree_skb(skb);
+	return NETDEV_TX_OK;
+}
+
+
+/******************************************
+ *   Routines looking at netdevice side.
+ ******************************************/
+
+/* Netdevice UP -> DOWN routine */
+static int slc_close(struct net_device *dev)
+{
+	struct slcan *sl = netdev_priv(dev);
+
+	spin_lock_bh(&sl->lock);
+	if (sl->tty) {
+		/* TTY discipline is running. */
+		clear_bit(TTY_DO_WRITE_WAKEUP, &sl->tty->flags);
+	}
+	netif_stop_queue(dev);
+	sl->rcount   = 0;
+	sl->xleft    = 0;
+	spin_unlock_bh(&sl->lock);
+
+	return 0;
+}
+
+/* Netdevice DOWN -> UP routine */
+static int slc_open(struct net_device *dev)
+{
+	struct slcan *sl = netdev_priv(dev);
+
+	if (sl->tty == NULL)
+		return -ENODEV;
+
+	sl->flags &= (1 << SLF_INUSE);
+	netif_start_queue(dev);
+	return 0;
+}
+
+/* Hook the destructor so we can free slcan devs at the right point in time */
+static void slc_free_netdev(struct net_device *dev)
+{
+	int i = dev->base_addr;
+	free_netdev(dev);
+	slcan_devs[i] = NULL;
+}
+
+static const struct net_device_ops slc_netdev_ops = {
+	.ndo_open               = slc_open,
+	.ndo_stop               = slc_close,
+	.ndo_start_xmit         = slc_xmit,
+};
+
+static void slc_setup(struct net_device *dev)
+{
+	dev->netdev_ops		= &slc_netdev_ops;
+	dev->destructor		= slc_free_netdev;
+
+	dev->hard_header_len	= 0;
+	dev->addr_len		= 0;
+	dev->tx_queue_len	= 10;
+
+	dev->mtu		= sizeof(struct can_frame);
+	dev->type		= ARPHRD_CAN;
+
+	/* New-style flags. */
+	dev->flags		= IFF_NOARP;
+	dev->features           = NETIF_F_NO_CSUM;
+}
+
+/******************************************
+  Routines looking at TTY side.
+ ******************************************/
+
+/*
+ * Handle the 'receiver data ready' interrupt.
+ * This function is called by the 'tty_io' module in the kernel when
+ * a block of SLCAN data has been received, which can now be decapsulated
+ * and sent on to some IP layer for further processing. This will not
+ * be re-entered while running but other ldisc functions may be called
+ * in parallel
+ */
+
+static void slcan_receive_buf(struct tty_struct *tty,
+			      const unsigned char *cp, char *fp, int count)
+{
+	struct slcan *sl = (struct slcan *) tty->disc_data;
+
+	if (!sl || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev))
+		return;
+
+	/* Read the characters out of the buffer */
+	while (count--) {
+		if (fp && *fp++) {
+			if (!test_and_set_bit(SLF_ERROR, &sl->flags))
+				sl->dev->stats.rx_errors++;
+			cp++;
+			continue;
+		}
+		slcan_unesc(sl, *cp++);
+	}
+}
+
+/************************************
+ *  slcan_open helper routines.
+ ************************************/
+
+/* Collect hanged up channels */
+static void slc_sync(void)
+{
+	int i;
+	struct net_device *dev;
+	struct slcan	  *sl;
+
+	for (i = 0; i < maxdev; i++) {
+		dev = slcan_devs[i];
+		if (dev == NULL)
+			break;
+
+		sl = netdev_priv(dev);
+		if (sl->tty || sl->leased)
+			continue;
+		if (dev->flags & IFF_UP)
+			dev_close(dev);
+	}
+}
+
+/* Find a free SLCAN channel, and link in this `tty' line. */
+static struct slcan *slc_alloc(dev_t line)
+{
+	int i;
+	struct net_device *dev = NULL;
+	struct slcan       *sl;
+
+	if (slcan_devs == NULL)
+		return NULL;	/* Master array missing ! */
+
+	for (i = 0; i < maxdev; i++) {
+		dev = slcan_devs[i];
+		if (dev == NULL)
+			break;
+
+	}
+
+	/* Sorry, too many, all slots in use */
+	if (i >= maxdev)
+		return NULL;
+
+	if (dev) {
+		sl = netdev_priv(dev);
+		if (test_bit(SLF_INUSE, &sl->flags)) {
+			unregister_netdevice(dev);
+			dev = NULL;
+			slcan_devs[i] = NULL;
+		}
+	}
+
+	if (!dev) {
+		char name[IFNAMSIZ];
+		sprintf(name, "slcan%d", i);
+
+		dev = alloc_netdev(sizeof(*sl), name, slc_setup);
+		if (!dev)
+			return NULL;
+		dev->base_addr  = i;
+	}
+
+	sl = netdev_priv(dev);
+
+	/* Initialize channel control data */
+	sl->magic = SLCAN_MAGIC;
+	sl->dev	= dev;
+	spin_lock_init(&sl->lock);
+	slcan_devs[i] = dev;
+
+	return sl;
+}
+
+/*
+ * Open the high-level part of the SLCAN channel.
+ * This function is called by the TTY module when the
+ * SLCAN line discipline is called for.  Because we are
+ * sure the tty line exists, we only have to link it to
+ * a free SLCAN channel...
+ *
+ * Called in process context serialized from other ldisc calls.
+ */
+
+static int slcan_open(struct tty_struct *tty)
+{
+	struct slcan *sl;
+	int err;
+
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
+	if (tty->ops->write == NULL)
+		return -EOPNOTSUPP;
+
+	/* RTnetlink lock is misused here to serialize concurrent
+	   opens of slcan channels. There are better ways, but it is
+	   the simplest one.
+	 */
+	rtnl_lock();
+
+	/* Collect hanged up channels. */
+	slc_sync();
+
+	sl = tty->disc_data;
+
+	err = -EEXIST;
+	/* First make sure we're not already connected. */
+	if (sl && sl->magic == SLCAN_MAGIC)
+		goto err_exit;
+
+	/* OK.  Find a free SLCAN channel to use. */
+	err = -ENFILE;
+	sl = slc_alloc(tty_devnum(tty));
+	if (sl == NULL)
+		goto err_exit;
+
+	sl->tty = tty;
+	tty->disc_data = sl;
+	sl->line = tty_devnum(tty);
+	sl->pid = current->pid;
+
+	if (!test_bit(SLF_INUSE, &sl->flags)) {
+		/* Perform the low-level SLCAN initialization. */
+		sl->rcount   = 0;
+		sl->xleft    = 0;
+
+		set_bit(SLF_INUSE, &sl->flags);
+
+		err = register_netdevice(sl->dev);
+		if (err)
+			goto err_free_chan;
+	}
+
+	/* Done.  We have linked the TTY line to a channel. */
+	rtnl_unlock();
+	tty->receive_room = 65536;	/* We don't flow control */
+	return sl->dev->base_addr;
+
+err_free_chan:
+	sl->tty = NULL;
+	tty->disc_data = NULL;
+	clear_bit(SLF_INUSE, &sl->flags);
+
+err_exit:
+	rtnl_unlock();
+
+	/* Count references from TTY module */
+	return err;
+}
+
+/*
+ * Close down a SLCAN channel.
+ * This means flushing out any pending queues, and then returning. This
+ * call is serialized against other ldisc functions.
+ *
+ * We also use this method for a hangup event.
+ */
+
+static void slcan_close(struct tty_struct *tty)
+{
+	struct slcan *sl = (struct slcan *) tty->disc_data;
+
+	/* First make sure we're connected. */
+	if (!sl || sl->magic != SLCAN_MAGIC || sl->tty != tty)
+		return;
+
+	tty->disc_data = NULL;
+	sl->tty = NULL;
+	if (!sl->leased)
+		sl->line = 0;
+
+	/* Flush network side */
+	unregister_netdev(sl->dev);
+	/* This will complete via sl_free_netdev */
+}
+
+static int slcan_hangup(struct tty_struct *tty)
+{
+	slcan_close(tty);
+	return 0;
+}
+
+/* Perform I/O control on an active SLCAN channel. */
+static int slcan_ioctl(struct tty_struct *tty, struct file *file,
+		       unsigned int cmd, unsigned long arg)
+{
+	struct slcan *sl = (struct slcan *) tty->disc_data;
+	unsigned int tmp;
+
+	/* First make sure we're connected. */
+	if (!sl || sl->magic != SLCAN_MAGIC)
+		return -EINVAL;
+
+	switch (cmd) {
+	case SIOCGIFNAME:
+		tmp = strlen(sl->dev->name) + 1;
+		if (copy_to_user((void __user *)arg, sl->dev->name, tmp))
+			return -EFAULT;
+		return 0;
+
+	case SIOCSIFHWADDR:
+		return -EINVAL;
+
+	default:
+		return tty_mode_ioctl(tty, file, cmd, arg);
+	}
+}
+
+static struct tty_ldisc_ops slc_ldisc = {
+	.owner		= THIS_MODULE,
+	.magic		= TTY_LDISC_MAGIC,
+	.name		= "slcan",
+	.open		= slcan_open,
+	.close		= slcan_close,
+	.hangup		= slcan_hangup,
+	.ioctl		= slcan_ioctl,
+	.receive_buf	= slcan_receive_buf,
+	.write_wakeup	= slcan_write_wakeup,
+};
+
+static int __init slcan_init(void)
+{
+	int status;
+
+	if (maxdev < 4)
+		maxdev = 4; /* Sanity */
+
+	printk(banner);
+	printk(KERN_INFO "slcan: %d dynamic interface channels.\n", maxdev);
+
+	slcan_devs = kzalloc(sizeof(struct net_device *)*maxdev, GFP_KERNEL);
+	if (!slcan_devs) {
+		printk(KERN_ERR "slcan: can't allocate slcan device array!\n");
+		return -ENOMEM;
+	}
+
+	/* Fill in our line protocol discipline, and register it */
+	status = tty_register_ldisc(N_SLCAN, &slc_ldisc);
+	if (status)  {
+		printk(KERN_ERR "slcan: can't register line discipline\n");
+		kfree(slcan_devs);
+	}
+	return status;
+}
+
+static void __exit slcan_exit(void)
+{
+	int i;
+	struct net_device *dev;
+	struct slcan *sl;
+	unsigned long timeout = jiffies + HZ;
+	int busy = 0;
+
+	if (slcan_devs == NULL)
+		return;
+
+	/* First of all: check for active disciplines and hangup them.
+	 */
+	do {
+		if (busy)
+			msleep_interruptible(100);
+
+		busy = 0;
+		for (i = 0; i < maxdev; i++) {
+			dev = slcan_devs[i];
+			if (!dev)
+				continue;
+			sl = netdev_priv(dev);
+			spin_lock_bh(&sl->lock);
+			if (sl->tty) {
+				busy++;
+				tty_hangup(sl->tty);
+			}
+			spin_unlock_bh(&sl->lock);
+		}
+	} while (busy && time_before(jiffies, timeout));
+
+	/* FIXME: hangup is async so we should wait when doing this second
+	   phase */
+
+	for (i = 0; i < maxdev; i++) {
+		dev = slcan_devs[i];
+		if (!dev)
+			continue;
+		slcan_devs[i] = NULL;
+
+		sl = netdev_priv(dev);
+		if (sl->tty) {
+			printk(KERN_ERR "%s: tty discipline still running\n",
+			       dev->name);
+			/* Intentionally leak the control block. */
+			dev->destructor = NULL;
+		}
+
+		unregister_netdev(dev);
+	}
+
+	kfree(slcan_devs);
+	slcan_devs = NULL;
+
+	i = tty_unregister_ldisc(N_SLCAN);
+	if (i)
+		printk(KERN_ERR "slcan: can't unregister ldisc (err %d)\n", i);
+}
+
+module_init(slcan_init);
+module_exit(slcan_exit);

^ permalink raw reply

* Re: [net-next-2.6] XFRM: remove unused member in xfrm_encap_tmpl.
From: David Shwatrz @ 2010-11-29 20:09 UTC (permalink / raw)
  To: Timo Teräs; +Cc: David S. Miller, netdev
In-Reply-To: <4CF3FE85.6040406@iki.fi>

Timo,
Thanks for your answer.

> Alternatively the other RFCs say that the checksum can be just
> recalculated. That's what the linux stack does: it throws the old
> checksum away (ignored on local receive and recalculated on send
> forward paths).

Sorry, something here seems to me still wrong; maybe I miss something.
We are talking about transport mode. Let's take TCP for example.
the packet is received by another peer. It is on port 4500 because of
NAT-T. Since it is ESP encrypted , it is it is decrypted. It reaches
the TCP layer. In TCP (as opposed to UDP), the checksum is mandatory.
But the checksum in that TCP header of the received
packet will not be correct, since the IP header of that packet is
**NOT** the original address ; the IP address was changed by the NAT.
The NAT  cannot change the TCP checksum since it is encrypted. So
wouldn't we have a checksum error in the case of TCP ?  It seems to me
that the purpose of NAT-OA was to pass the
original address, so that there will be no error in such a case.
But again, maybe I miss something, since I did not heard that
transport mode has any problems with NAT-T. Or maybe this was not
tested?


Rgs,
DS



2010/11/29 Timo Teräs <timo.teras@iki.fi>:
> On 11/29/2010 09:15 PM, David Shwatrz wrote:
>> But isn't something wrong here ?
>>
>> According to RFC 3948:
>> ...
>> 3.1.2.  Transport Mode Decapsulation NAT Procedure
>>
>> When a transport mode has been used to transmit packets, contained
>>    TCP or UDP headers will have incorrect checksums due to the change of
>>    parts of the IP header during transit.  This procedure defines how to
>>    fix these checksums
>> ...
>> incrementally recompute the
>>        TCP/UDP checksum:
>>
>>        *  Subtract the IP source address in the received packet from the
>>           checksum.
>>        *  Add the real IP source address received via IKE to the
>>           checksum (obtained from the NAT-OA)
>> ...
>>
>> So where do we pass the NAT-OA, received from IKE messages,  to this
>> checksum recalculation process, which should be done in the kernel
>> (layer 4 TCP/UDP I suppose) ?
>>
>> Should'nt this process be done in the kernel ?
>>
>> Isn't there something missing here ?
>
> That's what the field was intended for. Also it's passed around by e.g.
> 'ip xfrm' command. The header change would break compilation of iproute2
> too.
>
> Alternatively the other RFCs say that the checksum can be just
> recalculated. That's what the linux stack does: it throws the old
> checksum away (ignored on local receive and recalculated on send /
> forward paths). The ESP/AH packets are usually also configured to
> contain a cryptographic hash, so the packet modifications are detected
> even before trying to check the TCP/UDP checksum (making the check
> redundant).
>
> There's also probably some legacy reasons why the nat-oa field is useful
> in kernel; and why the tcp/udp is not updated according the above
> mentioned scheme. I guess doing that might speed up forwarding from one
> tunnel to another where hardware checksum acceleration is not available;
> maybe no one just had the time to implement it.
>
> - Timo
>

^ permalink raw reply

* Re: [PATCH 00/11] forcedeth: Convert to use netdev_<level> and neatening
From: David Miller @ 2010-11-29 19:51 UTC (permalink / raw)
  To: joe; +Cc: netdev, bhutchings, szymon, mirqus, linux-kernel
In-Reply-To: <cover.1291051316.git.joe@perches.com>

From: Joe Perches <joe@perches.com>
Date: Mon, 29 Nov 2010 09:41:51 -0800

> Some mild restructuring and some generally neatening.
> 
> The conversions of dprintk to netdev_dbg in patches 2 and 4 are
> deleted in patch 10 as these seem to have been used only
> during initial development and are not normally compiled-in.
> 
> Patch 10 may be ignored if desired.
> 
> Object size is reduced ~2Kb overall.
> 
> $ size drivers/net/forcedeth.o.*
>    text	   data	    bss	    dec	    hex	filename
>   71739	    336	  17176	  89251	  15ca3	drivers/net/forcedeth.o.new
>   73416	    240	  17696	  91352	  164d8	drivers/net/forcedeth.o.old

These look fine, applied, thanks.

^ permalink raw reply

* [PATCH 0/3] Tunneling minor patches
From: Stephen Hemminger @ 2010-11-29 19:47 UTC (permalink / raw)
  To: David Miller; +Cc: netdev



^ permalink raw reply

* [PATCH 1/3] gre: minor cleanups
From: Stephen Hemminger @ 2010-11-29 19:47 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20101129194746.724222156@vyatta.com>

[-- Attachment #1: gre-fix-trivial.patch --]
[-- Type: text/plain, Size: 602 bytes --]

Use strcpy() rather the sprintf() for the case where name is getting
generated.  Fix indentation.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

--- a/net/ipv4/ip_gre.c	2010-11-28 11:28:48.684091117 -0800
+++ b/net/ipv4/ip_gre.c	2010-11-28 11:29:21.839822531 -0800
@@ -405,11 +405,11 @@ static struct ip_tunnel *ipgre_tunnel_lo
 	if (parms->name[0])
 		strlcpy(name, parms->name, IFNAMSIZ);
 	else
-		sprintf(name, "gre%%d");
+		strcpy(name, "gre%d");
 
 	dev = alloc_netdev(sizeof(*t), name, ipgre_tunnel_setup);
 	if (!dev)
-	  return NULL;
+		return NULL;
 
 	dev_net_set(dev, net);
 



^ permalink raw reply

* [PATCH 2/3] gre: add module alias for gre0 tunnel device
From: Stephen Hemminger @ 2010-11-29 19:47 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20101129194746.724222156@vyatta.com>

[-- Attachment #1: gre-alias.patch --]
[-- Type: text/plain, Size: 549 bytes --]

If gre is built as a module the 'ip tunnel add' command would fail because
the ip_gre module was not being autoloaded.  Adding an alias for
the gre0 device name cause dev_load() to autoload it when needed.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>


--- a/net/ipv4/ip_gre.c	2010-11-29 11:35:36.388589982 -0800
+++ b/net/ipv4/ip_gre.c	2010-11-29 11:35:46.675624021 -0800
@@ -1764,3 +1764,4 @@ module_exit(ipgre_fini);
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_RTNL_LINK("gre");
 MODULE_ALIAS_RTNL_LINK("gretap");
+MODULE_ALIAS("gre0");



^ permalink raw reply

* [PATCH 3/3] ipip: add module alias for tunl0 tunnel device
From: Stephen Hemminger @ 2010-11-29 19:47 UTC (permalink / raw)
  To: David Miller; +Cc: netdev
In-Reply-To: <20101129194746.724222156@vyatta.com>

[-- Attachment #1: ipip-alias.patch --]
[-- Type: text/plain, Size: 536 bytes --]

If ipip is built as a module the 'ip tunnel add' command would fail because
the ipip module was not being autoloaded.  Adding an alias for
the tunl0 device name cause dev_load() to autoload it when needed.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

--- a/net/ipv4/ipip.c	2010-11-29 11:40:25.026277890 -0800
+++ b/net/ipv4/ipip.c	2010-11-29 11:41:05.790681069 -0800
@@ -913,3 +913,4 @@ static void __exit ipip_fini(void)
 module_init(ipip_init);
 module_exit(ipip_fini);
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("tunl0");



^ permalink raw reply

* Re: inet_hash_connect: source port allocation
From: Stephen Hemminger @ 2010-11-29 19:38 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: John Haxby, NetDev
In-Reply-To: <1291057655.3435.1363.camel@edumazet-laptop>

On Mon, 29 Nov 2010 20:07:35 +0100
Eric Dumazet <eric.dumazet@gmail.com> wrote:

> Le lundi 29 novembre 2010 à 19:46 +0100, Eric Dumazet a écrit :
> > Le lundi 29 novembre 2010 à 18:29 +0000, John Haxby a écrit :
> > 
> > > Sorry,  I think I phrased my question badly.
> > > 
> > > inet_csk_get_port() starts its search for a free port with
> > > 
> > >      smallest_rover = rover = net_random() % remaining + low;
> > > 
> > > whereas __inet_hash_connect() basically misses out that call to 
> > > net_random() so you get a predictable port number.
> > > 
> > > Is there any good reason why that is the case?
> > > 
> > 
> > It seems random select was done at bind() time only in commit
> > 6df716340da3a6f ([TCP/DCCP]: Randomize port selection)
> > 
> > It probably should be done in autobind too.
> > 
> > 
> 
> I'll test following patch :
> 
> diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
> index 1b344f3..65c3702 100644
> --- a/net/ipv4/inet_hashtables.c
> +++ b/net/ipv4/inet_hashtables.c
> @@ -466,20 +466,18 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
>  	int twrefcnt = 1;
>  
>  	if (!snum) {
> -		int i, remaining, low, high, port;
> -		static u32 hint;
> -		u32 offset = hint + port_offset;
> +		int remaining, low, high, port;
>  		struct hlist_node *node;
>  		struct inet_timewait_sock *tw = NULL;
>  
>  		inet_get_local_port_range(&low, &high);
>  		remaining = (high - low) + 1;
> +		port = net_random() % remaining + low;
>  
>  		local_bh_disable();
> -		for (i = 1; i <= remaining; i++) {
> -			port = low + (i + offset) % remaining;
> +		do {
>  			if (inet_is_reserved_local_port(port))
> -				continue;
> +				goto next_nolock;
>  			head = &hinfo->bhash[inet_bhashfn(net, port,
>  					hinfo->bhash_size)];
>  			spin_lock(&head->lock);
> @@ -510,16 +508,17 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
>  			tb->fastreuse = -1;
>  			goto ok;
>  
> -		next_port:
> +next_port:
>  			spin_unlock(&head->lock);
> -		}
> +next_nolock:
> +			if (++port > high)
> +				port = low;
> +		} while (--remaining > 0);
>  		local_bh_enable();
>  
>  		return -EADDRNOTAVAIL;
>  
>  ok:
> -		hint += i;
> -
>  		/* Head lock still held and bh's disabled */
>  		inet_bind_hash(sk, tb, port);
>  		if (sk_unhashed(sk)) {
> 

The original algorithm works better than uses if the port space is small
and being reused rapidly. Because the hint in the old algorithm is sequential ports
get used up sequentially.

You should look a the port randomization RFC. The earlier versions of the
RFC were better before the BSD guys started putting in their non-scalable
algorithms :-)


-- 

^ permalink raw reply

* Re: [net-next-2.6] XFRM: remove unused member in xfrm_encap_tmpl.
From: Timo Teräs @ 2010-11-29 19:27 UTC (permalink / raw)
  To: David Shwatrz; +Cc: David S. Miller, netdev
In-Reply-To: <AANLkTinQ1qbp9SyWgw7TdvH=5x_1AA6zqLkaa7c4PBGQ@mail.gmail.com>

On 11/29/2010 09:15 PM, David Shwatrz wrote:
> But isn't something wrong here ?
> 
> According to RFC 3948:
> ...
> 3.1.2.  Transport Mode Decapsulation NAT Procedure
> 
> When a transport mode has been used to transmit packets, contained
>    TCP or UDP headers will have incorrect checksums due to the change of
>    parts of the IP header during transit.  This procedure defines how to
>    fix these checksums
> ...
> incrementally recompute the
>        TCP/UDP checksum:
> 
>        *  Subtract the IP source address in the received packet from the
>           checksum.
>        *  Add the real IP source address received via IKE to the
>           checksum (obtained from the NAT-OA)
> ...
> 
> So where do we pass the NAT-OA, received from IKE messages,  to this
> checksum recalculation process, which should be done in the kernel
> (layer 4 TCP/UDP I suppose) ?
> 
> Should'nt this process be done in the kernel ?
> 
> Isn't there something missing here ?

That's what the field was intended for. Also it's passed around by e.g.
'ip xfrm' command. The header change would break compilation of iproute2
too.

Alternatively the other RFCs say that the checksum can be just
recalculated. That's what the linux stack does: it throws the old
checksum away (ignored on local receive and recalculated on send /
forward paths). The ESP/AH packets are usually also configured to
contain a cryptographic hash, so the packet modifications are detected
even before trying to check the TCP/UDP checksum (making the check
redundant).

There's also probably some legacy reasons why the nat-oa field is useful
in kernel; and why the tcp/udp is not updated according the above
mentioned scheme. I guess doing that might speed up forwarding from one
tunnel to another where hardware checksum acceleration is not available;
maybe no one just had the time to implement it.

- Timo

^ permalink raw reply

* Re: pull request: wireless-next-2.6 2010-11-29
From: David Miller @ 2010-11-29 19:22 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, netdev
In-Reply-To: <20101129191352.GB8199@tuxdriver.com>

From: "John W. Linville" <linville@tuxdriver.com>
Date: Mon, 29 Nov 2010 14:13:52 -0500

> Between celebrating my birthday and the Thanksgiving holiday, this pull
> request is a bit bigger than usual...sorry!

Hey another November boy :-)

> For the most part, this is the usual stuff -- driver updates and the
> like.  mwl8k, wl1271, ath9k, carl9170, rt2x00, b43, and iwlwifi all get
> significant attention, along with a smattering of others.  mac80211 gets
> a variety of updates as well.
> 
> This includes the movement of an EWMA library to lib for general use.
> Also included is some file renaming for drivers/net/wireless/wl12xx.
> 
> Please let me know if there are problems!

Pulled, thanks!

^ permalink raw reply

* Re: inet_hash_connect: source port allocation
From: Eric Dumazet @ 2010-11-29 19:21 UTC (permalink / raw)
  To: John Haxby; +Cc: NetDev, Stephen Hemminger
In-Reply-To: <1291057655.3435.1363.camel@edumazet-laptop>

Le lundi 29 novembre 2010 à 20:07 +0100, Eric Dumazet a écrit :
> Le lundi 29 novembre 2010 à 19:46 +0100, Eric Dumazet a écrit :
> > Le lundi 29 novembre 2010 à 18:29 +0000, John Haxby a écrit :
> > 
> > > Sorry,  I think I phrased my question badly.
> > > 
> > > inet_csk_get_port() starts its search for a free port with
> > > 
> > >      smallest_rover = rover = net_random() % remaining + low;
> > > 
> > > whereas __inet_hash_connect() basically misses out that call to 
> > > net_random() so you get a predictable port number.
> > > 
> > > Is there any good reason why that is the case?
> > > 
> > 
> > It seems random select was done at bind() time only in commit
> > 6df716340da3a6f ([TCP/DCCP]: Randomize port selection)
> > 
> > It probably should be done in autobind too.
> > 
> > 
> 
> I'll test following patch :

Oh well, forget this, there is something about inet_sk_port_offset()
using secure_ipv4_port_ephemeral()

We want to avoid reusing same port too fast.

http://www.tcpipguide.com/free/t_TCPIPClientEphemeralPortsandClientServerApplicatio-2.htm

Port is predictable only for same destination, and if no other
connections are attempted by other threads.




^ permalink raw reply

* 2.6.35 -> 2.6.36 panic when vlan and promisc with tg3
From: Michael Leun @ 2010-11-29 19:17 UTC (permalink / raw)
  To: linux-kernel, netdev

Hi,

only kernel message I was able to capture on serial were:

UG: unable to handle kernel paging request at 01cc921c
IP: [<c034bfce>] vlan_hwaccel_do_receive+0x59/0xd0
*pdpt = 0000000036a2a001 *pde = 0000000000000000
Oops: 0002 [#1] SMP
last sysfs

Then machine dead.

In 2.6.35.x this did not happen (but vlans broken - cannot see vlan
tags with tcpdump),

To reproduce:

ip link set eth0 up
vconfig add eth0 2
ip link set eth0 promisc on

Machines with these ethernet cards I've seen to be affected:

Ethernet controller: Broadcom Corporation NetXtreme BCM5714 Gigabit
Ethernet (rev a3)

Ethernet controller: Broadcom Corporation NetXtreme BCM5752M Gigabit
Ethernet PCI Express (rev 02)

Machine with this card is NOT affected (no vlan hw accel?):

Ethernet controller: Broadcom Corporation NetLink BCM5906M Fast
Ethernet PCI Express (rev 02)


-- 
MfG,

Michael Leun

^ permalink raw reply

* Re: [net-next-2.6] XFRM: remove unused member in xfrm_encap_tmpl.
From: David Shwatrz @ 2010-11-29 19:15 UTC (permalink / raw)
  To: Timo Teräs; +Cc: David S. Miller, netdev
In-Reply-To: <4CF3EBF2.5060308@iki.fi>

Hi,
Thanks, Timo.

But isn't something wrong here ?

According to RFC 3948:
...
3.1.2.  Transport Mode Decapsulation NAT Procedure

When a transport mode has been used to transmit packets, contained
   TCP or UDP headers will have incorrect checksums due to the change of
   parts of the IP header during transit.  This procedure defines how to
   fix these checksums
...
incrementally recompute the
       TCP/UDP checksum:

       *  Subtract the IP source address in the received packet from the
          checksum.
       *  Add the real IP source address received via IKE to the
          checksum (obtained from the NAT-OA)
...

So where do we pass the NAT-OA, received from IKE messages,  to this
checksum recalculation process, which should be done in the kernel
(layer 4 TCP/UDP I suppose) ?

Should'nt this process be done in the kernel ?

Isn't there something missing here ?

Rgs,
DS

2010/11/29 Timo Teräs <timo.teras@iki.fi>:
> On 01/-10/-28163 09:59 PM, David Shwatrz wrote:
>> Hi,
>>  The patch removes unused member in xfrm_encap_tmpl.
>>
>> Regards,
>> David Shwartz
>>
>>
>> Signed-off-by: David Shwartz <dshwatrz@gmail.com>
>>
>>
>> diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
>> index b971e38..7312707 100644
>> --- a/include/linux/xfrm.h
>> +++ b/include/linux/xfrm.h
>> @@ -235,7 +235,6 @@ struct xfrm_encap_tmpl {
>>       __u16           encap_type;
>>       __be16          encap_sport;
>>       __be16          encap_dport;
>> -     xfrm_address_t  encap_oa;
>>  };
>>
>>  /* AEVENT flags  */
>
> struct xfrm_encap_tmpl is exposed to userland via netlink. This would
> break ABI.
>

^ permalink raw reply

* [GIT] Networking
From: David Miller @ 2010-11-29 19:15 UTC (permalink / raw)
  To: torvalds; +Cc: akpm, netdev, linux-kernel


1) Two fixes for some exploitable cases in AF_UNIX file descriptor
   passing.  Both from Eric Dumazet.

2) DECnet uninitialized data to userspace fix from Dan Rosenberg.

3) Unit allocation passes incorrect error back to userspace, fix
   from Cyrill Gorcunov.

4) Inet port binding optimization maintains it's counters
   erroneously, fix from Nagendra Tomar.

5) Three econet CVE fixes from Phil Blundell.

6) ucc_geth halts in half-duplex due to over-aggressive fifo
   size setting, fix from Yang Li.

7) mcast/ucast Address handling fix in cxgb4vf from Casey Leedom.

8) tcp_adv_win_scale can cause undefined behavior if the
   abos() of it's value is >31 since it is used in shifts.
   Fix from Alexey Dobriyan

9) Regression in au1000_eth MAC enable register accesses, fix
   from Wolfgang Grandegger.

10) Struct initializer fix in pch_gbe from Toshiharu Okada.

11) Stack corruption bug in isdn icn driver from Steven Rostedt.

12) DCCP ACK tracking fix from Gerrit Renker.

13) HSO driver does not honor disable_net setting, from Filip Aben.

14) ath9k wireless timeout fix from Felix Fietkau.

Please pull, thanks a lot!

The following changes since commit 72083646528d4887b920deb71b37e09bc7d227bb:

  Un-inline get_pipe_info() helper function (2010-11-28 16:27:19 -0800)

are available in the git repository at:
  master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6.git master

Alexey Dobriyan (1):
      tcp: restrict net.ipv4.tcp_adv_win_scale (#20312)

Breno Leitao (1):
      ehea: Add some info messages and fix an issue

Casey Leedom (1):
      cxgb4vf: fix setting unicast/multicast addresses ...

Christian Lamparter (1):
      carl9170: fix virtual interface setup crash

Cyrill Gorcunov (1):
      net, ppp: Report correct error code if unit allocation failed

Dan Rosenberg (1):
      DECnet: don't leak uninitialized stack byte

Daniel Klaffenbach (1):
      ssb: b43-pci-bridge: Add new vendor for BCM4318

David S. Miller (3):
      Merge branch 'master' of git://git.kernel.org/.../linville/wireless-2.6
      tcp: Make TCP_MAXSEG minimum more correct.
      Merge branch 'vhost-net' of git://git.kernel.org/.../mst/vhost

Eric Dumazet (2):
      af_unix: limit unix_tot_inflight
      af_unix: limit recursion level

Felix Fietkau (1):
      ath9k: fix timeout on stopping rx dma

Filip Aben (1):
      hso: fix disable_net

Gerrit Renker (1):
      dccp: fix error in updating the GAR

Guennadi Liakhovetski (1):
      wireless: b43: fix error path in SDIO

Jiri Slaby (1):
      NET: wan/x25_asy, move lapb_unregister to x25_asy_close_tty

Michael S. Tsirkin (1):
      vhost/net: fix rcu check usage

Nagendra Tomar (1):
      inet: Fix __inet_inherit_port() to correctly increment bsockets and num_owners

Pavel Emelyanov (1):
      netns: Don't leak others' openreq-s in proc

Phil Blundell (3):
      econet: disallow NULL remote addr for sendmsg(), fixes CVE-2010-3849
      econet: fix CVE-2010-3850
      econet: fix CVE-2010-3848

Steven Rostedt (1):
      isdn: icn: Fix stack corruption bug.

Toshiharu Okada (2):
      pch_gbe dreiver: chang author
      pch_gbe driver: The wrong of initializer entry

Tracey Dent (1):
      Net: ceph: Makefile: Remove unnessary code

Wolfgang Grandegger (1):
      au1000_eth: fix invalid address accessing the MAC enable register

Yang Li (1):
      ucc_geth: fix ucc halt problem in half duplex mode

 Documentation/networking/ip-sysctl.txt   |    1 +
 drivers/isdn/icn/icn.c                   |    7 +-
 drivers/net/Kconfig                      |    6 +-
 drivers/net/au1000_eth.c                 |   10 ++--
 drivers/net/cxgb4vf/cxgb4vf_main.c       |   73 ++++++++++++++---------
 drivers/net/cxgb4vf/t4vf_hw.c            |   96 +++++++++++++++++++-----------
 drivers/net/ehea/ehea_main.c             |   18 ++++-
 drivers/net/pch_gbe/pch_gbe_main.c       |    6 +-
 drivers/net/pch_gbe/pch_gbe_param.c      |    8 +-
 drivers/net/ppp_generic.c                |   43 +++++++-------
 drivers/net/ucc_geth.h                   |    3 +-
 drivers/net/usb/hso.c                    |   10 ++-
 drivers/net/wan/x25_asy.c                |   11 ++--
 drivers/net/wireless/ath/ath9k/recv.c    |    2 +-
 drivers/net/wireless/ath/carl9170/main.c |    2 +-
 drivers/net/wireless/b43/sdio.c          |    1 +
 drivers/ssb/b43_pci_bridge.c             |    1 +
 drivers/vhost/net.c                      |    5 +-
 include/linux/pci_ids.h                  |    1 +
 include/net/af_unix.h                    |    2 +
 net/ceph/Makefile                        |   22 -------
 net/dccp/input.c                         |    3 +-
 net/decnet/af_decnet.c                   |    2 +
 net/econet/af_econet.c                   |   91 +++++++++++++---------------
 net/ipv4/inet_hashtables.c               |    3 +-
 net/ipv4/sysctl_net_ipv4.c               |    6 ++-
 net/ipv4/tcp.c                           |    2 +-
 net/ipv4/tcp_ipv4.c                      |    4 +-
 net/unix/af_unix.c                       |   37 ++++++++++--
 net/unix/garbage.c                       |    9 +++-
 30 files changed, 281 insertions(+), 204 deletions(-)

^ permalink raw reply

* pull request: wireless-next-2.6 2010-11-29
From: John W. Linville @ 2010-11-29 19:13 UTC (permalink / raw)
  To: davem-fT/PcQaiUtIeIZ0/mPfg9Q
  Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA

Dave,

Between celebrating my birthday and the Thanksgiving holiday, this pull
request is a bit bigger than usual...sorry!

For the most part, this is the usual stuff -- driver updates and the
like.  mwl8k, wl1271, ath9k, carl9170, rt2x00, b43, and iwlwifi all get
significant attention, along with a smattering of others.  mac80211 gets
a variety of updates as well.

This includes the movement of an EWMA library to lib for general use.
Also included is some file renaming for drivers/net/wireless/wl12xx.

Please let me know if there are problems!

Thanks,

John

---

The following changes since commit e9248fbd6b6f7ef1917bfffe998654e40dfb4cfd:

  vmxnet3: fix compilation when RSS is disabled (2010-11-28 18:25:33 -0800)

are available in the git repository at:
  git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6.git for-davem

Arik Nemtsov (2):
      mac80211: support hardware TX fragmentation offload
      wl1271: add support for HW TX fragmentation

Ben Greear (1):
      ath5k: Cleanup opmode setting logic.

Brian Cavagnolo (6):
      mwl8k: revert unnecessary modification of tx descriptor
      mwl8k: factor out firmware loading and hw init code
      mwl8k: choose proper firmware image as directed by user
      mwl8k: add API version checking for AP firmware
      mwl8k: make initial firmware load asynchronous
      mwl8k: use const struct fw pointers throughout

Bruno Randolf (7):
      cfg80211: Add nl80211 antenna configuration
      mac80211: Add antenna configuration
      ath5k: Add support for antenna configuration
      lib: Add generic exponentially weighted moving average (EWMA) function
      ath5k: Use generic EWMA library
      nl80211/mac80211: Report signal average
      cfg80211: Add documentation for antenna ops

Christian Lamparter (2):
      carl9170: fix virtual interface setup crash
      carl9170: fix init-self regression

Daniel Drake (1):
      libertas: don't block usb8388 suspend if no wakeup conditions are set

Daniel Klaffenbach (1):
      ssb: b43-pci-bridge: Add new vendor for BCM4318

Deepak Saxena (1):
      libertas: EHS_REMOVE_WAKEUP is not always supported

Felix Fietkau (36):
      ath9k: remove the unnecessary private xretry tx flag
      ath9k: handle tx underrun in the driver instead of rate control
      ath9k: remove the tx info padding byte abuse
      ath9k: clean up tx buffer setup
      ath9k_hw: add a private op for configuring radar pulse detection
      cfg80211: add support for setting the ad-hoc multicast rate
      mac80211: add support for setting the ad-hoc multicast rate
      ath9k_hw: set default values for radar pulse detection
      ath9k: fix PA predistortion training frame setup
      ath9k: remove bfs_seqno from struct ath_buf_state
      ath9k: remove bfs_tidno from struct ath_buf_state
      ath9k: remove bfs_keytype from struct ath_buf_state
      ath9k: remove bfs_paprd_timestamp from struct ath_buf_state
      ath9k: remove bfs_keyix from struct ath_buf_state
      ath9k: remove bfs_al from struct ath_buf_state
      ath9k: remove bfs_nframes from struct ath_buf_state
      ath9k: remove bfs_frmlen from struct ath_buf_state
      ath9k: remove bf_tx_aborted from struct ath_buf
      ath9k: clean up code duplication around ath_tx_start
      ath9k: block new AMPDU sessions if SC_OP_TXAGGR is not set
      ath9k: more tx setup cleanups
      ath9k: store frame information used by aggregation inside the skb tx info
      ath9k_hw: add support for reading EEPROM data from the internal OTP ROM
      ath9k: add support for reading eeprom from platform data on PCI devices
      ath9k_hw: support reading calibration data from flash on AR9003
      ath9k: fix timeout on stopping rx dma
      ath9k: fix recursive locking in the tx flush path
      ath9k_hw: fix A-MPDU key search issues on AR9003
      ath9k_htc: fix eeprom access
      mac80211: restart beacon miss timer on system resume from suspend
      mac80211: calculate beacon loss time accurately
      mac80211: probe the AP when resuming
      cfg80211/mac80211: improve ad-hoc multicast rate handling
      mac80211: use nullfunc instead of probe request for connection monitoring
      mac80211: reduce the number of retries for nullfunc probing
      ath9k_hw: remove ath9k_hw_stoppcurecv

Gertjan van Wingerde (5):
      rt2x00: Add initial support for RT3370/RT3390 devices.
      rt2x00: Clean up Kconfig for RT2800 devices.
      rt2x00: Remove RT30XX Kconfig variables.
      rt2x00: Remove unneccessary internal Kconfig symbols.
      rt2x00: Use ioremap for SoC devices instead of KSEG1ADDR.

Gery Kahn (1):
      wl1271: cleanup unused code of calibration structures

Guennadi Liakhovetski (1):
      wireless: b43: fix error path in SDIO

Helmut Schaa (1):
      mac80211: Disable hw crypto for GTKs on AP VLAN interfaces

Huang Weiyi (1):
      libertas: remove duplicated #include

Ivo van Doorn (1):
      rt2x00: Increase REGISTER_BUSY_COUNT

Joe Perches (16):
      drivers/net/wireless/ath/debug.c: Use printf extension %pV
      drivers/net/wireless/b43/main.c: Use printf extension %pV
      drivers/net/wireless/b43legacy/main.c: Use printf extension %pV
      ar9170: Use const
      ath5k: Use static const
      ath9k: Use static const
      carl9170: Use static const
      atmel: Use static const
      b43: Use static const
      iwlwifi: Use static const
      libertas: Use static const
      ray_cs: Use static const
      rndis_wlan: Use static const
      rt2x00: Use static const
      zd1211rw: Use const
      net/wireless: Use pr_<level> and netdev_<level>

Johannes Berg (14):
      iwlagn: fix some naming regarding FIFOs
      iwlagn: remove unused variable swq_id
      iwlagn: remove a bogus AGG_OFF check
      iwlwifi: pass txq to wake/stop queue
      iwlwifi: always build swq_id as virtual queue ID
      iwlagn: fix PAN queues
      iwlagn: avoid crash if vif is not assigned
      iwlagn: reprogram AP STA after assoc
      iwlagn: fix PAN slot timing wrt. DTIM
      mac80211: defines for AC numbers
      mac80211: fix powersaving clients races
      iwlwifi: fix modular 3945 only build
      cfg80211: allow using CQM event to notify packet loss
      mac80211: implement packet loss notification

John W. Linville (6):
      iwmc3200wifi: clarify potentially undefined operation in iwm_scan_ssids
      rndis_wlan: avoid uninitialized var warning in rndis_wlan_craft_connected_bss
      Merge branch 'wireless-next-2.6' of git://git.kernel.org/.../iwlwifi/iwlwifi-2.6
      Revert "nl80211/mac80211: Report signal average"
      Merge branch 'master' of git://git.kernel.org/.../linville/wireless-2.6
      Merge branch 'master' of git://git.kernel.org/.../linville/wireless-next-2.6 into for-davem

Jussi Kivilinna (2):
      rndis_wlan: workaround device not returning bss for currently connected AP
      rndis_wlan: workaround poor scanning with BCM4320a

Juuso Oikarinen (4):
      mac80211: Add function to get probe request template for current AP
      wl1271: Prevent ad-hoc and active scanning on 11a DFS frequencies
      Revert "wl1271: Change supported channel order for a more optimal scan"
      wl12xx: Unset bssid filter, ssid and bssid from firmware on disassoc

Luis R. Rodriguez (6):
      cfg80211: put core regulatory request into queue
      cfg80211: move reg_work and reg_todo above
      cfg80211: move mutex locking to reg_process_pending_hints()
      cfg80211: Fix regulatory bug with multiple cards and delays
      ath9k: avoid aggregation for VO traffic
      mac80211: avoid aggregation for VO traffic

Mohammed Shafi Shajakhan (1):
      ath9k_htc: Use macro for caldata array size

Nishant Sarmukadam (1):
      mwl8k: rf_tx_power cmd not supported by AP firmware APIv1

RA-Jay Hung (3):
      rt2x00: Fix rt2800 USB TX Path DMA issue
      rt2x00: Fix header_length in rt2x00lib_txdone
      rt2x00: Modify rt2x00queue_remove_l2pad to make skb->data two-byte alignment

Rafał Miłecki (12):
      ssb: workarounds: be verbose about hacking SPROM revision, don't duplicate code
      ssb: return -ENOMEM on alloc fail (instead of CRC check's result)
      ssb: drop BCM4328 hack for SPROM revision
      b43: N-PHY: add 2056 radio channels tables
      b43: rfkill: use HI enabled bit for all devices
      b43: N-PHY: fix values for PHY regs in channel tables of 2055 radio
      b43: N-PHY: minor fixes to match specs
      b43: N-PHY: fix some typos, conditions, set gain_boost
      b43: N-PHY: init BPHY when needed
      b43: N-PHY: fix BPHY init
      b43: N-PHY: rev2: save and restore PHY regs on RSSI poll
      b43: N-PHY: little cleanups

Rajkumar Manoharan (4):
      ath: Add a driver_info bitmask field
      ath9k_htc: Add driver_info in usb device list
      ath9k_hw: Fix eeprom offset for AR9287 devices (PCI/USB)
      ath9k_htc: Identify devices using driver_info

Senthil Balasubramanian (6):
      ath9k_hw: Fix a reset failure on AR9382 (2x2).
      ath9k_hw: Add new member into the eeprom structure.
      ath9k_hw: Initialize 2GHz CTL properly.
      ath9k_hw: Fix paprd training frame failure.
      ath9k_hw: add eeprom templates for ar9003 family chipsets
      ath9k_hw: Fix low throughput issue with AR93xx

Shahar Levi (1):
      wl1271: Change wl12xx Files Names

Shanyu Zhao (2):
      iwlagn: update QoS before commit associated RXON
      iwlagn: check change before commit RXON cmd

Stanislaw Gruszka (3):
      iwl3945: remove unused len_org variable
      iwlagn: simplify iwlagn_tx_skb
      iwlwifi: kill elapsed_jiffies

Vasanthakumar Thiagarajan (5):
      ath9k_hw: Fix XPABIAS level configuration for AR9003
      ath9k_hw: Enable strong signal detection for AR9003
      ath9k_hw: Improve power control accuracy for AR9003
      ath9k_hw: Add helper function for interpolation
      ath9k: Fix bug in delimiter padding computation

Wey-Yi Guy (12):
      iwlagn: used frame count info in compressed ba packet
      iwlagn: set dynamic aggregation threshold for BT
      iwlagn: support dynamic aggregation for BT coex
      iwlagn: change default ACK/CTS MASK setting for WiFi/BT coex
      iwlwifi: change default led mode for different devices
      iwlagn: use SKU information in the EEPROM
      iwlwifi: set STATUS_READY before commit_rxon
      iwlagn: name change for BT config flag
      iwlwifi: add more power management flags
      iwlwifi: consider BT for power management
      iwlwifi: power management checking for shadow register
      iwlwifi: advance power management support

 drivers/net/wireless/ath/ar9170/cmd.c              |    2 +-
 drivers/net/wireless/ath/ath.h                     |    6 +
 drivers/net/wireless/ath/ath5k/Kconfig             |    1 +
 drivers/net/wireless/ath/ath5k/ani.c               |   38 +-
 drivers/net/wireless/ath/ath5k/ath5k.h             |   26 +-
 drivers/net/wireless/ath/ath5k/base.c              |   50 +-
 drivers/net/wireless/ath/ath5k/debug.c             |    2 +-
 drivers/net/wireless/ath/ath9k/ani.c               |    8 +-
 drivers/net/wireless/ath/ath9k/ar5008_phy.c        |   79 +-
 drivers/net/wireless/ath/ath9k/ar9002_phy.c        |   12 +-
 drivers/net/wireless/ath/ath9k/ar9003_calib.c      |   27 +-
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.c     | 2758 +++++++++-
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.h     |   27 +-
 drivers/net/wireless/ath/ath9k/ar9003_mac.c        |   28 +-
 drivers/net/wireless/ath/ath9k/ar9003_paprd.c      |    4 +-
 drivers/net/wireless/ath/ath9k/ar9003_phy.c        |   51 +-
 drivers/net/wireless/ath/ath9k/ath9k.h             |   42 +-
 drivers/net/wireless/ath/ath9k/beacon.c            |   19 +
 drivers/net/wireless/ath/ath9k/eeprom_4k.c         |   12 +-
 drivers/net/wireless/ath/ath9k/eeprom_9287.c       |   20 +-
 drivers/net/wireless/ath/ath9k/eeprom_def.c        |   17 +-
 drivers/net/wireless/ath/ath9k/hif_usb.c           |   61 +-
 drivers/net/wireless/ath/ath9k/htc.h               |    4 +-
 drivers/net/wireless/ath/ath9k/htc_drv_init.c      |   38 +-
 drivers/net/wireless/ath/ath9k/htc_hst.c           |    5 +-
 drivers/net/wireless/ath/ath9k/htc_hst.h           |    3 +-
 drivers/net/wireless/ath/ath9k/hw.c                |   20 +-
 drivers/net/wireless/ath/ath9k/hw.h                |   41 +
 drivers/net/wireless/ath/ath9k/init.c              |    3 +
 drivers/net/wireless/ath/ath9k/mac.c               |    8 -
 drivers/net/wireless/ath/ath9k/mac.h               |    1 -
 drivers/net/wireless/ath/ath9k/main.c              |   30 +-
 drivers/net/wireless/ath/ath9k/pci.c               |   42 +-
 drivers/net/wireless/ath/ath9k/rc.c                |   29 +-
 drivers/net/wireless/ath/ath9k/rc.h                |    6 -
 drivers/net/wireless/ath/ath9k/recv.c              |    2 +-
 drivers/net/wireless/ath/ath9k/reg.h               |   14 +-
 drivers/net/wireless/ath/ath9k/virtual.c           |    5 +-
 drivers/net/wireless/ath/ath9k/xmit.c              |  631 +--
 drivers/net/wireless/ath/carl9170/cmd.c            |    2 +-
 drivers/net/wireless/ath/carl9170/main.c           |    2 +-
 drivers/net/wireless/ath/carl9170/tx.c             |    2 +-
 drivers/net/wireless/ath/debug.c                   |    9 +-
 drivers/net/wireless/atmel.c                       |    6 +-
 drivers/net/wireless/b43/main.c                    |   48 +-
 drivers/net/wireless/b43/phy_common.c              |    8 +-
 drivers/net/wireless/b43/phy_n.c                   |   86 +-
 drivers/net/wireless/b43/radio_2055.c              |  248 +-
 drivers/net/wireless/b43/radio_2056.c              | 5968 ++++++++++++++++++++
 drivers/net/wireless/b43/rfkill.c                  |   19 +-
 drivers/net/wireless/b43/sdio.c                    |    1 +
 drivers/net/wireless/b43legacy/main.c              |   47 +-
 drivers/net/wireless/iwlwifi/Makefile              |    4 +
 drivers/net/wireless/iwlwifi/iwl-1000.c            |    8 +-
 drivers/net/wireless/iwlwifi/iwl-3945.c            |    6 +-
 drivers/net/wireless/iwlwifi/iwl-4965.c            |   13 +-
 drivers/net/wireless/iwlwifi/iwl-5000.c            |   14 +-
 drivers/net/wireless/iwlwifi/iwl-6000.c            |   46 +-
 drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c      |   21 +
 drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c        |    5 +-
 drivers/net/wireless/iwlwifi/iwl-agn-lib.c         |   27 +-
 drivers/net/wireless/iwlwifi/iwl-agn-rs.c          |   32 +-
 drivers/net/wireless/iwlwifi/iwl-agn-rxon.c        |  103 +-
 drivers/net/wireless/iwlwifi/iwl-agn-tx.c          |  110 +-
 drivers/net/wireless/iwlwifi/iwl-agn-ucode.c       |   65 +-
 drivers/net/wireless/iwlwifi/iwl-agn.c             |   11 +-
 drivers/net/wireless/iwlwifi/iwl-commands.h        |   25 +-
 drivers/net/wireless/iwlwifi/iwl-core.c            |    2 +-
 drivers/net/wireless/iwlwifi/iwl-core.h            |   11 +-
 drivers/net/wireless/iwlwifi/iwl-debugfs.c         |    9 +-
 drivers/net/wireless/iwlwifi/iwl-dev.h             |    3 +-
 drivers/net/wireless/iwlwifi/iwl-eeprom.h          |   12 +-
 drivers/net/wireless/iwlwifi/iwl-helpers.h         |   45 +-
 drivers/net/wireless/iwlwifi/iwl-led.c             |   10 +-
 drivers/net/wireless/iwlwifi/iwl-led.h             |    6 +-
 drivers/net/wireless/iwlwifi/iwl-power.c           |   95 +-
 drivers/net/wireless/iwlwifi/iwl-scan.c            |    3 +-
 drivers/net/wireless/iwlwifi/iwl-sta.c             |   51 +-
 drivers/net/wireless/iwlwifi/iwl-sta.h             |    1 +
 drivers/net/wireless/iwlwifi/iwl-tx.c              |   11 +-
 drivers/net/wireless/iwlwifi/iwl3945-base.c        |   11 +-
 drivers/net/wireless/iwmc3200wifi/commands.c       |    2 +-
 drivers/net/wireless/libertas/cfg.c                |    4 +-
 drivers/net/wireless/libertas/cmd.c                |    8 +
 drivers/net/wireless/libertas/dev.h                |    1 +
 drivers/net/wireless/libertas/if_usb.c             |   13 +-
 drivers/net/wireless/libertas/main.c               |    3 +-
 drivers/net/wireless/libertas/rx.c                 |    4 +-
 drivers/net/wireless/mwl8k.c                       |  677 ++-
 drivers/net/wireless/ray_cs.c                      |    4 +-
 drivers/net/wireless/rndis_wlan.c                  |  206 +-
 drivers/net/wireless/rt2x00/Kconfig                |   72 +-
 drivers/net/wireless/rt2x00/rt2800.h               |    1 +
 drivers/net/wireless/rt2x00/rt2800lib.c            |   11 +-
 drivers/net/wireless/rt2x00/rt2800pci.c            |   49 +-
 drivers/net/wireless/rt2x00/rt2800usb.c            |  212 +-
 drivers/net/wireless/rt2x00/rt2x00.h               |    2 +-
 drivers/net/wireless/rt2x00/rt2x00dev.c            |    8 +-
 drivers/net/wireless/rt2x00/rt2x00queue.c          |    6 +-
 drivers/net/wireless/rt2x00/rt2x00soc.c            |    6 +-
 drivers/net/wireless/wl12xx/Kconfig                |   52 +-
 drivers/net/wireless/wl12xx/Makefile               |   17 +-
 .../net/wireless/wl12xx/{wl1271_acx.c => acx.c}    |   12 +-
 .../net/wireless/wl12xx/{wl1271_acx.h => acx.h}    |   10 +-
 .../net/wireless/wl12xx/{wl1271_boot.c => boot.c}  |   10 +-
 .../net/wireless/wl12xx/{wl1271_boot.h => boot.h}  |    2 +-
 .../net/wireless/wl12xx/{wl1271_cmd.c => cmd.c}    |   12 +-
 .../net/wireless/wl12xx/{wl1271_cmd.h => cmd.h}    |   54 +-
 .../net/wireless/wl12xx/{wl1271_conf.h => conf.h}  |    4 +-
 .../wl12xx/{wl1271_debugfs.c => debugfs.c}         |   10 +-
 .../wl12xx/{wl1271_debugfs.h => debugfs.h}         |    6 +-
 .../wireless/wl12xx/{wl1271_event.c => event.c}    |   12 +-
 .../wireless/wl12xx/{wl1271_event.h => event.h}    |    4 +-
 .../net/wireless/wl12xx/{wl1271_ini.h => ini.h}    |    4 +-
 .../net/wireless/wl12xx/{wl1271_init.c => init.c}  |   10 +-
 .../net/wireless/wl12xx/{wl1271_init.h => init.h}  |    6 +-
 drivers/net/wireless/wl12xx/{wl1271_io.c => io.c}  |    4 +-
 drivers/net/wireless/wl12xx/{wl1271_io.h => io.h}  |    6 +-
 .../net/wireless/wl12xx/{wl1271_main.c => main.c}  |  183 +-
 drivers/net/wireless/wl12xx/{wl1271_ps.c => ps.c}  |    6 +-
 drivers/net/wireless/wl12xx/{wl1271_ps.h => ps.h}  |    8 +-
 .../net/wireless/wl12xx/{wl1271_reg.h => reg.h}    |    0
 drivers/net/wireless/wl12xx/{wl1271_rx.c => rx.c}  |   12 +-
 drivers/net/wireless/wl12xx/{wl1271_rx.h => rx.h}  |    4 +-
 .../net/wireless/wl12xx/{wl1271_scan.c => scan.c}  |    8 +-
 .../net/wireless/wl12xx/{wl1271_scan.h => scan.h}  |    6 +-
 .../net/wireless/wl12xx/{wl1271_sdio.c => sdio.c}  |    4 +-
 .../net/wireless/wl12xx/{wl1271_spi.c => spi.c}    |    6 +-
 .../wl12xx/{wl1271_testmode.c => testmode.c}       |    6 +-
 .../wl12xx/{wl1271_testmode.h => testmode.h}       |    4 +-
 drivers/net/wireless/wl12xx/{wl1271_tx.c => tx.c}  |   12 +-
 drivers/net/wireless/wl12xx/{wl1271_tx.h => tx.h}  |    4 +-
 drivers/net/wireless/wl12xx/{wl1271.h => wl12xx.h} |    8 +-
 drivers/net/wireless/zd1211rw/zd_chip.c            |    4 +-
 drivers/ssb/b43_pci_bridge.c                       |    1 +
 drivers/ssb/pci.c                                  |   52 +-
 include/linux/average.h                            |   32 +
 include/linux/nl80211.h                            |   32 +
 include/linux/pci_ids.h                            |    1 +
 include/net/cfg80211.h                             |   17 +
 include/net/mac80211.h                             |   50 +-
 include/net/regulatory.h                           |    7 +
 lib/Kconfig                                        |    3 +
 lib/Makefile                                       |    2 +
 lib/average.c                                      |   57 +
 net/mac80211/cfg.c                                 |   26 +
 net/mac80211/driver-ops.h                          |   37 +
 net/mac80211/driver-trace.h                        |   71 +
 net/mac80211/ibss.c                                |    2 +
 net/mac80211/ieee80211_i.h                         |   10 +
 net/mac80211/key.c                                 |    9 +-
 net/mac80211/mlme.c                                |  143 +-
 net/mac80211/rate.c                                |   18 +-
 net/mac80211/rc80211_minstrel_ht.c                 |    3 +
 net/mac80211/rx.c                                  |    2 -
 net/mac80211/sta_info.c                            |   17 +-
 net/mac80211/sta_info.h                            |    3 +
 net/mac80211/status.c                              |   26 +
 net/mac80211/tx.c                                  |   16 +-
 net/mac80211/util.c                                |   40 +-
 net/mac80211/wme.c                                 |   11 +-
 net/wireless/core.c                                |    8 +-
 net/wireless/lib80211.c                            |    8 +-
 net/wireless/lib80211_crypt_tkip.c                 |   16 +-
 net/wireless/mlme.c                                |   12 +
 net/wireless/nl80211.c                             |  111 +-
 net/wireless/nl80211.h                             |    4 +
 net/wireless/reg.c                                 |  127 +-
 net/wireless/util.c                                |   11 +-
 net/wireless/wext-core.c                           |   10 +-
 170 files changed, 12136 insertions(+), 2036 deletions(-)
 rename drivers/net/wireless/wl12xx/{wl1271_acx.c => acx.c} (99%)
 rename drivers/net/wireless/wl12xx/{wl1271_acx.h => acx.h} (99%)
 rename drivers/net/wireless/wl12xx/{wl1271_boot.c => boot.c} (99%)
 rename drivers/net/wireless/wl12xx/{wl1271_boot.h => boot.h} (98%)
 rename drivers/net/wireless/wl12xx/{wl1271_cmd.c => cmd.c} (99%)
 rename drivers/net/wireless/wl12xx/{wl1271_cmd.h => cmd.h} (91%)
 rename drivers/net/wireless/wl12xx/{wl1271_conf.h => conf.h} (99%)
 rename drivers/net/wireless/wl12xx/{wl1271_debugfs.c => debugfs.c} (99%)
 rename drivers/net/wireless/wl12xx/{wl1271_debugfs.h => debugfs.h} (93%)
 rename drivers/net/wireless/wl12xx/{wl1271_event.c => event.c} (98%)
 rename drivers/net/wireless/wl12xx/{wl1271_event.h => event.h} (98%)
 rename drivers/net/wireless/wl12xx/{wl1271_ini.h => ini.h} (98%)
 rename drivers/net/wireless/wl12xx/{wl1271_init.c => init.c} (98%)
 rename drivers/net/wireless/wl12xx/{wl1271_init.h => init.h} (93%)
 rename drivers/net/wireless/wl12xx/{wl1271_io.c => io.c} (99%)
 rename drivers/net/wireless/wl12xx/{wl1271_io.h => io.h} (98%)
 rename drivers/net/wireless/wl12xx/{wl1271_main.c => main.c} (97%)
 rename drivers/net/wireless/wl12xx/{wl1271_ps.c => ps.c} (98%)
 rename drivers/net/wireless/wl12xx/{wl1271_ps.h => ps.h} (92%)
 rename drivers/net/wireless/wl12xx/{wl1271_reg.h => reg.h} (100%)
 rename drivers/net/wireless/wl12xx/{wl1271_rx.c => rx.c} (97%)
 rename drivers/net/wireless/wl12xx/{wl1271_rx.h => rx.h} (98%)
 rename drivers/net/wireless/wl12xx/{wl1271_scan.c => scan.c} (98%)
 rename drivers/net/wireless/wl12xx/{wl1271_scan.h => scan.h} (97%)
 rename drivers/net/wireless/wl12xx/{wl1271_sdio.c => sdio.c} (99%)
 rename drivers/net/wireless/wl12xx/{wl1271_spi.c => spi.c} (99%)
 rename drivers/net/wireless/wl12xx/{wl1271_testmode.c => testmode.c} (98%)
 rename drivers/net/wireless/wl12xx/{wl1271_testmode.h => testmode.h} (93%)
 rename drivers/net/wireless/wl12xx/{wl1271_tx.c => tx.c} (98%)
 rename drivers/net/wireless/wl12xx/{wl1271_tx.h => tx.h} (99%)
 rename drivers/net/wireless/wl12xx/{wl1271.h => wl12xx.h} (99%)
 create mode 100644 include/linux/average.h
 create mode 100644 lib/average.c

Omnibus patch is available here:

	http://www.kernel.org/pub/linux/kernel/people/linville/wireless-next-2.6-2010-11-29.patch.bz2

-- 
John W. Linville		Someday the world will need a hero, and you
linville-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org			might be all we have.  Be ready.
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: Broken TX checksumming offloads
From: Ben Hutchings @ 2010-11-29 19:13 UTC (permalink / raw)
  To: Michał Mirosław; +Cc: netdev, Toshiharu Okada, e1000-devel
In-Reply-To: <20101129181742.GA29192@rere.qmqm.pl>

On Mon, 2010-11-29 at 19:17 +0100, Michał Mirosław wrote:
> Hi!
> 
> Unless I'm horribly mistaken, generic HW checksumming works as follows:
>  - driver sets netdev->features & NETIF_F_HW_CSUM to indicate support
>    for generic checksumming; if the flag is not set, networking core
>    will checksum skb before calling ndo_start_xmit (let's ignore
>    other checksumming options for now) and not pass skb with
>    skb->ip_summed == CHECKSUM_PARTIAL
>  - ndo_start_xmit() should use skb->csum_start and skb->csum_offset
>    (or skb->csum) to update checksum in software or instruct HW to do so
> 
> Looking at pch_gbe_xmit_frame() and its callee - pch_gbe_tx_queue() it
> looks like the driver should set NETIF_F_IP_CSUM instead of NETIF_F_HW_CSUM
> feature.
>
> Similar thing happens in ixgbe driver: it sets NETIF_F_HW_CSUM and checks
> for skb->ip_summed == CHECKSUM_PARTIAL, but then just warns on protocols
> other that TCP and SCTP (see: ixgbe_psum()).

AFAIK only {TCP,UDP}/IPv{4,6} use the simple 16-bit checksum algorithm
that NETIF_F_HW_CSUM implies, so in practice it is equivalent to
NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM even though it doesn't mean the same
thing.

Older kernel versions lacked a definititon of NETIF_F_IPV6_CSUM so
out-of-tree drivers and in-tree drivers that started out-of-tree are
likely to use NETIF_F_HW_CSUM as a workaround for that.

Since the minimum size of a {TCP,UDP}/IPv6/Ethernet frame is 62 bytes +
CRC, the workaround in pch_gbe_tx_queue() may not be needed for IPv6.
(I'm assuming that the critical length of 64 bytes actually includes the
CRC, although the workaround code currently assumes otherwise.)

> This means that these drivers might send packets with broken checksums
> when TX checksumming offload is enabled. I haven't checked other drivers, yet.

They might or they might not; it's hard to tell without access to the
hardware.  But if the driver never references csum_{start,offset} then
it is probably valid to replace NETIF_F_HW_CSUM with NETIF_F_IP_CSUM |
NETIF_F_IPV6_CSUM (and similarly for the ethtool operations).

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.


^ permalink raw reply

* Re: inet_hash_connect: source port allocation
From: Eric Dumazet @ 2010-11-29 19:07 UTC (permalink / raw)
  To: John Haxby; +Cc: NetDev, Stephen Hemminger
In-Reply-To: <1291056363.3435.1338.camel@edumazet-laptop>

Le lundi 29 novembre 2010 à 19:46 +0100, Eric Dumazet a écrit :
> Le lundi 29 novembre 2010 à 18:29 +0000, John Haxby a écrit :
> 
> > Sorry,  I think I phrased my question badly.
> > 
> > inet_csk_get_port() starts its search for a free port with
> > 
> >      smallest_rover = rover = net_random() % remaining + low;
> > 
> > whereas __inet_hash_connect() basically misses out that call to 
> > net_random() so you get a predictable port number.
> > 
> > Is there any good reason why that is the case?
> > 
> 
> It seems random select was done at bind() time only in commit
> 6df716340da3a6f ([TCP/DCCP]: Randomize port selection)
> 
> It probably should be done in autobind too.
> 
> 

I'll test following patch :

diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index 1b344f3..65c3702 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -466,20 +466,18 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
 	int twrefcnt = 1;
 
 	if (!snum) {
-		int i, remaining, low, high, port;
-		static u32 hint;
-		u32 offset = hint + port_offset;
+		int remaining, low, high, port;
 		struct hlist_node *node;
 		struct inet_timewait_sock *tw = NULL;
 
 		inet_get_local_port_range(&low, &high);
 		remaining = (high - low) + 1;
+		port = net_random() % remaining + low;
 
 		local_bh_disable();
-		for (i = 1; i <= remaining; i++) {
-			port = low + (i + offset) % remaining;
+		do {
 			if (inet_is_reserved_local_port(port))
-				continue;
+				goto next_nolock;
 			head = &hinfo->bhash[inet_bhashfn(net, port,
 					hinfo->bhash_size)];
 			spin_lock(&head->lock);
@@ -510,16 +508,17 @@ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
 			tb->fastreuse = -1;
 			goto ok;
 
-		next_port:
+next_port:
 			spin_unlock(&head->lock);
-		}
+next_nolock:
+			if (++port > high)
+				port = low;
+		} while (--remaining > 0);
 		local_bh_enable();
 
 		return -EADDRNOTAVAIL;
 
 ok:
-		hint += i;
-
 		/* Head lock still held and bh's disabled */
 		inet_bind_hash(sk, tb, port);
 		if (sk_unhashed(sk)) {



^ permalink raw reply related

* Re: [net-next-2.6] XFRM: remove unused member in xfrm_encap_tmpl.
From: David Miller @ 2010-11-29 18:57 UTC (permalink / raw)
  To: timo.teras; +Cc: dshwatrz, netdev
In-Reply-To: <4CF3EBF2.5060308@iki.fi>

From: Timo Teräs <timo.teras@iki.fi>
Date: Mon, 29 Nov 2010 20:07:46 +0200

> On 01/-10/-28163 09:59 PM, David Shwatrz wrote:
>> Hi,
>>  The patch removes unused member in xfrm_encap_tmpl.
>> 
>> Regards,
>> David Shwartz
>> 
>> 
>> Signed-off-by: David Shwartz <dshwatrz@gmail.com>
>> 
>> 
>> diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
>> index b971e38..7312707 100644
>> --- a/include/linux/xfrm.h
>> +++ b/include/linux/xfrm.h
>> @@ -235,7 +235,6 @@ struct xfrm_encap_tmpl {
>>  	__u16		encap_type;
>>  	__be16		encap_sport;
>>  	__be16		encap_dport;
>> -	xfrm_address_t	encap_oa;
>>  };
>>  
>>  /* AEVENT flags  */
> 
> struct xfrm_encap_tmpl is exposed to userland via netlink. This would
> break ABI.

RIght.

^ permalink raw reply

* Re: inet_hash_connect: source port allocation
From: Eric Dumazet @ 2010-11-29 18:46 UTC (permalink / raw)
  To: John Haxby; +Cc: NetDev, Stephen Hemminger
In-Reply-To: <4CF3F114.2070108@oracle.com>

Le lundi 29 novembre 2010 à 18:29 +0000, John Haxby a écrit :

> Sorry,  I think I phrased my question badly.
> 
> inet_csk_get_port() starts its search for a free port with
> 
>      smallest_rover = rover = net_random() % remaining + low;
> 
> whereas __inet_hash_connect() basically misses out that call to 
> net_random() so you get a predictable port number.
> 
> Is there any good reason why that is the case?
> 

It seems random select was done at bind() time only in commit
6df716340da3a6f ([TCP/DCCP]: Randomize port selection)

It probably should be done in autobind too.




^ permalink raw reply

* Re: [PATCH 2/2] pch_gbe driver: The wrong of initializer entry
From: Dr. David Alan Gilbert @ 2010-11-29 18:32 UTC (permalink / raw)
  To: Toshiharu Okada
  Cc: David S. Miller, Randy Dunlap, John Linn, Ralf Baechle,
	Kristoffer Glembo, Maxime Bizon, Greg Rose, ML netdev, LKML,
	Wang, Qi, Wang, Yong Y, Andrew, Intel OTC, Foster, Margie,
	Ewe, Kok Howg
In-Reply-To: <4CF3D23F.3040003@dsn.okisemi.com>

* Toshiharu Okada (toshiharu-linux@dsn.okisemi.com) wrote:
> The wrong of initializer entry was modified.
> 
> Signed-off-by: Toshiharu Okada <toshiharu-linux@dsn.okisemi.com>
> Reported-by: Dr. David Alan Gilbert <linux@treblig.org>

Thanks.

Dave
-- 
 -----Open up your eyes, open up your mind, open up your code -------   
/ Dr. David Alan Gilbert    |       Running GNU/Linux       | Happy  \ 
\ gro.gilbert @ treblig.org |                               | In Hex /
 \ _________________________|_____ http://www.treblig.org   |_______/

^ permalink raw reply

* Re: inet_hash_connect: source port allocation
From: John Haxby @ 2010-11-29 18:29 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: NetDev
In-Reply-To: <1291051560.3435.1198.camel@edumazet-laptop>

On 29/11/10 17:26, Eric Dumazet wrote:
> Le lundi 29 novembre 2010 à 17:04 +0000, John Haxby a écrit :
>> Hello,
>>
>> Please forgive me if this is a stupid question, but is there any
>> particular reason why the source port allocation in
>> __inet_hash_connect() shouldn't use the same random allocation that
>> inet_csk_get_port() uses?  The latter, of course, is used when bind()
>> doesn't specify a source port but the implicit "bind" for a connect()
>> gets its port allocated by __inet_hash_connect().
>>
>> jch
> autobind vs bind
>
> bind() gives more information, like local address (if any)
>
> autobind(), we dont know local address, it'll be chose later by routing.

Sorry,  I think I phrased my question badly.

inet_csk_get_port() starts its search for a free port with

     smallest_rover = rover = net_random() % remaining + low;

whereas __inet_hash_connect() basically misses out that call to 
net_random() so you get a predictable port number.

Is there any good reason why that is the case?

jch



^ permalink raw reply


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