Netdev List
 help / color / mirror / Atom feed
* RE: [PATCH net-next 1/3] net/usb/r8152: support aggregation
From: hayeswang @ 2013-08-13 12:32 UTC (permalink / raw)
  To: 'Oliver Neukum'; +Cc: netdev, linux-kernel, linux-usb
In-Reply-To: <1376383742.1681.1.camel@linux-fkkt.site>

 Oliver Neukum [mailto:oneukum@suse.de] 
> Sent: Tuesday, August 13, 2013 4:49 PM
> To: Hayeswang
> Cc: netdev@vger.kernel.org; linux-kernel@vger.kernel.org; 
> linux-usb@vger.kernel.org
> Subject: Re: [PATCH net-next 1/3] net/usb/r8152: support aggregation
> 
[...]
> > +               len_used = 0;
> > +               rx_desc = agg->head;
> > +               rx_data = agg->head;
> > +               smp_wmb();
> > +               pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK;
> > +               len_used += sizeof(struct rx_desc) + pkt_len;
> > +
> > +               while (urb->actual_length >= len_used) {
> > +                       if (pkt_len < ETH_ZLEN)
> > +                               break;
> > +
> > +                       pkt_len -= 4; /* CRC */
> > +                       rx_data += sizeof(struct rx_desc);
> > +
> > +                       skb = netdev_alloc_skb_ip_align(netdev,
> > pkt_len);
> > +                       if (!skb) {
> > +                               stats->rx_dropped++;
> > +                               break;
> > +                       }
> > +                       memcpy(skb->data, rx_data, pkt_len);
> > +                       skb_put(skb, pkt_len);
> > +                       skb->protocol = eth_type_trans(skb, netdev);
> > +                       netif_rx(skb);
> > +                       stats->rx_packets++;
> > +                       stats->rx_bytes += pkt_len;
> > +
> > +                       rx_data = rx_agg_align(rx_data + 
> pkt_len + 4);
> > +                       rx_desc = (struct rx_desc *)rx_data;
> > +                       smp_wmb();
> 
> Against what is the memory barrier?

Excuse me. I don't understand your question. Do you mean the function should not
be used here?

Best Regards,
Hayes

^ permalink raw reply

* RE: [PATCH net v5 0/5] bnx2x: fixes
From: Ariel Elior @ 2013-08-13 12:38 UTC (permalink / raw)
  To: Benjamin Poirier, Dmitry Kravkov
  Cc: davem@davemloft.net, netdev@vger.kernel.org, Eilon Greenstein
In-Reply-To: <20130813123043.GA30192@d2.synalogic.ca>

> I'm confused. Wasn't "[PATCH net v4 1/6] bnx2x: properly initialize
> statistic counters" supposed to fix a race condition? According to
> earlier communication with Ariel:
> 	In this issue a race condition at driver startup causes a second
> 	statistics query to be sent before the first one completes,
> 	resulting in a firmware assert and a stuck chip. A patch was
> 	sent upstream fixing this:
> 	http://patchwork.ozlabs.org/patch/264810/

As I explicitly mentioned in the communique which you quoted above, the patch was sent but not yet accepted.
This is precisely the upstream process - patches are being sent, reviewed and sometimes rejected and revised.
If you have further questions please address them to me - the technical forum is no place for this kind of discussion.
Thanks,
Ariel

^ permalink raw reply

* Re: ipsec smp scalability and cpu use fairness (softirqs)
From: Timo Teras @ 2013-08-13 12:41 UTC (permalink / raw)
  To: Steffen Klassert; +Cc: Andrew Collins, netdev
In-Reply-To: <20130813115652.GE26773@secunet.com>

On Tue, 13 Aug 2013 13:56:52 +0200
Steffen Klassert <steffen.klassert@secunet.com> wrote:

> On Tue, Aug 13, 2013 at 02:33:25PM +0300, Timo Teras wrote:
> > 
> > I've been now playing with pcrypt. It seems to not give significant
> > boost in throughput. I've setup the cpumaps properly, and top says
> > the work is distributed to appropriate kworkers, but for some reason
> > throughput does not get any better. I've tested with iperf in both
> > udp and tcp modes, with various amounts of threads.
> > 
> > Is there any more synchronization points for single SA that might
> > limit throughput? I've been testing with auth hmac(sha1), enc
> > cbc(aes) - according to metric the CPUs are still largely idle
> > instead of processing more data for better throughput. aes-gcm
> > (without pcrypt) achieves better throughput even saturating my test
> > box links.
> > 
> > Any pointers what to test, or to pinpoint the bottleneck?
> > 
> 
> The only pitfall that comes to my mind is that pcrypt must be
> instantiated before inserting the states. Your /proc/crypto
> should show something like:
> 
> name         : authenc(hmac(sha1),cbc(aes))
> driver       : pcrypt(authenc(hmac(sha1-generic),cbc(aes-asm)))
> module       : pcrypt
> priority     : 2100
> refcnt       : 1
> selftest     : passed
> type         : aead
> async        : yes
> blocksize    : 16
> ivsize       : 16
> maxauthsize  : 20
> geniv        : <built-in>
> 
> pcrypt is now instantiated, e.g. all new IPsec states (that do
> hmac-sha1, cbc-aes) will use it, adding new states increase the
> refcount.
> 
> I'll do some tests with current net-next on my own tomorrow and let
> you know about the results.

Yes, I've got pcrypt there. Apparently I had some of the cpu bindings
not right, so now it's looking a lot better. But it seems that
ksoftirqd on one of the CPUs becomes first bottleneck. I'll try to
figure out why.

Thanks on all the info so far, will continue experimenting here too.

^ permalink raw reply

* Re: [patch net] ipv6: do not create neighbor entries for local delivery
From: Marcelo Ricardo Leitner @ 2013-08-13 12:48 UTC (permalink / raw)
  To: Hannes Frederic Sowa
  Cc: Debabrata Banerjee, Jiri Pirko, davem@davemloft.net,
	netdev@vger.kernel.org, Alexey Kuznetsov, jmorris@namei.org,
	yoshfuji@linux-ipv6.org, Patrick McHardy, Banerjee, Debabrata,
	Joshua Hunt
In-Reply-To: <20130812222642.GA27385@order.stressinduktion.org>

Em 12-08-2013 19:26, Hannes Frederic Sowa escreveu:
> Hi Marcelo!
>
> On Mon, Aug 12, 2013 at 03:09:19PM -0300, Marcelo Ricardo Leitner wrote:
>> Hannes, would something like this be acceptable? I'm hoping it's not too
>> ugly/hacky... as far as I could track back, input and output routines were
>> merged mainly due code similarity.
>
> Your idea seems sound and I don't think it is very ugly or hacky. It's
> as minimal as a stable-only patch should be. But we could simplify the
> logic a bit. ;) See below.
>
>> TPROXY scenario needs to not create this neighbor entries on INPUT path,
>> while Debabrata ping test needs it on OUTPUT path. This patch limits my
>> previous patch to INPUT only then.
>
> Yes, agreed. I don't see anything which could break because of this patch.
> So I would go with it.
>
>> Initial testing here seems good, TPROXY seems to be working as expected and
>> also the ping6 test.
>>
>> What do you think?

Aye Hannes, thanks! I'll rework the patch based on your points, do some more 
testings in here and post it probably only by tomorrow.

Thanks!
Marcelo

>> diff --git a/net/ipv6/route.c b/net/ipv6/route.c
>> index 18ea73c..603f9d9 100644
>> --- a/net/ipv6/route.c
>> +++ b/net/ipv6/route.c
>> @@ -791,7 +791,7 @@ static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort,
>>   }
>>
>>   static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, int oif,
>> -				      struct flowi6 *fl6, int flags)
>> +				      struct flowi6 *fl6, int flags, int output)
>
> 								     bool input
>
>>   {
>>   	struct fib6_node *fn;
>>   	struct rt6_info *rt, *nrt;
>> @@ -799,8 +799,11 @@ static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
>>   	int attempts = 3;
>>   	int err;
>>   	int reachable = net->ipv6.devconf_all->forwarding ? 0 : RT6_LOOKUP_F_REACHABLE;
>> +	int local = RTF_NONEXTHOP;
>>
>>   	strict |= flags & RT6_LOOKUP_F_IFACE;
>> +	if (!output)
>> +			local |= RTF_LOCAL;
>
>
> 	if (input)
> 			local |= RTF_LOCAL;
>
>>
>>   relookup:
>>   	read_lock_bh(&table->tb6_lock);
>> @@ -820,7 +823,7 @@ restart:
>>   	read_unlock_bh(&table->tb6_lock);
>>
>>   	if (!dst_get_neighbour_raw(&rt->dst)
>> -	    && !(rt->rt6i_flags & (RTF_NONEXTHOP | RTF_LOCAL)))
>> +	    && !(rt->rt6i_flags & local))
>>   		nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr);
>>   	else if (!(rt->dst.flags & DST_HOST))
>>   		nrt = rt6_alloc_clone(rt, &fl6->daddr);
>> @@ -864,7 +867,7 @@ out2:
>>   static struct rt6_info *ip6_pol_route_input(struct net *net, struct fib6_table *table,
>>   					    struct flowi6 *fl6, int flags)
>>   {
>> -	return ip6_pol_route(net, table, fl6->flowi6_iif, fl6, flags);
>> +	return ip6_pol_route(net, table, fl6->flowi6_iif, fl6, flags, 0);
>
> 								      true);
>
>
>>   }
>>
>>   void ip6_route_input(struct sk_buff *skb)
>> @@ -890,7 +893,7 @@ void ip6_route_input(struct sk_buff *skb)
>>   static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table *table,
>>   					     struct flowi6 *fl6, int flags)
>>   {
>> -	return ip6_pol_route(net, table, fl6->flowi6_oif, fl6, flags);
>> +	return ip6_pol_route(net, table, fl6->flowi6_oif, fl6, flags, 1);
>
> 								      false);
>
>>   }
>>
>>   struct dst_entry * ip6_route_output(struct net *net, const struct sock *sk,
>
> Thanks,
>
>    Hannes
>
>

^ permalink raw reply

* [PATCH] ethernet/arc/arc_emac - fix NAPI "work > weight" warning
From: Alexey Brodkin @ 2013-08-13 13:04 UTC (permalink / raw)
  To: netdev
  Cc: Alexey Brodkin, Vineet Gupta, Mischa Jonker, Arnd Bergmann,
	Grant Likely, Rob Herring, Paul Gortmaker, David S. Miller,
	linux-kernel

Initially I improperly set a boundary for maximum number of input
packets to process on NAPI poll ("work") so it might be more than
expected amount ("weight").

This was really harmless but seeing WARN_ON_ONCE on every device boot is
not nice. So trivial fix ("<" instead of "<=") is here.

Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>

Cc: Vineet Gupta <vgupta@synopsys.com>
Cc: Mischa Jonker <mjonker@synopsys.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Grant Likely <grant.likely@linaro.org>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Paul Gortmaker <paul.gortmaker@windriver.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: linux-kernel@vger.kernel.org
---
 drivers/net/ethernet/arc/emac_main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c
index f1b121e..55d79cb 100644
--- a/drivers/net/ethernet/arc/emac_main.c
+++ b/drivers/net/ethernet/arc/emac_main.c
@@ -199,7 +199,7 @@ static int arc_emac_rx(struct net_device *ndev, int budget)
 	struct arc_emac_priv *priv = netdev_priv(ndev);
 	unsigned int work_done;
 
-	for (work_done = 0; work_done <= budget; work_done++) {
+	for (work_done = 0; work_done < budget; work_done++) {
 		unsigned int *last_rx_bd = &priv->last_rx_bd;
 		struct net_device_stats *stats = &priv->stats;
 		struct buffer_state *rx_buff = &priv->rx_buff[*last_rx_bd];
-- 
1.8.1.2

^ permalink raw reply related

* [PATCH 2/2] netfilter: export xt_HMARK.h to userland
From: Nicolas Dichtel @ 2013-08-13 13:05 UTC (permalink / raw)
  To: netfilter-devel; +Cc: pablo, netdev, Nicolas Dichtel
In-Reply-To: <1376399139-4181-1-git-send-email-nicolas.dichtel@6wind.com>

This file contains the API for the target "HMARK", hence it should be exported
to userland.

Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
 include/linux/netfilter/xt_HMARK.h      | 50 ---------------------------------
 include/uapi/linux/netfilter/Kbuild     |  1 +
 include/uapi/linux/netfilter/xt_HMARK.h | 50 +++++++++++++++++++++++++++++++++
 3 files changed, 51 insertions(+), 50 deletions(-)
 delete mode 100644 include/linux/netfilter/xt_HMARK.h
 create mode 100644 include/uapi/linux/netfilter/xt_HMARK.h

diff --git a/include/linux/netfilter/xt_HMARK.h b/include/linux/netfilter/xt_HMARK.h
deleted file mode 100644
index 826fc5807577..000000000000
--- a/include/linux/netfilter/xt_HMARK.h
+++ /dev/null
@@ -1,50 +0,0 @@
-#ifndef XT_HMARK_H_
-#define XT_HMARK_H_
-
-#include <linux/types.h>
-
-enum {
-	XT_HMARK_SADDR_MASK,
-	XT_HMARK_DADDR_MASK,
-	XT_HMARK_SPI,
-	XT_HMARK_SPI_MASK,
-	XT_HMARK_SPORT,
-	XT_HMARK_DPORT,
-	XT_HMARK_SPORT_MASK,
-	XT_HMARK_DPORT_MASK,
-	XT_HMARK_PROTO_MASK,
-	XT_HMARK_RND,
-	XT_HMARK_MODULUS,
-	XT_HMARK_OFFSET,
-	XT_HMARK_CT,
-	XT_HMARK_METHOD_L3,
-	XT_HMARK_METHOD_L3_4,
-};
-#define XT_HMARK_FLAG(flag)	(1 << flag)
-
-union hmark_ports {
-	struct {
-		__u16	src;
-		__u16	dst;
-	} p16;
-	struct {
-		__be16	src;
-		__be16	dst;
-	} b16;
-	__u32	v32;
-	__be32	b32;
-};
-
-struct xt_hmark_info {
-	union nf_inet_addr	src_mask;
-	union nf_inet_addr	dst_mask;
-	union hmark_ports	port_mask;
-	union hmark_ports	port_set;
-	__u32			flags;
-	__u16			proto_mask;
-	__u32			hashrnd;
-	__u32			hmodulus;
-	__u32			hoffset;	/* Mark offset to start from */
-};
-
-#endif /* XT_HMARK_H_ */
diff --git a/include/uapi/linux/netfilter/Kbuild b/include/uapi/linux/netfilter/Kbuild
index dc00927ffd62..174915420d3f 100644
--- a/include/uapi/linux/netfilter/Kbuild
+++ b/include/uapi/linux/netfilter/Kbuild
@@ -22,6 +22,7 @@ header-y += xt_CONNMARK.h
 header-y += xt_CONNSECMARK.h
 header-y += xt_CT.h
 header-y += xt_DSCP.h
+header-y += xt_HMARK.h
 header-y += xt_IDLETIMER.h
 header-y += xt_LED.h
 header-y += xt_LOG.h
diff --git a/include/uapi/linux/netfilter/xt_HMARK.h b/include/uapi/linux/netfilter/xt_HMARK.h
new file mode 100644
index 000000000000..826fc5807577
--- /dev/null
+++ b/include/uapi/linux/netfilter/xt_HMARK.h
@@ -0,0 +1,50 @@
+#ifndef XT_HMARK_H_
+#define XT_HMARK_H_
+
+#include <linux/types.h>
+
+enum {
+	XT_HMARK_SADDR_MASK,
+	XT_HMARK_DADDR_MASK,
+	XT_HMARK_SPI,
+	XT_HMARK_SPI_MASK,
+	XT_HMARK_SPORT,
+	XT_HMARK_DPORT,
+	XT_HMARK_SPORT_MASK,
+	XT_HMARK_DPORT_MASK,
+	XT_HMARK_PROTO_MASK,
+	XT_HMARK_RND,
+	XT_HMARK_MODULUS,
+	XT_HMARK_OFFSET,
+	XT_HMARK_CT,
+	XT_HMARK_METHOD_L3,
+	XT_HMARK_METHOD_L3_4,
+};
+#define XT_HMARK_FLAG(flag)	(1 << flag)
+
+union hmark_ports {
+	struct {
+		__u16	src;
+		__u16	dst;
+	} p16;
+	struct {
+		__be16	src;
+		__be16	dst;
+	} b16;
+	__u32	v32;
+	__be32	b32;
+};
+
+struct xt_hmark_info {
+	union nf_inet_addr	src_mask;
+	union nf_inet_addr	dst_mask;
+	union hmark_ports	port_mask;
+	union hmark_ports	port_set;
+	__u32			flags;
+	__u16			proto_mask;
+	__u32			hashrnd;
+	__u32			hmodulus;
+	__u32			hoffset;	/* Mark offset to start from */
+};
+
+#endif /* XT_HMARK_H_ */
-- 
1.8.2.1

^ permalink raw reply related

* [PATCH 1/2] netfilter: export xt_rpfilter.h to userland
From: Nicolas Dichtel @ 2013-08-13 13:05 UTC (permalink / raw)
  To: netfilter-devel; +Cc: pablo, netdev, Nicolas Dichtel

This file contains the API for the match "rpfilter", hence it should be exported
to userland.

Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
 include/linux/netfilter/xt_rpfilter.h      | 23 -----------------------
 include/uapi/linux/netfilter/Kbuild        |  1 +
 include/uapi/linux/netfilter/xt_rpfilter.h | 23 +++++++++++++++++++++++
 3 files changed, 24 insertions(+), 23 deletions(-)
 delete mode 100644 include/linux/netfilter/xt_rpfilter.h
 create mode 100644 include/uapi/linux/netfilter/xt_rpfilter.h

diff --git a/include/linux/netfilter/xt_rpfilter.h b/include/linux/netfilter/xt_rpfilter.h
deleted file mode 100644
index 8358d4f71952..000000000000
--- a/include/linux/netfilter/xt_rpfilter.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef _XT_RPATH_H
-#define _XT_RPATH_H
-
-#include <linux/types.h>
-
-enum {
-	XT_RPFILTER_LOOSE = 1 << 0,
-	XT_RPFILTER_VALID_MARK = 1 << 1,
-	XT_RPFILTER_ACCEPT_LOCAL = 1 << 2,
-	XT_RPFILTER_INVERT = 1 << 3,
-#ifdef __KERNEL__
-	XT_RPFILTER_OPTION_MASK = XT_RPFILTER_LOOSE |
-				  XT_RPFILTER_VALID_MARK |
-				  XT_RPFILTER_ACCEPT_LOCAL |
-				  XT_RPFILTER_INVERT,
-#endif
-};
-
-struct xt_rpfilter_info {
-	__u8 flags;
-};
-
-#endif
diff --git a/include/uapi/linux/netfilter/Kbuild b/include/uapi/linux/netfilter/Kbuild
index 41115776d76f..dc00927ffd62 100644
--- a/include/uapi/linux/netfilter/Kbuild
+++ b/include/uapi/linux/netfilter/Kbuild
@@ -68,6 +68,7 @@ header-y += xt_quota.h
 header-y += xt_rateest.h
 header-y += xt_realm.h
 header-y += xt_recent.h
+header-y += xt_rpfilter.h
 header-y += xt_sctp.h
 header-y += xt_set.h
 header-y += xt_socket.h
diff --git a/include/uapi/linux/netfilter/xt_rpfilter.h b/include/uapi/linux/netfilter/xt_rpfilter.h
new file mode 100644
index 000000000000..8358d4f71952
--- /dev/null
+++ b/include/uapi/linux/netfilter/xt_rpfilter.h
@@ -0,0 +1,23 @@
+#ifndef _XT_RPATH_H
+#define _XT_RPATH_H
+
+#include <linux/types.h>
+
+enum {
+	XT_RPFILTER_LOOSE = 1 << 0,
+	XT_RPFILTER_VALID_MARK = 1 << 1,
+	XT_RPFILTER_ACCEPT_LOCAL = 1 << 2,
+	XT_RPFILTER_INVERT = 1 << 3,
+#ifdef __KERNEL__
+	XT_RPFILTER_OPTION_MASK = XT_RPFILTER_LOOSE |
+				  XT_RPFILTER_VALID_MARK |
+				  XT_RPFILTER_ACCEPT_LOCAL |
+				  XT_RPFILTER_INVERT,
+#endif
+};
+
+struct xt_rpfilter_info {
+	__u8 flags;
+};
+
+#endif
-- 
1.8.2.1

^ permalink raw reply related

* [PATCH net] tun: compare with 0 instead of total_len
From: Weiping Pan @ 2013-08-13 13:46 UTC (permalink / raw)
  To: netdev

Since we set "len = total_len" in the beginning of tun_get_user(),
so we should compare the new len with 0, instead of total_len,
or the if statement always returns false.

Signed-off-by: Weiping Pan <wpan@redhat.com>
---
 drivers/net/tun.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index db690a3..5a8ee1c 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1074,7 +1074,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
 	u32 rxhash;
 
 	if (!(tun->flags & TUN_NO_PI)) {
-		if ((len -= sizeof(pi)) > total_len)
+		if ((len -= sizeof(pi)) < 0)
 			return -EINVAL;
 
 		if (memcpy_fromiovecend((void *)&pi, iv, 0, sizeof(pi)))
@@ -1083,7 +1083,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
 	}
 
 	if (tun->flags & TUN_VNET_HDR) {
-		if ((len -= tun->vnet_hdr_sz) > total_len)
+		if ((len -= tun->vnet_hdr_sz) < 0)
 			return -EINVAL;
 
 		if (memcpy_fromiovecend((void *)&gso, iv, offset, sizeof(gso)))
-- 
1.7.4

^ permalink raw reply related

* Quick Blind TCP Connection Spoofing with SYN Cookies
From: Jakob Lell @ 2013-08-13 13:57 UTC (permalink / raw)
  To: full-disclosure-yjGSz5NhYZxwCIiogXJnzFpr/1R2p/CL
  Cc: oss-security-ZwoEplunGu1jrUoiu81ncdBPR1lH4CV8,
	netdev-u79uwXL29TY76Z2rM5mHXA

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

Advisory location:
http://www.jakoblell.com/blog/2013/08/13/quick-blind-tcp-connection-spoofing-with-syn-cookies/

Quick Blind TCP Connection Spoofing with SYN Cookies

Abstract:

TCP uses 32 bit Seq/Ack numbers in order to make sure that both sides of 
a connection can actually receive packets from each other. Additionally, 
these numbers make it relatively hard to spoof the source address 
because successful spoofing requires guessing the correct initial 
sequence number (ISN) which is generated by the server in a 
non-guessable way. It is commonly known that a 32 bit number can be 
brute forced in a couple of hours given a fast (gigabit) network 
connection. This article shows that the effort required for guessing a 
valid ISN can be reduced from hours to minutes if the server uses TCP 
SYN Cookies (a widely used defense mechanism against SYN-Flooding DOS 
Attacks), which are enabled by default for various Linux distributions 
including Ubuntu and Debian.

I. Repetition of TCP Basics

A TCP Connection is initiated with a three-way handshake:

SYN: The Client sends a SYN packet to the server in order to initiate a 
connection. The SYN packet contains an initial sequence number (ISN) 
generated by the client.
SYN-ACK: The server acknowledges the connection request by the client. 
The SYN-ACK Packet contains an ISN generated by the server. It also 
confirms the ISN from the client in the ack field of the TCP header so 
that the client can verify that the SYN-ACK packet actually comes from 
the server and isn't spoofed.
ACK: In the final ACK packet of the three-way handshake the client 
confirms that it has received the ISN generated by the server. That way 
the server knows that the client has actually received the SYN-ACK 
packet from the server and thus the connection request isn't spoofed.

After this three-way handshake, the TCP connection is established and 
both sides can send data to each other. The initial sequence numbers 
make sure that the other side can actually receive the packets and thus 
prevent IP spoofing given that the attacker can't receive packets sent 
to the spoofed IP address.

Since the initial sequence numbers are only 32-bit values, it is not 
impossible to blindly spoof a connection by brute-forcing the ISN. If we 
need to send 3 packets to the server (one SYN packet to initiate the 
connection, one ACK packet to finish the three-way handshake and one 
payload packet), we will have to send 3*2^32 packets per successfully 
spoofed connection at an average. Given a packet rate of 300,000 packets 
per second (which can easily be achieved with a gigabit connection), 
sending this packets requires some 12 hours.

One long-known weakness of the original TCP protocol design is that an 
attacker can spoof a high number of SYN packets to a server. The server 
then has to send (and maybe even retransmit) a SYN-ACK packet to each of 
the spoofed IP addresses and keep track the half-open connection so that 
it can handle an ACK packet. Remembering a high number of bogus 
half-open connections can lead to resource exhaustion and make the 
server unresponsive to legitimate clients. This attack is called SYN 
Flooding and it can lead to DOS even if the attacker only uses a 
fraction of the network bandwidth available to the server.

II. Description of the SYN Cookie approach

In order to protect servers against SYN-Flooding attacks, Daniel J. 
Bernstein suggested the technique of TCP Syn Cookies in 1996. The main 
idea of the approach is not to keep track of incoming SYN packets and 
instead encode the required information in the ISN generated by the 
server. Once the server receives an ACK packet, he can check whether the 
Ack number from the client actually matches the server-generated ISN, 
which can easily be recalculated when receiving the ACK-packet. This 
allows processing the ACK packet without remembering anything about the 
initial SYN request issued by the client.

Since the server doesn't keep track of half-open connections, it can't 
remember any detail of the SYN packet sent by the client. Since the 
initial SYN packet contains the maximum segment size (MSS) of the 
client, the server encodes the MSS using 3 bits (via a table with 8 
hard-coded MSS values). In order to make sure that half-open connections 
expire after a certain time, the server also encodes a 
slowly-incrementing (typically about once a minute) counter to the ISN. 
Other options of the initial SYN packet are typically ignored (although 
recent Linux kernels do support some options by encoding them via TCP 
Timestamps [1]). When receiving an ACK packet, the kernel extracts the 
counter value from the SYN Cookie and checks whether it is one of the 
last 4 valid values.

The original approach of Bernstein [2] only encodes the counter and the 
MSS value in the first 8 bits of the ISN thus leaving only 24 bits for 
the cryptographically generated (non-guessable) value which needs to be 
guessed for spoofing a connection. This can easily be brute forced 
within relatively short time given the speed of modern network hardware. 
In order to mitigate this attack, Bernstein suggests[3]:

# Add another number to the cookie: a 32-bit server-selected secret 
function of the client address and server address (but not the current 
time). This forces the attacker to guess 32 bits instead of 24.

This is implemented in recent Linux kernels and it does indeed make 
guessing the ISN more costly than a simple implementation without this 
additional secret function. However, as we will see in the next section, 
it does not require the attacker to guess the full 32 bit ISN.

The following function shows the generation of the SYN Cookies in the 
Linux Kernel 3.10.1 (file net/ipv4/syncookies.c):

#define COOKIEBITS 24    /* Upper bits store count */
#define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1)

static __u32 secure_tcp_syn_cookie(__be32 saddr, __be32 daddr, __be16 sport,
                    __be16 dport, __u32 sseq, __u32 count,
                    __u32 data)
{
     /*
      * Compute the secure sequence number.
      * The output should be:
      *   HASH(sec1,saddr,sport,daddr,dport,sec1) + sseq + (count * 2^24)
      *      + (HASH(sec2,saddr,sport,daddr,dport,count,sec2) % 2^24).
      * Where sseq is their sequence number and count increases every
      * minute by 1.
      * As an extra hack, we add a small "data" value that encodes the
      * MSS into the second hash value.
      */

     return (cookie_hash(saddr, daddr, sport, dport, 0, 0) +
         sseq + (count << COOKIEBITS) +
         ((cookie_hash(saddr, daddr, sport, dport, count, 1) + data)
          & COOKIEMASK));
}

The value sseq is the sequence number generated by the client and is 
therefore directly known to the attacker. The data is an integer between 
0 and 7, which encodes one of 8 possible MSS values. The count value is 
just a timestamp which is increased once a minute and it is encoded in 
the upper 8 bits of the generated cookie. However, since the first hash 
value is not known to the attacker, the timestamp value must be guessed 
by the attacker as well.

The following two functions show how the SYN Cookies are verified when 
receiving an ACK packet:

#define COUNTER_TRIES 4


/*
  * This retrieves the small "data" value from the syncookie.
  * If the syncookie is bad, the data returned will be out of
  * range.  This must be checked by the caller.
  *
  * The count value used to generate the cookie must be within
  * "maxdiff" if the current (passed-in) "count".  The return value
  * is (__u32)-1 if this test fails.
  */
static __u32 check_tcp_syn_cookie(__u32 cookie, __be32 saddr, __be32 daddr,
                   __be16 sport, __be16 dport, __u32 sseq,
                   __u32 count, __u32 maxdiff)
{
     __u32 diff;

     /* Strip away the layers from the cookie */
     cookie -= cookie_hash(saddr, daddr, sport, dport, 0, 0) + sseq;

     /* Cookie is now reduced to (count * 2^24) ^ (hash % 2^24) */
     diff = (count - (cookie >> COOKIEBITS)) & ((__u32) - 1 >> COOKIEBITS);
     if (diff >= maxdiff)
         return (__u32)-1;

     return (cookie -
         cookie_hash(saddr, daddr, sport, dport, count - diff, 1))
         & COOKIEMASK;    /* Leaving the data behind */
}

/*
  * Check if a ack sequence number is a valid syncookie.
  * Return the decoded mss if it is, or 0 if not.
  */
static inline int cookie_check(struct sk_buff *skb, __u32 cookie)
{
     const struct iphdr *iph = ip_hdr(skb);
     const struct tcphdr *th = tcp_hdr(skb);
     __u32 seq = ntohl(th->seq) - 1;
     __u32 mssind = check_tcp_syn_cookie(cookie, iph->saddr, iph->daddr,
                         th->source, th->dest, seq,
                         jiffies / (HZ * 60),
                         COUNTER_TRIES);

     return mssind < ARRAY_SIZE(msstab) ? msstab[mssind] : 0;
}

First of all, the server removes the first hash value and the ISN chosen 
by the client. This is easily possible because the hash only depends on 
a server secret and the source/destination address/port and doesn't 
change over time. Then the upper 8 bits contain the count value and if 
this counter is one of the last four valid counter values, it is 
accepted. At that point the counter used for generating the SYN Cookie 
is known and the server can therefore calculate the second hash and 
subtract it from the cookie. The remaining value is the encoded MSS 
value. The Cookie is only accepted if this encoded MSS value is actually 
a number between 0 and 7.


III. Reduced cost of guessing due to multiple valid ISNs

Since the kernel encodes a counter and the MSS value in the ISN, there 
must be one valid ISN for every combination of a valid counter value and 
a valid MSS value. In current implementations there are 4 valid counter 
values and 8 possible MSS values. This gives a total of 32 valid 
combinations which will be accepted by the server at any given time. 
Each of this 32 combination results in one valid ISN and if the attacker 
guesses any one of them, the kernel will accept the ACK packet. This 
reduces the effort needed to successfully guess a valid ISN by the 
factor 32.

Since the server doesn't remember that he has received a SYN packet when 
using SYN Cookies, there is no need to actually send the initial SYN 
packet. If we start the connection by sending an ACK packet and guess 
one of the 32 valid ISNs, the kernel will process the ACK packet without 
noticing that he has never received a SYN packet from the client and 
responded with a SYN-Ack packet.

IV. Combination of ACK-Packet and Payload

Although the TCP standard assumes that the three-way handshake is 
completed before any data is sent, it is also possible to add data to 
the final ACK packet of the handshake [4]. This means that guessing an 
ISN and spoofing a full tcp connection with some payload data (such as 
an http request) can be reduced to sending out only one single packet. 
So the average number of packets required per successfully spoofed 
connection can be reduced to 2^32 / 32 (because the server accepts 32 
different ISNs at a time). At a packet rate of 300,000 pps (which can 
easily be achieved with gigabit ethernet) this amount of packets can be 
sent out in no more than 8 minutes (compared to the 12 hours calculated 
in section I).

V. Possible real-life applications of TCP Connection spoofing

Many application developers assume that TCP makes sure that the client 
IP address is actually correct and can't easily be spoofed. Being able 
to spoof the source address obviously creates significant problems when 
using the IP address for authentication e.g. for legacy protocols like 
RSH. Even if RSH has widely been replaced by more secure alternatives 
like SSH by now, there are still some applications where the IP address 
is used for authentication. For instance it is still common to have 
administrative interfaces which can only be accessed from certain IP 
addresses. Another widespread usage of IP addresses for authentication 
is that many web applications bind the session ID to a specific IP 
address. If the session ID can be stolen by other means, an attacker can 
use the method described here to bypass this IP address verification.

Aside from actually using IP addresses for authenticating requests, it 
is also quite common to log IP addresses, which may then be used to 
track down initiators of objectionable requests such as exploits, 
abusive blog comments or illegal file sharing traffic. Using the 
technique described here may allow planting false evidence in the logged 
IP addresses.

Being able to spoof IP addresses also allows bypassing SPF e.g. when 
sending spear phishing mails in order to give the phishing mails the 
additional credibility of a valid SPF sender address, which may help to 
bypass email filtering software.

An obvious limitation of the technique described here is that when 
spoofing the IP address, you can only send a request (which may result 
in persistent changes on the server) but not receive any responses sent 
by the server. For many protocols it is however possible to guess the 
size of the server responses, send matching ACK packets and transmit 
multiple payload packets in order to spoof a more complex protocol 
interaction with the server.


VI. POC Exploit and real-life performance measures

This section describes the steps needed to actually carry out the attack 
and contains full POC code. For my experimental setup the server used 
the IP address 192.168.1.11 and port 1234. The attacker system was 
located in the same local subnet and the spoofed IP address was 
192.168.1.217.

First of all, even if SYN Cookies are enabled in 
/proc/sys/net/ipv4/tcp_syncookies (which is the default for various 
linux distributions), the system will still use a traditional backlog 
queue for storing half-open connections and only fall back to using SYN 
Cookies if the backlog queue overflows. The main reason for this is that 
storing information about connection requests allows full support of TCP 
Options and arbitrary MSS values (which don't have to be reduced to one 
of 8 predefined values). The backlog queue size is 2048 by default and 
can be adjusted via /proc/sys/net/ipv4/tcp_max_syn_backlog. So in order 
to actually carry out the spoofing attack, we have to intentionally 
overflow the backlog queue by doing a Syn-Flooding attack. This can be 
done e.g. with the hping3 command:

hping3 -i u100 -p 1234 -S -a 192.168.1.216 -q 192.168.1.11

Experiments have shown that running hping3 in parallel to the actual ISN 
brute-forcing does significantly reduce the packet rate even if hping3 
is configured to use only a small fraction of the packet rate of the ISN 
brute-forcing tool. In order to achieve the maximum packet rate 
possible, it is therefore more efficient to run hping3 in regular short 
intervals. The following command sends out 3000 SYN packets in a short 
burst once a second:

while true;do time hping3 -i u1 -c 3000 -S -q -p 1234 -a 192.168.1.216 
192.168.1.11;sleep 1;done

The source IP address used for this SYN-Flooding attack should not 
respond with a RST packet or return an ICMP Destination Host Unreachable 
message so that the queue entries aren't freed before they time out. On 
linux you can easily add another IP address to a network interface and 
block all traffic coming to this IP address in order to prevent it from 
responding with RST packets:

ifconfig eth0:1 inet 192.168.1.216 netmask 255.255.255.0 up
iptables -I INPUT --dst 192.168.1.216 -j DROP

I've used the same commands to set up the IP address 192.168.1.217, 
which is the IP address I wanted to spoof. This makes sure that sending 
responses to the spoofed address won't lead to a RST packet or an ICMP 
Destination Host Unreachable packet, which may lead to a premature 
termination of the connection and the processing of the spoofed request 
in the server software.

ifconfig eth0:2 inet 192.168.1.217 netmask 255.255.255.0 up
iptables -I INPUT --dst 192.168.1.217 -j DROP

In a real world attack, the same goal can also be achieved by issuing a 
(D)DOS attack against the spoofed IP address.

Once the system is in SYN-Cookie mode, it is necessary to spoof a high 
number of ACK packets with a payload in order to guess one of the 32 
valid ISNs. I initially wanted to do this with scapy but this failed due 
to the utterly low performance of scapy (less then 10k packets per 
second). So I went on to create a pcap file in scapy, which can then be 
sent out with a patched version of tcpreplay in a loop. The patched 
tcpreplay just increases the ack field of the tcp header by 31337 for 
each repetition of the loop. Using an uneven number makes sure that it 
reaches all 2^32 possible values without repetitions. In theory you 
could just linearly try all possible ISNs. However, the counter value in 
the 8 upper bits of the ISN only changes once a minute and is linearly 
incremented for a given combination of source and destination 
address/port. Therefore a linear search will likely be in an incorrect 
range and not create any hit within a long time. So it is advisable to 
increment the guessed ISN by a larger number so that it traverses the 
full ISN space relatively quickly.

The attached script create_packet.py creates a single ACK packet with 
some payload data.

The next step is to patch and compile tcpreplay. Here are the commands 
needed on an Ubuntu 12.04 amd64 system:

apt-get install build-essential libpcap-dev
ln -s lib/x86_64-linux-gnu /usr/lib64 # Quick workaround for a bug in 
the build system of tcpreplay
wget -O tcpreplay-3.4.4.tar.gz 
http://prdownloads.sourceforge.net/tcpreplay/tcpreplay-3.4.4.tar.gz?download
tar xzvf tcpreplay-3.4.4.tar.gz
cd tcpreplay-3.4.4
cat ../tcpreplay_patch.txt | patch -p1
./configure
make
cp src/tcpreplay-edit ../


After compiling a patched version of tcpreplay, you can use the 
following commands to actually send out packets in an infinite loop:
python create_packet.py
while true;do time ./tcpreplay-edit -i eth0 -t -C -K -l 500000000 -q 
ack_with_payload.pcap;done


VII. Experimental results

I've tested this setup in a local network between a 3 year old notebook 
(HP 6440b, i5-430M CPU and Marvell 88E8072 gigabit NIC) as the client 
and a desktop computer as the server. With a small test payload, the 
achievable packet rate is some 280,000 packets per seconds, which leads 
to some 73% CPU usage of the tcpreplay process (18% user and 55% sys in 
the output of time). According to [5] it may be expected that the packet 
rate can at least be doubled given a fast system with a decent Intel 
gigabit network card. Obviously the actual packet rate also depends on 
the size of the payload data. During a 10.5 hour overnight run I 
successfully spoofed 64 connections, which is about one successful spoof 
every 10 minutes. This is a little bit less than the expected value of 
79 spoofed connections (once every 8 minutes). There are several 
possible explanations for this deviation:
* The tcpreplay process takes some time to print the statistics in the 
end. During that time no packets are sent. I've only used the statistics 
output of tcpreplay for measuring the packet rate and so the measured 
packet rate may be a little bit off.
* When going to the maximum packet rate achievable with your hardware, 
there may be packet loss (especially if you don't use any kind of 
congestion control).
* Last but not least the spoofing is a statistical process. The standard 
deviation is approximately the square root of the expected number of 
spoofed connections and it is not particularly unlikely to be off by one 
or two standard deviations from the expected value. For this experiment 
the standard deviation is sqrt(79) = 8.89 and the measured number of 
spoofed connections was off by 1.68 standard deviations, which is well 
within the expected statistical variation.

VIII. Possible mitigation options

The simplification of TCP Connection Spoofing described here is an 
inherent problem of TCP SYN Cookies and so there won't be a simple patch 
which just solves the issue and makes the Spoofing Attack as hard as it 
is without SYN Cookies. It is only possible to gradually increase the 
required effort for successfully spoofing a connection e.g. by only 
accepting the last two instead of four counter values (which will lead 
to a 60-120s timeout between the initial SYN and the final ACK packet of 
the three-way handshake during a SYN Flooding attack) or by disallowing 
the combination of the final ACK packet with payload data (which will 
double the number of packets the attacker has to send). However, even 
with this two mitigation options in place, the spoofing attack is still 
about an order of magnitude easier with SYN Cookies than it is without 
SYN Cookies and it would still be very inadvisable to assume that the 
source IP address of TCP connections can't be spoofed. It may also be 
possible to use the lower bits of the TCP timestamp option (which is 
currently used in order to support TCP Options with SYN Cookies) for 
encoding the MSS and counter values. However, this can only provide 
effective protection against a spoofing attack if the server refuses 
clients which don't support TCP timestamps during a SYN Flooding Attack, 
which will break compatibility with some standard-conform TCP 
implementations.

It is obviously possible to disable SYN Cookies (and increase the 
backlog queue size in /proc/sys/net/ipv4/tcp_max_syn_backlog) in order 
to make the spoofing attack as hard as possible and force an attacker to 
brute force the full 32 bit ISN space. However, disabling SYN Cookies 
may require a significant amount of CPU Time and Memory during a SYN 
Flooding Attack. Moreover, the spoofing is still not impossible even 
without SYN Cookies and it will likely succeed within a couple of hours 
with a gigabit ethernet connection.

Given the limitations of the other mitigation options my suggestion is 
to solve the  problem on a higher level and make sure that the security 
of applications doesn't rely on the impossible of spoofing the source 
address of TCP connections. This obviously means that you should never 
rely on source IP addresses for authentication. For web applications it 
is also possible to mitigate the issue by using secure CSRF tokens for 
all actions which cause persistent changes on the server and not 
processing the request unless it uses a valid CSRF token. In that case 
the IP address of the request using the CSRF token may be spoofed but 
the IP address to which the token has been sent to can't be spoofed 
since the attacker will need to receive the CSRF token so that he can 
use it. When logging IP addresses used for certain actions such as blog 
comments or account registrations, the IP address to which the CSRF 
token has been sent to should be logged additionally to (or instead of) 
the IP address using the token.

References:
[1]: http://lwn.net/Articles/277146/
[2]: http://cr.yp.to/syncookies.html Section "What are SYN cookies?"
[3]: http://cr.yp.to/syncookies.html Section "Blind connection forgery"
[4]: http://www.thice.nl/creating-ack-get-packets-with-scapy/
[5]: 
http://wiki.networksecuritytoolkit.org/nstwiki/index.php/LAN_Ethernet_Maximum_Rates,_Generation,_Capturing_%26_Monitoring#pktgen:_UDP_60_Byte_Packets


[-- Attachment #2: create_packet.py --]
[-- Type: text/x-python, Size: 794 bytes --]

#!/usr/bin/python

# Change log level to suppress annoying IPv6 error
import logging
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)

from scapy.all import *
import time

# Adjust MAC addresses of sender and recipient of this packet accordingly, the dst MAC 
# should be the MAC of the gateway to use when the target is not on your local subnet
ether=Ether(src="40:eb:60:9f:42:a0",dst="e8:40:f2:d1:b3:a2")
# Set up source and destination IP addresses
ip=IP(src="192.168.1.217", dst="192.168.1.11")

# Assemble an ACK packet with "Hello World\n" as a payload
pkt = ether/ip/TCP(sport=31337, dport=1234, flags="A", seq=43, ack=1337) / ("Hello World\n")
# Write the packet to a pcap file, which can then be sent using a patched version of tcpreplay
wrpcap("ack_with_payload.pcap",pkt)


[-- Attachment #3: tcpreplay_patch.txt --]
[-- Type: text/plain, Size: 1578 bytes --]

diff -u -r tcpreplay-3.4.4/src/send_packets.c tcpreplay-3.4.4.patched/src/send_packets.c
--- tcpreplay-3.4.4/src/send_packets.c	2010-04-05 02:58:02.000000000 +0200
+++ tcpreplay-3.4.4.patched/src/send_packets.c	2013-08-06 10:56:51.757048452 +0200
@@ -81,6 +81,9 @@
 void
 send_packets(pcap_t *pcap, int cache_file_idx)
 {
+    static u_int32_t ack_bruteforce_offset = 1;
+    uint32_t* ack;
+    uint32_t orig_ack;
     struct timeval last = { 0, 0 }, last_print_time = { 0, 0 }, print_delta, now;
     COUNTER packetnum = 0;
     struct pcap_pkthdr pkthdr;
@@ -154,6 +157,9 @@
 #endif
 
 #if defined TCPREPLAY && defined TCPREPLAY_EDIT
+        ack = (uint32_t*)(pktdata + 14 + 20 + 8);
+        orig_ack = *ack;
+        *ack = htonl(ntohl(*ack) + ack_bruteforce_offset);
         pkthdr_ptr = &pkthdr;
         if (tcpedit_packet(tcpedit, &pkthdr_ptr, &pktdata, sp->cache_dir) == -1) {
             errx(-1, "Error editing packet #" COUNTER_SPEC ": %s", packetnum, tcpedit_geterr(tcpedit));
@@ -176,7 +182,7 @@
         /* write packet out on network */
         if (sendpacket(sp, pktdata, pktlen) < (int)pktlen)
             warnx("Unable to send packet: %s", sendpacket_geterr(sp));
-
+        *ack = orig_ack;
         /*
          * track the time of the "last packet sent".  Again, because of OpenBSD
          * we have to do a mempcy rather then assignment.
@@ -205,7 +211,7 @@
             }
         }
     } /* while */
-
+    ack_bruteforce_offset += 31337;
     if (options.enable_file_cache) {
         options.file_cache[cache_file_idx].cached = TRUE;
     }


^ permalink raw reply

* Re: [PATCH net v5 0/5] bnx2x: fixes
From: Benjamin Poirier @ 2013-08-13 14:07 UTC (permalink / raw)
  To: Ariel Elior
  Cc: Dmitry Kravkov, davem@davemloft.net, netdev@vger.kernel.org,
	Eilon Greenstein
In-Reply-To: <6AE768456CEC4B4A9B2248CB6B87EB3E1BEB957E@SJEXCHMB05.corp.ad.broadcom.com>

On 2013/08/13 12:38, Ariel Elior wrote:
> > I'm confused. Wasn't "[PATCH net v4 1/6] bnx2x: properly initialize
> > statistic counters" supposed to fix a race condition? According to
> > earlier communication with Ariel:
> > 	In this issue a race condition at driver startup causes a second
> > 	statistics query to be sent before the first one completes,
> > 	resulting in a firmware assert and a stuck chip. A patch was
> > 	sent upstream fixing this:
> > 	http://patchwork.ozlabs.org/patch/264810/
> 
> As I explicitly mentioned in the communique which you quoted above, the patch was sent but not yet accepted.
> This is precisely the upstream process - patches are being sent, reviewed and sometimes rejected and revised.
> If you have further questions please address them to me - the technical forum is no place for this kind of discussion.
> Thanks,
> Ariel
> 

It's a technical question about a patch which was sent upstream. Where
should the discussion happen if not upstream?

Let me rephrase my question:

I'm confused. I thought that "[PATCH net v4 1/6] bnx2x: properly
initialize statistic counters" was meant to fix a race condition at
driver startup which causes a second statistics query to be sent before
the first one completes, resulting in a firmware assert and a stuck
chip. Am I mistaken and there is no such race condition, or is it
addressed by the other patches in this series?

^ permalink raw reply

* RE: [PATCH net v5 0/5] bnx2x: fixes
From: Dmitry Kravkov @ 2013-08-13 14:16 UTC (permalink / raw)
  To: Benjamin Poirier, Ariel Elior
  Cc: davem@davemloft.net, netdev@vger.kernel.org, Eilon Greenstein
In-Reply-To: <20130813140715.GA4394@d2.synalogic.ca>

> -----Original Message-----
> From: netdev-owner@vger.kernel.org [mailto:netdev-
> owner@vger.kernel.org] On Behalf Of Benjamin Poirier
> Sent: Tuesday, August 13, 2013 5:07 PM
> To: Ariel Elior
> Cc: Dmitry Kravkov; davem@davemloft.net; netdev@vger.kernel.org; Eilon
> Greenstein
> Subject: Re: [PATCH net v5 0/5] bnx2x: fixes
> 
> On 2013/08/13 12:38, Ariel Elior wrote:
> > > I'm confused. Wasn't "[PATCH net v4 1/6] bnx2x: properly initialize
> > > statistic counters" supposed to fix a race condition? According to
> > > earlier communication with Ariel:
> > > 	In this issue a race condition at driver startup causes a second
> > > 	statistics query to be sent before the first one completes,
> > > 	resulting in a firmware assert and a stuck chip. A patch was
> > > 	sent upstream fixing this:
> > > 	http://patchwork.ozlabs.org/patch/264810/
> >
> > As I explicitly mentioned in the communique which you quoted above,
> the patch was sent but not yet accepted.
> > This is precisely the upstream process - patches are being sent, reviewed
> and sometimes rejected and revised.
> > If you have further questions please address them to me - the technical
> forum is no place for this kind of discussion.
> > Thanks,
> > Ariel
> >
> 
> It's a technical question about a patch which was sent upstream. Where
> should the discussion happen if not upstream?
> 
> Let me rephrase my question:
> 
> I'm confused. I thought that "[PATCH net v4 1/6] bnx2x: properly initialize
> statistic counters" was meant to fix a race condition at driver startup which
> causes a second statistics query to be sent before the first one completes,
> resulting in a firmware assert and a stuck chip. Am I mistaken and there is no
> such race condition, or is it addressed by the other patches in this series?
> 
There is such condition, but it's not caused by wrongly initialized counted -
the initialization done in a correct way. Patch "[PATCH net v5 1/5] bnx2x: protect
different statistics flows"  - prevents from two outstanding queries to be sent
simultaneously.

Thanks
Dmitry

^ permalink raw reply

* Re: the congestion window rfc2001
From: Yuchung Cheng @ 2013-08-13 14:29 UTC (permalink / raw)
  To: Dong Fang; +Cc: netdev
In-Reply-To: <520AC2AD.1030306@gmail.com>

Please ask those questions on more relevant list such as
tcpm@ietf.org. This list is for discussing Linux kernel networking
development, not generic TCP protocol.

On Tue, Aug 13, 2013 at 4:35 PM, Dong Fang <yp.fangdong@gmail.com> wrote:
> hi, all
>
>
> http://tools.ietf.org/html/rfc2001
>
>
>    1.  When the third duplicate ACK in a row is received, set ssthresh
>        to one-half the current congestion window, cwnd, but no less
>        than two segments.  Retransmit the missing segment.  Set cwnd =
>        ssthresh + 3 times the segment size.  This inflates the
> -- what is the meaning of '3'
>
>        congestion window by the number of segments that have left the
>        network and which the other end has cached (3).
>
>    2.  Each time another duplicate ACK arrives, increment cwnd by the
>        segment size.  This inflates the congestion window for the
>        additional segment that has left the network.
> -- why do this
>
>        Transmit a packet, if allowed by the new value of cwnd.
>
>    3.  When the next ACK arrives that acknowledges new data, set cwnd
>        to ssthresh (the value set in step 1).  This ACK should be the
>        acknowledgment of the retransmission from step 1, one round-trip
>        time after the retransmission.  Additionally, this ACK should
>        acknowledge all the intermediate segments sent between the lost
>        packet and the receipt of the first duplicate ACK.  This step is
>        congestion avoidance, since TCP is down to one-half the rate it
>        was at when the packet was lost.
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH 1/2] ipv6: do not disable temp_address when reaching max_address
From: Sergei Shtylyov @ 2013-08-13 14:31 UTC (permalink / raw)
  To: Ding Tianhong
  Cc: David S. Miller, Alexey Kuznetsov, James Morris,
	Hideaki YOSHIFUJI, Netdev, Patrick McHardy
In-Reply-To: <5209CEE2.70908@huawei.com>

Hello.

On 08/13/2013 10:14 AM, Ding Tianhong wrote:

> A LAN user can remotely disable temporary address which may lead
> to privacy violatins and information disclosure.

> The reason is that the linux kernel uses the 'ipv6.max_addresses'
> option to specify how many ipv6 addresses and interface may have.
> The 'ipv6.regen_max_retry' (default value 3) option specifies
> how many times the kernel will try to create a new address.

> But the kernel is not distinguish between the event of reaching
> max_addresses for an interface and failing to generate a new address.
> the kernel disable the temporary address after regenerate a new
> address 'regen_max_retry' times.

> According RFC4941 3.3.7:

> ---------------------------------------

> If DAD indicates the address is already in use,
> the node must generate a new randomized interface
> identifier as described in section 3.2 above, and
> repeat the previous steps as appropriate up to
> TEMP_IDGEN_RETRIES times.

> If after TEMP_IDGEN_RETRIES consecutive attempts no
> non-unique address was generated, the node must log
> a system error and must not attempt to generate
> temporary address for that interface.

> ------------------------------------------

> RFC4941 3.3.7 specifies that disabling the temp_address must happen
> upon the address is already in use, not reach the max_address,
> So we have to check the return err and distinguish the correct retry path.

> This fixes CVE-2013-0343

> Signed-off-by: Ding Tianhong <dingtianhong@huawei.com>
> Tested-by: Wang Weidong <wangweidong1@huawei.com>
> Cc: David S. Miller <davem@davemloft.net>
> ---
>   net/ipv6/addrconf.c | 25 +++++++++++++++++++++----
>   1 file changed, 21 insertions(+), 4 deletions(-)

> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
> index da4241c..99f9fd5 100644
> --- a/net/ipv6/addrconf.c
> +++ b/net/ipv6/addrconf.c
> @@ -1134,10 +1134,27 @@ retry:
[...]
> +		if (PTR_ERR(ift) == -EEXIST) {
> +			pr_info("%s: retry temporary address regeneration\n", __func__);
> +			tmpaddr = &addr;
> +			write_lock(&idev->lock);
> +			goto retry;
> +		} else
> +			goto out;

    According to CodingStyle, both arms of the *if* statement should have {} 
if one has it.

WBR, Sergei

^ permalink raw reply

* tun always return NETDEV_TX_OK, why?
From: Yannick Koehler @ 2013-08-13 14:39 UTC (permalink / raw)
  To: netdev

Hello,

  I hit a problem recently with the tun interface, it looks like when
this interface reach its txqueuelen it will then drop the packet and
return NETDEV_TX_OK unconditionally.

 That, from my little understanding of the netdev framework, appears
to be wrong and will simply eat up any pending buffer and discard them
until the queue frees itself.  That seems to be against the flow
control design in the tx queue system of the kernel.

  So, is this a bug or a misunderstanding?  Would it be ok for tun to
return NETDEV_TX_BUSY when the txqueuelen is reach and call
netif_stop_queue() so that the layer above stop sending frame to this
interface until it can cope it's current queue content?

-- 
Yannick Koehler

^ permalink raw reply

* Re: [PATCH net-next 2/3] net/usb/r8152: enable tx checksum
From: Sergei Shtylyov @ 2013-08-13 14:39 UTC (permalink / raw)
  To: Hayes Wang; +Cc: netdev, linux-kernel, linux-usb
In-Reply-To: <1376378913-879-2-git-send-email-hayeswang@realtek.com>

Hello.

On 08/13/2013 11:28 AM, Hayes Wang wrote:

> Enable tx checksum.

> Signed-off-by: Hayes Wang <hayeswang@realtek.com>
> ---
>   drivers/net/usb/r8152.c | 63 +++++++++++++++++++++++++++++++++++++++++++++----
>   1 file changed, 58 insertions(+), 5 deletions(-)

> diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
> index c6c5aa2..5d9d949 100644
> --- a/drivers/net/usb/r8152.c
> +++ b/drivers/net/usb/r8152.c
[...]
> @@ -964,6 +971,51 @@ err1:
>   	return -ENOMEM;
>   }
>
> +static void
> +r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc, struct sk_buff *skb)
> +{
[...]
> +		if (ip_protocol == IPPROTO_TCP) {
> +			opts2 |= TCP_CS;
> +			opts2 |= (skb_transport_offset(skb) & 0x7fff) << 17;
> +		} else if (ip_protocol == IPPROTO_UDP) {
> +			opts2 |= UDP_CS;
> +		} else
> +			WARN_ON_ONCE(1);

    Stange, why *else if* branch has {} and *else* don't. It should, according 
to Documentation/CodingStyle.

> +
> +		desc->opts2 = cpu_to_le32(opts2);
> +	}
> +}
> +

WBR, Sergei

^ permalink raw reply

* [PATCH] phy: micrel: Add definitions for common Micrel PHY registers
From: dinguyen @ 2013-08-13 14:59 UTC (permalink / raw)
  To: dinh.linux
  Cc: Dinh Nguyen, David S. Miller, Andrew Victor,
	Jean-Christophe Plagniol-Villard, Shawn Guo, Nicolas Ferre,
	netdev, linux-arm-kernel
In-Reply-To: <1376405940-17141-1-git-send-email-dinguyen@altera.com>

From: Dinh Nguyen <dinguyen@altera.com>

Add defines for common Micrel PHY setups so that other platforms
can use them. Update imx61 and sama5 hardware to use the micrel_phy.h
PHY defines.

Also add support for the KSZ9021RLRN PHY.

Signed-off-by: Dinh Nguyen <dinguyen@altera.com>
Acked-by: Shawn Guo <shawn.guo@linaro.org>
Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Cc: David S. Miller <davem@davemloft.net>
CC: Andrew Victor <linux@maxim.org.za>
CC: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
Cc: Shawn Guo <shawn.guo@linaro.org>
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Cc: netdev@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
---
 arch/arm/mach-at91/board-dt-sama5.c |   17 ++++++-----------
 arch/arm/mach-imx/mach-imx6q.c      |   13 ++++++++-----
 include/linux/micrel_phy.h          |    6 ++++++
 3 files changed, 20 insertions(+), 16 deletions(-)

diff --git a/arch/arm/mach-at91/board-dt-sama5.c b/arch/arm/mach-at91/board-dt-sama5.c
index ad95f6a..bf00d15 100644
--- a/arch/arm/mach-at91/board-dt-sama5.c
+++ b/arch/arm/mach-at91/board-dt-sama5.c
@@ -42,20 +42,15 @@ static int ksz9021rn_phy_fixup(struct phy_device *phy)
 {
 	int value;
 
-#define GMII_RCCPSR	260
-#define GMII_RRDPSR	261
-#define GMII_ERCR	11
-#define GMII_ERDWR	12
-
 	/* Set delay values */
-	value = GMII_RCCPSR | 0x8000;
-	phy_write(phy, GMII_ERCR, value);
+	value = MICREL_KSZ9021_RGMII_CLK_CTRL_PAD_SCEW | 0x8000;
+	phy_write(phy, MICREL_KSZ9021_EXTREG_CTRL, value);
 	value = 0xF2F4;
-	phy_write(phy, GMII_ERDWR, value);
-	value = GMII_RRDPSR | 0x8000;
-	phy_write(phy, GMII_ERCR, value);
+	phy_write(phy, MICREL_KSZ9021_EXTREG_DATA_WRITE, value);
+	value = MICREL_KSZ9021_RGMII_RX_DATA_PAD_SCEW | 0x8000;
+	phy_write(phy, MICREL_KSZ9021_EXTREG_CTRL, value);
 	value = 0x2222;
-	phy_write(phy, GMII_ERDWR, value);
+	phy_write(phy, MICREL_KSZ9021_EXTREG_DATA_WRITE, value);
 
 	return 0;
 }
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index 7be13f8..c8d7814 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -103,13 +103,16 @@ static int ksz9021rn_phy_fixup(struct phy_device *phydev)
 {
 	if (IS_BUILTIN(CONFIG_PHYLIB)) {
 		/* min rx data delay */
-		phy_write(phydev, 0x0b, 0x8105);
-		phy_write(phydev, 0x0c, 0x0000);
+		phy_write(phydev, MICREL_KSZ9021_EXTREG_CTRL,
+			0x8000 | MICREL_KSZ9021_RGMII_RX_DATA_PAD_SCEW);
+		phy_write(phydev, MICREL_KSZ9021_EXTREG_DATA_WRITE, 0x0000);
 
 		/* max rx/tx clock delay, min rx/tx control delay */
-		phy_write(phydev, 0x0b, 0x8104);
-		phy_write(phydev, 0x0c, 0xf0f0);
-		phy_write(phydev, 0x0b, 0x104);
+		phy_write(phydev, MICREL_KSZ9021_EXTREG_CTRL,
+			0x8000 | MICREL_KSZ9021_RGMII_CLK_CTRL_PAD_SCEW);
+		phy_write(phydev, MICREL_KSZ9021_EXTREG_DATA_WRITE, 0xf0f0);
+		phy_write(phydev, MICREL_KSZ9021_EXTREG_CTRL,
+			MICREL_KSZ9021_RGMII_CLK_CTRL_PAD_SCEW);
 	}
 
 	return 0;
diff --git a/include/linux/micrel_phy.h b/include/linux/micrel_phy.h
index 8752dbb..ad05ce6 100644
--- a/include/linux/micrel_phy.h
+++ b/include/linux/micrel_phy.h
@@ -17,6 +17,7 @@
 
 #define PHY_ID_KSZ8873MLL	0x000e7237
 #define PHY_ID_KSZ9021		0x00221610
+#define PHY_ID_KSZ9021RLRN	0x00221611
 #define PHY_ID_KS8737		0x00221720
 #define PHY_ID_KSZ8021		0x00221555
 #define PHY_ID_KSZ8031		0x00221556
@@ -35,4 +36,9 @@
 /* struct phy_device dev_flags definitions */
 #define MICREL_PHY_50MHZ_CLK	0x00000001
 
+#define MICREL_KSZ9021_EXTREG_CTRL	0xB
+#define MICREL_KSZ9021_EXTREG_DATA_WRITE	0xC
+#define MICREL_KSZ9021_RGMII_CLK_CTRL_PAD_SCEW	0x104
+#define MICREL_KSZ9021_RGMII_RX_DATA_PAD_SCEW	0x105
+
 #endif /* _MICREL_PHY_H */
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH] phy: micrel: Add definitions for common Micrel PHY registers
From: dinguyen @ 2013-08-13 14:58 UTC (permalink / raw)
  To: dinh.linux
  Cc: Dinh Nguyen, Shawn Guo, Nicolas Ferre, David S. Miller,
	Andrew Victor, Jean-Christophe Plagniol-Villard, netdev,
	linux-arm-kernel

From: Dinh Nguyen <dinguyen@altera.com>

Hi Shawn,

Can you apply this patch to your tree for 3.12?

Thanks,

Dinh Nguyen (1):
  phy: micrel: Add definitions for common Micrel PHY registers

 arch/arm/mach-at91/board-dt-sama5.c |   17 ++++++-----------
 arch/arm/mach-imx/mach-imx6q.c      |   13 ++++++++-----
 include/linux/micrel_phy.h          |    6 ++++++
 3 files changed, 20 insertions(+), 16 deletions(-)

Cc: Shawn Guo <shawn.guo@linaro.org>
Cc: Nicolas Ferre <nicolas.ferre@atmel.com>
Cc: David S. Miller <davem@davemloft.net>
CC: Andrew Victor <linux@maxim.org.za>
CC: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
Cc: netdev@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org

-- 
1.7.9.5

^ permalink raw reply

* question about drivers/net/ethernet/nxp/lpc_eth.c
From: Julia Lawall @ 2013-08-13 15:01 UTC (permalink / raw)
  To: grant.likely, rob.herring, netdev, linux-kernel, devicetree

I wonder why drivers/net/ethernet/nxp/lpc_eth.c uses dev_alloc_skb in the
function __lpc_handle_recv, rather than netdev_alloc_skb?  The difference
seems to be only that with dev_alloc_skb, the dev field of the skb is
initialized to NULL, rather than to a net_device, but this function seems
to have a net_device value available, so I wonder why it is not used?

thanks,
julia

^ permalink raw reply

* Re: [PATCH net-next 1/3] net/usb/r8152: support aggregation
From: Oliver Neukum @ 2013-08-13 15:17 UTC (permalink / raw)
  To: hayeswang; +Cc: netdev, linux-kernel, linux-usb
In-Reply-To: <9E410853D1BD483E9479C175D5E72EB6@realtek.com.tw>

On Tue, 2013-08-13 at 20:32 +0800, hayeswang wrote:
>  Oliver Neukum [mailto:oneukum@suse.de] 
> > Sent: Tuesday, August 13, 2013 4:49 PM
> > To: Hayeswang
> > Cc: netdev@vger.kernel.org; linux-kernel@vger.kernel.org; 
> > linux-usb@vger.kernel.org
> > Subject: Re: [PATCH net-next 1/3] net/usb/r8152: support aggregation
> > 
> [...]
> > > +               len_used = 0;
> > > +               rx_desc = agg->head;
> > > +               rx_data = agg->head;
> > > +               smp_wmb();
> > > +               pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK;
> > > +               len_used += sizeof(struct rx_desc) + pkt_len;
> > > +
> > > +               while (urb->actual_length >= len_used) {
> > > +                       if (pkt_len < ETH_ZLEN)
> > > +                               break;
> > > +
> > > +                       pkt_len -= 4; /* CRC */
> > > +                       rx_data += sizeof(struct rx_desc);
> > > +
> > > +                       skb = netdev_alloc_skb_ip_align(netdev,
> > > pkt_len);
> > > +                       if (!skb) {
> > > +                               stats->rx_dropped++;
> > > +                               break;
> > > +                       }
> > > +                       memcpy(skb->data, rx_data, pkt_len);
> > > +                       skb_put(skb, pkt_len);
> > > +                       skb->protocol = eth_type_trans(skb, netdev);
> > > +                       netif_rx(skb);
> > > +                       stats->rx_packets++;
> > > +                       stats->rx_bytes += pkt_len;
> > > +
> > > +                       rx_data = rx_agg_align(rx_data + 
> > pkt_len + 4);
> > > +                       rx_desc = (struct rx_desc *)rx_data;
> > > +                       smp_wmb();
> > 
> > Against what is the memory barrier?
> 
> Excuse me. I don't understand your question. Do you mean the function should not
> be used here?

I don't understand what problem the function is supposed to fix. As long
as I don't understand it I cannot say for sure whether it is correct.
There seems no obvious reason for a memory barrier, but there may be a
hidden reason I don't see.

	Regards
		Oliver

^ permalink raw reply

* question about drivers/net/ethernet/sgi
From: Julia Lawall @ 2013-08-13 15:43 UTC (permalink / raw)
  To: ralf, linux-mips, netdev

The files in drivers/net/ethernet/sgi (meth.c and ioc3-eth.c) both use
alloc_skb.  Is there a reason why they do not use netdev_alloc_skb, like
most other ethernet drivers?

thanks,
julia

^ permalink raw reply

* [PATCH net-next v2 0/4] ipip/ip6tnl: allow to switch netns during encap/decap
From: Nicolas Dichtel @ 2013-08-13 15:51 UTC (permalink / raw)
  To: netdev; +Cc: davem, ebiederm, bcrl, ravi.mlists, bhutchings, eric.dumazet
In-Reply-To: <20130704.145621.2060744817757546493.davem@davemloft.net>


This serie is a follow up of the previous serie witch adds this functionality
for sit tunnels.

The goal is to add x-netns support for the module ipip and ip6_tunnel, ie the
encapsulation addresses and the network device are not owned by the same
namespace.

Note that the two first patches are cleanup.

Example to configure an ipip tunnel:

modprobe ipip
ip netns add netns1
ip link add ipip1 type ipip remote 10.16.0.121 local 10.16.0.249
ip l s ipip1 netns netns1
ip netns exec netns1 ip l s lo up
ip netns exec netns1 ip l s ipip1 up
ip netns exec netns1 ip a a dev ipip1 192.168.2.123 remote 192.168.2.121

or an ip6_tunnel:

modprobe ip6_tunnel
ip netns add netns1
ip link add ip6tnl1 type ip6tnl remote 2001:660:3008:c1c3::121 local 2001:660:3008:c1c3::123
ip l s ip6tnl1 netns netns1
ip netns exec netns1 ip l s lo up
ip netns exec netns1 ip l s ip6tnl1 up
ip netns exec netns1 ip a a dev ip6tnl1 192.168.1.123 remote 192.168.1.121
ip netns exec netns1 ip -6 a a dev ip6tnl1 2001:1235::123 remote 2001:1235::121

v2: remove the patch 1/3 of the v1 serie (already included)
    use net_eq()
    add patch 1/4 and 2/4

 include/net/ip6_tunnel.h |  1 +
 include/net/ip_tunnels.h |  2 +-
 net/core/dev.c           |  6 +++---
 net/ipv4/ip_gre.c        |  4 ++--
 net/ipv4/ip_tunnel.c     | 52 ++++++++++++++++++++++++++++++------------------
 net/ipv4/ip_vti.c        |  2 +-
 net/ipv4/ipip.c          |  3 +--
 net/ipv6/ip6_gre.c       |  5 +++++
 net/ipv6/ip6_tunnel.c    | 41 ++++++++++++++++++++++++++++----------
 net/ipv6/sit.c           |  6 +++---
 10 files changed, 81 insertions(+), 41 deletions(-)

Comments are welcome.

Regards,
Nicolas

^ permalink raw reply

* [PATCH net-next v2 1/4] dev: move skb_scrub_packet() after eth_type_trans()
From: Nicolas Dichtel @ 2013-08-13 15:51 UTC (permalink / raw)
  To: netdev
  Cc: davem, ebiederm, bcrl, ravi.mlists, bhutchings, eric.dumazet,
	Nicolas Dichtel
In-Reply-To: <1376409072-6414-1-git-send-email-nicolas.dichtel@6wind.com>

skb_scrub_packet() was called before eth_type_trans() to let eth_type_trans()
set pkt_type.

In fact, we should force pkt_type to PACKET_HOST, so move the call after
eth_type_trans().

Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
 net/core/dev.c       | 6 +++---
 net/ipv4/ip_tunnel.c | 7 ++++---
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index 58eb802584b9..1ed2b66a10a6 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1691,13 +1691,13 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb)
 		kfree_skb(skb);
 		return NET_RX_DROP;
 	}
-	skb_scrub_packet(skb);
 	skb->protocol = eth_type_trans(skb, dev);
 
 	/* eth_type_trans() can set pkt_type.
-	 * clear pkt_type _after_ calling eth_type_trans()
+	 * call skb_scrub_packet() after it to clear pkt_type _after_ calling
+	 * eth_type_trans().
 	 */
-	skb->pkt_type = PACKET_HOST;
+	skb_scrub_packet(skb);
 
 	return netif_rx(skb);
 }
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index 9fdf8a6d95f3..fbc1094964bf 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -454,15 +454,16 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
 	tstats->rx_bytes += skb->len;
 	u64_stats_update_end(&tstats->syncp);
 
-	if (tunnel->net != dev_net(tunnel->dev))
-		skb_scrub_packet(skb);
-
 	if (tunnel->dev->type == ARPHRD_ETHER) {
 		skb->protocol = eth_type_trans(skb, tunnel->dev);
 		skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
 	} else {
 		skb->dev = tunnel->dev;
 	}
+
+	if (tunnel->net != dev_net(tunnel->dev))
+		skb_scrub_packet(skb);
+
 	gro_cells_receive(&tunnel->gro_cells, skb);
 	return 0;
 
-- 
1.8.2.1

^ permalink raw reply related

* [PATCH net-next v2 4/4] ip6tnl: add x-netns support
From: Nicolas Dichtel @ 2013-08-13 15:51 UTC (permalink / raw)
  To: netdev
  Cc: davem, ebiederm, bcrl, ravi.mlists, bhutchings, eric.dumazet,
	Nicolas Dichtel
In-Reply-To: <1376409072-6414-1-git-send-email-nicolas.dichtel@6wind.com>

This patch allows to switch the netns when packet is encapsulated or
decapsulated. In other word, the encapsulated packet is received in a netns,
where the lookup is done to find the tunnel. Once the tunnel is found, the
packet is decapsulated and injecting into the corresponding interface which
stands to another netns.

When one of the two netns is removed, the tunnel is destroyed.

Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
 include/net/ip6_tunnel.h |  1 +
 net/ipv6/ip6_gre.c       |  5 +++++
 net/ipv6/ip6_tunnel.c    | 41 +++++++++++++++++++++++++++++++----------
 3 files changed, 37 insertions(+), 10 deletions(-)

diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h
index 4da5de10d1d4..2265b0bf97e5 100644
--- a/include/net/ip6_tunnel.h
+++ b/include/net/ip6_tunnel.h
@@ -36,6 +36,7 @@ struct __ip6_tnl_parm {
 struct ip6_tnl {
 	struct ip6_tnl __rcu *next;	/* next tunnel in list */
 	struct net_device *dev;	/* virtual device associated with tunnel */
+	struct net *net;	/* netns for packet i/o */
 	struct __ip6_tnl_parm parms;	/* tunnel configuration parameters */
 	struct flowi fl;	/* flowi template for xmit */
 	struct dst_entry *dst_cache;    /* cached dst */
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index ecd60733e5e2..f2d0a42f8057 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -335,6 +335,7 @@ static struct ip6_tnl *ip6gre_tunnel_locate(struct net *net,
 	dev->rtnl_link_ops = &ip6gre_link_ops;
 
 	nt->dev = dev;
+	nt->net = dev_net(dev);
 	ip6gre_tnl_link_config(nt, 1);
 
 	if (register_netdevice(dev) < 0)
@@ -1255,6 +1256,7 @@ static int ip6gre_tunnel_init(struct net_device *dev)
 	tunnel = netdev_priv(dev);
 
 	tunnel->dev = dev;
+	tunnel->net = dev_net(dev);
 	strcpy(tunnel->parms.name, dev->name);
 
 	memcpy(dev->dev_addr, &tunnel->parms.laddr, sizeof(struct in6_addr));
@@ -1275,6 +1277,7 @@ static void ip6gre_fb_tunnel_init(struct net_device *dev)
 	struct ip6_tnl *tunnel = netdev_priv(dev);
 
 	tunnel->dev = dev;
+	tunnel->net = dev_net(dev);
 	strcpy(tunnel->parms.name, dev->name);
 
 	tunnel->hlen		= sizeof(struct ipv6hdr) + 4;
@@ -1450,6 +1453,7 @@ static int ip6gre_tap_init(struct net_device *dev)
 	tunnel = netdev_priv(dev);
 
 	tunnel->dev = dev;
+	tunnel->net = dev_net(dev);
 	strcpy(tunnel->parms.name, dev->name);
 
 	ip6gre_tnl_link_config(tunnel, 1);
@@ -1501,6 +1505,7 @@ static int ip6gre_newlink(struct net *src_net, struct net_device *dev,
 		eth_hw_addr_random(dev);
 
 	nt->dev = dev;
+	nt->net = dev_net(dev);
 	ip6gre_tnl_link_config(nt, !tb[IFLA_MTU]);
 
 	/* Can use a lockless transmit, unless we generate output sequences */
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 1e55866cead7..cc3bb201b8b0 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -315,6 +315,7 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct __ip6_tnl_parm *p)
 
 	t = netdev_priv(dev);
 	t->parms = *p;
+	t->net = dev_net(dev);
 	err = ip6_tnl_create2(dev);
 	if (err < 0)
 		goto failed_free;
@@ -374,7 +375,7 @@ static void
 ip6_tnl_dev_uninit(struct net_device *dev)
 {
 	struct ip6_tnl *t = netdev_priv(dev);
-	struct net *net = dev_net(dev);
+	struct net *net = t->net;
 	struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
 
 	if (dev == ip6n->fb_tnl_dev)
@@ -741,7 +742,7 @@ int ip6_tnl_rcv_ctl(struct ip6_tnl *t,
 {
 	struct __ip6_tnl_parm *p = &t->parms;
 	int ret = 0;
-	struct net *net = dev_net(t->dev);
+	struct net *net = t->net;
 
 	if ((p->flags & IP6_TNL_F_CAP_RCV) ||
 	    ((p->flags & IP6_TNL_F_CAP_PER_PACKET) &&
@@ -827,6 +828,9 @@ static int ip6_tnl_rcv(struct sk_buff *skb, __u16 protocol,
 		tstats->rx_packets++;
 		tstats->rx_bytes += skb->len;
 
+		if (!net_eq(t->net, dev_net(t->dev)))
+			skb_scrub_packet(skb);
+
 		netif_rx(skb);
 
 		rcu_read_unlock();
@@ -895,7 +899,7 @@ int ip6_tnl_xmit_ctl(struct ip6_tnl *t)
 {
 	struct __ip6_tnl_parm *p = &t->parms;
 	int ret = 0;
-	struct net *net = dev_net(t->dev);
+	struct net *net = t->net;
 
 	if (p->flags & IP6_TNL_F_CAP_XMIT) {
 		struct net_device *ldev = NULL;
@@ -945,8 +949,8 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
 			 int encap_limit,
 			 __u32 *pmtu)
 {
-	struct net *net = dev_net(dev);
 	struct ip6_tnl *t = netdev_priv(dev);
+	struct net *net = t->net;
 	struct net_device_stats *stats = &t->dev->stats;
 	struct ipv6hdr *ipv6h = ipv6_hdr(skb);
 	struct ipv6_tel_txoption opt;
@@ -996,6 +1000,9 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
 		goto tx_err_dst_release;
 	}
 
+	if (!net_eq(t->net, dev_net(dev)))
+		skb_scrub_packet(skb);
+
 	/*
 	 * Okay, now see if we can stuff it in the buffer as-is.
 	 */
@@ -1202,7 +1209,7 @@ static void ip6_tnl_link_config(struct ip6_tnl *t)
 		int strict = (ipv6_addr_type(&p->raddr) &
 			      (IPV6_ADDR_MULTICAST|IPV6_ADDR_LINKLOCAL));
 
-		struct rt6_info *rt = rt6_lookup(dev_net(dev),
+		struct rt6_info *rt = rt6_lookup(t->net,
 						 &p->raddr, &p->laddr,
 						 p->link, strict);
 
@@ -1251,7 +1258,7 @@ ip6_tnl_change(struct ip6_tnl *t, const struct __ip6_tnl_parm *p)
 
 static int ip6_tnl_update(struct ip6_tnl *t, struct __ip6_tnl_parm *p)
 {
-	struct net *net = dev_net(t->dev);
+	struct net *net = t->net;
 	struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
 	int err;
 
@@ -1463,7 +1470,6 @@ static void ip6_tnl_dev_setup(struct net_device *dev)
 		dev->mtu-=8;
 	dev->flags |= IFF_NOARP;
 	dev->addr_len = sizeof(struct in6_addr);
-	dev->features |= NETIF_F_NETNS_LOCAL;
 	dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
 }
 
@@ -1479,6 +1485,7 @@ ip6_tnl_dev_init_gen(struct net_device *dev)
 	struct ip6_tnl *t = netdev_priv(dev);
 
 	t->dev = dev;
+	t->net = dev_net(dev);
 	dev->tstats = alloc_percpu(struct pcpu_tstats);
 	if (!dev->tstats)
 		return -ENOMEM;
@@ -1596,9 +1603,9 @@ static int ip6_tnl_newlink(struct net *src_net, struct net_device *dev,
 static int ip6_tnl_changelink(struct net_device *dev, struct nlattr *tb[],
 			      struct nlattr *data[])
 {
-	struct ip6_tnl *t;
+	struct ip6_tnl *t = netdev_priv(dev);
 	struct __ip6_tnl_parm p;
-	struct net *net = dev_net(dev);
+	struct net *net = t->net;
 	struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
 
 	if (dev == ip6n->fb_tnl_dev)
@@ -1699,14 +1706,24 @@ static struct xfrm6_tunnel ip6ip6_handler __read_mostly = {
 
 static void __net_exit ip6_tnl_destroy_tunnels(struct ip6_tnl_net *ip6n)
 {
+	struct net *net = dev_net(ip6n->fb_tnl_dev);
+	struct net_device *dev, *aux;
 	int h;
 	struct ip6_tnl *t;
 	LIST_HEAD(list);
 
+	for_each_netdev_safe(net, dev, aux)
+		if (dev->rtnl_link_ops == &ip6_link_ops)
+			unregister_netdevice_queue(dev, &list);
+
 	for (h = 0; h < HASH_SIZE; h++) {
 		t = rtnl_dereference(ip6n->tnls_r_l[h]);
 		while (t != NULL) {
-			unregister_netdevice_queue(t->dev, &list);
+			/* If dev is in the same netns, it has already
+			 * been added to the list by the previous loop.
+			 */
+			if (!net_eq(dev_net(t->dev), net))
+				unregister_netdevice_queue(t->dev, &list);
 			t = rtnl_dereference(t->next);
 		}
 	}
@@ -1732,6 +1749,10 @@ static int __net_init ip6_tnl_init_net(struct net *net)
 	if (!ip6n->fb_tnl_dev)
 		goto err_alloc_dev;
 	dev_net_set(ip6n->fb_tnl_dev, net);
+	/* FB netdevice is special: we have one, and only one per netns.
+	 * Allowing to move it to another netns is clearly unsafe.
+	 */
+	ip6n->fb_tnl_dev->features |= NETIF_F_NETNS_LOCAL;
 
 	err = ip6_fb_tnl_dev_init(ip6n->fb_tnl_dev);
 	if (err < 0)
-- 
1.8.2.1

^ permalink raw reply related

* [PATCH net-next v2 2/4] ipv4 tunnels: use net_eq() helper to check netns
From: Nicolas Dichtel @ 2013-08-13 15:51 UTC (permalink / raw)
  To: netdev
  Cc: davem, ebiederm, bcrl, ravi.mlists, bhutchings, eric.dumazet,
	Nicolas Dichtel
In-Reply-To: <1376409072-6414-1-git-send-email-nicolas.dichtel@6wind.com>

It's better to use available helpers for these tests.

Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
 net/ipv4/ip_tunnel.c | 4 ++--
 net/ipv6/sit.c       | 6 +++---
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index fbc1094964bf..a351a003ee6b 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -461,7 +461,7 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb,
 		skb->dev = tunnel->dev;
 	}
 
-	if (tunnel->net != dev_net(tunnel->dev))
+	if (!net_eq(tunnel->net, dev_net(tunnel->dev)))
 		skb_scrub_packet(skb);
 
 	gro_cells_receive(&tunnel->gro_cells, skb);
@@ -614,7 +614,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
 		goto tx_error;
 	}
 
-	if (tunnel->net != dev_net(dev))
+	if (!net_eq(tunnel->net, dev_net(dev)))
 		skb_scrub_packet(skb);
 
 	if (tunnel->err_count > 0) {
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index a3437a4cd07e..f18f842ac893 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -621,7 +621,7 @@ static int ipip6_rcv(struct sk_buff *skb)
 		tstats->rx_packets++;
 		tstats->rx_bytes += skb->len;
 
-		if (tunnel->net != dev_net(tunnel->dev))
+		if (!net_eq(tunnel->net, dev_net(tunnel->dev)))
 			skb_scrub_packet(skb);
 		netif_rx(skb);
 
@@ -860,7 +860,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
 			tunnel->err_count = 0;
 	}
 
-	if (tunnel->net != dev_net(dev))
+	if (!net_eq(tunnel->net, dev_net(dev)))
 		skb_scrub_packet(skb);
 
 	/*
@@ -1589,7 +1589,7 @@ static void __net_exit sit_destroy_tunnels(struct sit_net *sitn, struct list_hea
 				/* If dev is in the same netns, it has already
 				 * been added to the list by the previous loop.
 				 */
-				if (dev_net(t->dev) != net)
+				if (!net_eq(dev_net(t->dev), net))
 					unregister_netdevice_queue(t->dev,
 								   head);
 				t = rtnl_dereference(t->next);
-- 
1.8.2.1

^ permalink raw reply related

* [PATCH net-next v2 3/4] ipip: add x-netns support
From: Nicolas Dichtel @ 2013-08-13 15:51 UTC (permalink / raw)
  To: netdev
  Cc: davem, ebiederm, bcrl, ravi.mlists, bhutchings, eric.dumazet,
	Nicolas Dichtel
In-Reply-To: <1376409072-6414-1-git-send-email-nicolas.dichtel@6wind.com>

This patch allows to switch the netns when packet is encapsulated or
decapsulated. In other word, the encapsulated packet is received in a netns,
where the lookup is done to find the tunnel. Once the tunnel is found, the
packet is decapsulated and injecting into the corresponding interface which
stands to another netns.

When one of the two netns is removed, the tunnel is destroyed.

Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
 include/net/ip_tunnels.h |  2 +-
 net/ipv4/ip_gre.c        |  4 ++--
 net/ipv4/ip_tunnel.c     | 43 ++++++++++++++++++++++++++++---------------
 net/ipv4/ip_vti.c        |  2 +-
 net/ipv4/ipip.c          |  3 +--
 5 files changed, 33 insertions(+), 21 deletions(-)

diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
index c6acd9f8f877..5a76f2bef822 100644
--- a/include/net/ip_tunnels.h
+++ b/include/net/ip_tunnels.h
@@ -102,7 +102,7 @@ void  ip_tunnel_dellink(struct net_device *dev, struct list_head *head);
 int ip_tunnel_init_net(struct net *net, int ip_tnl_net_id,
 		       struct rtnl_link_ops *ops, char *devname);
 
-void ip_tunnel_delete_net(struct ip_tunnel_net *itn);
+void ip_tunnel_delete_net(struct ip_tunnel_net *itn, struct rtnl_link_ops *ops);
 
 void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
 		    const struct iphdr *tnl_params, const u8 protocol);
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 1f6eab66f7ce..bc3a76521deb 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -534,7 +534,7 @@ static int __net_init ipgre_init_net(struct net *net)
 static void __net_exit ipgre_exit_net(struct net *net)
 {
 	struct ip_tunnel_net *itn = net_generic(net, ipgre_net_id);
-	ip_tunnel_delete_net(itn);
+	ip_tunnel_delete_net(itn, &ipgre_link_ops);
 }
 
 static struct pernet_operations ipgre_net_ops = {
@@ -767,7 +767,7 @@ static int __net_init ipgre_tap_init_net(struct net *net)
 static void __net_exit ipgre_tap_exit_net(struct net *net)
 {
 	struct ip_tunnel_net *itn = net_generic(net, gre_tap_net_id);
-	ip_tunnel_delete_net(itn);
+	ip_tunnel_delete_net(itn, &ipgre_tap_ops);
 }
 
 static struct pernet_operations ipgre_tap_net_ops = {
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index a351a003ee6b..a4d9126c7b51 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -350,7 +350,7 @@ static int ip_tunnel_bind_dev(struct net_device *dev)
 		struct flowi4 fl4;
 		struct rtable *rt;
 
-		rt = ip_route_output_tunnel(dev_net(dev), &fl4,
+		rt = ip_route_output_tunnel(tunnel->net, &fl4,
 					    tunnel->parms.iph.protocol,
 					    iph->daddr, iph->saddr,
 					    tunnel->parms.o_key,
@@ -365,7 +365,7 @@ static int ip_tunnel_bind_dev(struct net_device *dev)
 	}
 
 	if (!tdev && tunnel->parms.link)
-		tdev = __dev_get_by_index(dev_net(dev), tunnel->parms.link);
+		tdev = __dev_get_by_index(tunnel->net, tunnel->parms.link);
 
 	if (tdev) {
 		hlen = tdev->hard_header_len + tdev->needed_headroom;
@@ -654,7 +654,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
 		}
 	}
 
-	err = iptunnel_xmit(dev_net(dev), rt, skb,
+	err = iptunnel_xmit(tunnel->net, rt, skb,
 			    fl4.saddr, fl4.daddr, protocol,
 			    ip_tunnel_ecn_encap(tos, inner_iph, skb), ttl, df);
 	iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
@@ -821,11 +821,10 @@ static void ip_tunnel_dev_free(struct net_device *dev)
 
 void ip_tunnel_dellink(struct net_device *dev, struct list_head *head)
 {
-	struct net *net = dev_net(dev);
 	struct ip_tunnel *tunnel = netdev_priv(dev);
 	struct ip_tunnel_net *itn;
 
-	itn = net_generic(net, tunnel->ip_tnl_net_id);
+	itn = net_generic(tunnel->net, tunnel->ip_tnl_net_id);
 
 	if (itn->fb_tunnel_dev != dev) {
 		ip_tunnel_del(netdev_priv(dev));
@@ -855,6 +854,10 @@ int ip_tunnel_init_net(struct net *net, int ip_tnl_net_id,
 
 	rtnl_lock();
 	itn->fb_tunnel_dev = __ip_tunnel_create(net, ops, &parms);
+	/* FB netdevice is special: we have one, and only one per netns.
+	 * Allowing to move it to another netns is clearly unsafe.
+	 */
+	itn->fb_tunnel_dev->features |= NETIF_F_NETNS_LOCAL;
 	rtnl_unlock();
 
 	if (IS_ERR(itn->fb_tunnel_dev))
@@ -864,28 +867,39 @@ int ip_tunnel_init_net(struct net *net, int ip_tnl_net_id,
 }
 EXPORT_SYMBOL_GPL(ip_tunnel_init_net);
 
-static void ip_tunnel_destroy(struct ip_tunnel_net *itn, struct list_head *head)
+static void ip_tunnel_destroy(struct ip_tunnel_net *itn, struct list_head *head,
+			      struct rtnl_link_ops *ops)
 {
+	struct net *net = dev_net(itn->fb_tunnel_dev);
+	struct net_device *dev, *aux;
 	int h;
 
+	for_each_netdev_safe(net, dev, aux)
+		if (dev->rtnl_link_ops == ops)
+			unregister_netdevice_queue(dev, head);
+
 	for (h = 0; h < IP_TNL_HASH_SIZE; h++) {
 		struct ip_tunnel *t;
 		struct hlist_node *n;
 		struct hlist_head *thead = &itn->tunnels[h];
 
 		hlist_for_each_entry_safe(t, n, thead, hash_node)
-			unregister_netdevice_queue(t->dev, head);
+			/* If dev is in the same netns, it has already
+			 * been added to the list by the previous loop.
+			 */
+			if (!net_eq(dev_net(t->dev), net))
+				unregister_netdevice_queue(t->dev, head);
 	}
 	if (itn->fb_tunnel_dev)
 		unregister_netdevice_queue(itn->fb_tunnel_dev, head);
 }
 
-void ip_tunnel_delete_net(struct ip_tunnel_net *itn)
+void ip_tunnel_delete_net(struct ip_tunnel_net *itn, struct rtnl_link_ops *ops)
 {
 	LIST_HEAD(list);
 
 	rtnl_lock();
-	ip_tunnel_destroy(itn, &list);
+	ip_tunnel_destroy(itn, &list, ops);
 	unregister_netdevice_many(&list);
 	rtnl_unlock();
 }
@@ -929,23 +943,21 @@ EXPORT_SYMBOL_GPL(ip_tunnel_newlink);
 int ip_tunnel_changelink(struct net_device *dev, struct nlattr *tb[],
 			 struct ip_tunnel_parm *p)
 {
-	struct ip_tunnel *t, *nt;
-	struct net *net = dev_net(dev);
+	struct ip_tunnel *t;
 	struct ip_tunnel *tunnel = netdev_priv(dev);
+	struct net *net = tunnel->net;
 	struct ip_tunnel_net *itn = net_generic(net, tunnel->ip_tnl_net_id);
 
 	if (dev == itn->fb_tunnel_dev)
 		return -EINVAL;
 
-	nt = netdev_priv(dev);
-
 	t = ip_tunnel_find(itn, p, dev->type);
 
 	if (t) {
 		if (t->dev != dev)
 			return -EEXIST;
 	} else {
-		t = nt;
+		t = tunnel;
 
 		if (dev->type != ARPHRD_ETHER) {
 			unsigned int nflags = 0;
@@ -984,6 +996,7 @@ int ip_tunnel_init(struct net_device *dev)
 	}
 
 	tunnel->dev = dev;
+	tunnel->net = dev_net(dev);
 	strcpy(tunnel->parms.name, dev->name);
 	iph->version		= 4;
 	iph->ihl		= 5;
@@ -994,8 +1007,8 @@ EXPORT_SYMBOL_GPL(ip_tunnel_init);
 
 void ip_tunnel_uninit(struct net_device *dev)
 {
-	struct net *net = dev_net(dev);
 	struct ip_tunnel *tunnel = netdev_priv(dev);
+	struct net *net = tunnel->net;
 	struct ip_tunnel_net *itn;
 
 	itn = net_generic(net, tunnel->ip_tnl_net_id);
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c
index 79b263da4168..e805e7b3030e 100644
--- a/net/ipv4/ip_vti.c
+++ b/net/ipv4/ip_vti.c
@@ -318,7 +318,7 @@ static int __net_init vti_init_net(struct net *net)
 static void __net_exit vti_exit_net(struct net *net)
 {
 	struct ip_tunnel_net *itn = net_generic(net, vti_net_id);
-	ip_tunnel_delete_net(itn);
+	ip_tunnel_delete_net(itn, &vti_link_ops);
 }
 
 static struct pernet_operations vti_net_ops = {
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 51fc2a1dcdd3..87bd2952c733 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -286,7 +286,6 @@ static void ipip_tunnel_setup(struct net_device *dev)
 	dev->flags		= IFF_NOARP;
 	dev->iflink		= 0;
 	dev->addr_len		= 4;
-	dev->features		|= NETIF_F_NETNS_LOCAL;
 	dev->features		|= NETIF_F_LLTX;
 	dev->priv_flags		&= ~IFF_XMIT_DST_RELEASE;
 
@@ -437,7 +436,7 @@ static int __net_init ipip_init_net(struct net *net)
 static void __net_exit ipip_exit_net(struct net *net)
 {
 	struct ip_tunnel_net *itn = net_generic(net, ipip_net_id);
-	ip_tunnel_delete_net(itn);
+	ip_tunnel_delete_net(itn, &ipip_link_ops);
 }
 
 static struct pernet_operations ipip_net_ops = {
-- 
1.8.2.1

^ permalink raw reply related


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