* Re: [patch net-next] team: add support for non-ethernet devices
From: David Miller @ 2012-08-20 9:42 UTC (permalink / raw)
To: jiri; +Cc: netdev
In-Reply-To: <1345212048-1378-1-git-send-email-jiri@resnulli.us>
From: Jiri Pirko <jiri@resnulli.us>
Date: Fri, 17 Aug 2012 16:00:48 +0200
> This is resolved by two things:
> 1) allow dev_addr of different length than ETH_ALEN
> 2) during port add, check for dev->type and change it if necessary
>
> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Looks good, applied, thanks Jiri.
^ permalink raw reply
* Re: [PATCH 0/5] netfilter fixes for 3.6-rc
From: David Miller @ 2012-08-20 9:45 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel, netdev
In-Reply-To: <1345212573-3076-1-git-send-email-pablo@netfilter.org>
From: pablo@netfilter.org
Date: Fri, 17 Aug 2012 16:09:28 +0200
> The following five patches contain fixes for 3.6-rc, they are:
>
> * Two fixes for message parsing in the SIP conntrack helper, from
> Patrick McHardy.
>
> * One fix for the SIP helper introduced in the user-space cthelper
> infrastructure, from Patrick McHardy.
>
> * fix missing appropriate locking while modifying one conntrack entry
> from the nfqueue integration code, from myself.
>
> * fix possible access to uninitiliazed timer in the nf_conntrack
> expectation infrastructure, from myself.
>
> You can pull these changes from:
>
> git://1984.lsi.us.es/nf
Pulled, thanks Pablo.
^ permalink raw reply
* Re: [PATCH] caif: Do not dereference NULL in chnl_recv_cb()
From: David Miller @ 2012-08-20 9:48 UTC (permalink / raw)
To: sjur.brandeland; +Cc: jj, linux-kernel, netdev, daniel.martensson
In-Reply-To: <81C3A93C17462B4BBD7E272753C1057923B924D522@EXDCVYMBSTM005.EQ1STM.local>
From: Sjur BRENDELAND <sjur.brandeland@stericsson.com>
Date: Mon, 20 Aug 2012 08:33:35 +0200
>> In net/caif/chnl_net.c::chnl_recv_cb() we call skb_header_pointer()
>> which may return NULL, but we do not check for a NULL pointer before
>> dereferencing it.
>> This patch adds such a NULL check and properly free's allocated memory
>> and return an error (-EINVAL) on failure - much better than crashing..
>>
>> Signed-off-by: Jesper Juhl <jj@chaosbits.net>
>
> Thank you for fixing this, the patch looks good to me.
> Acked-by: Sjur Brændeland <sjur.brandeland@stericsson.com>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH] ipv4: Use netinet->inet_opt in inet_csk_route_child_sock()
From: David Miller @ 2012-08-20 9:51 UTC (permalink / raw)
To: christoph.paasch; +Cc: netdev
In-Reply-To: <1345239312-19266-1-git-send-email-christoph.paasch@uclouvain.be>
From: Christoph Paasch <christoph.paasch@uclouvain.be>
Date: Fri, 17 Aug 2012 23:35:12 +0200
> @@ -404,7 +404,7 @@ struct dst_entry *inet_csk_route_child_sock(struct sock *sk,
> {
> const struct inet_request_sock *ireq = inet_rsk(req);
> struct inet_sock *newinet = inet_sk(newsk);
> - struct ip_options_rcu *opt = ireq->opt;
> + struct ip_options_rcu *opt = rcu_dereference(newinet->inet_opt);
> struct net *net = sock_net(sk);
We're not inside of a rcu_read_lock() protected section, so this access
is not legitimate. If you enabled RCU lock debugging, you would have
triggered a warning in the kernel log.
^ permalink raw reply
* Re: [PATCH] net/stmmac: fix issue of clk_get for Loongson1B.
From: David Miller @ 2012-08-20 9:52 UTC (permalink / raw)
To: keguang.zhang; +Cc: netdev, linux-kernel, peppe.cavallaro
In-Reply-To: <1345284983-12610-1-git-send-email-keguang.zhang@gmail.com>
From: Kelvin Cheung <keguang.zhang@gmail.com>
Date: Sat, 18 Aug 2012 18:16:23 +0800
> When getting clock, give a chance to the CPUs without DT support,
> which use Common Clock Framework, such as Loongson1B.
>
> Signed-off-by: Kelvin Cheung <keguang.zhang@gmail.com>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH]: net: ipv6: fix oops in inet_putpeer()
From: David Miller @ 2012-08-20 9:58 UTC (permalink / raw)
To: kaber; +Cc: netdev
In-Reply-To: <Pine.GSO.4.63.1208181729020.7404@stinky-local.trash.net>
From: Patrick McHardy <kaber@trash.net>
Date: Sat, 18 Aug 2012 17:32:31 +0200 (MEST)
> The attached patch fixes an oops in inet_putpeer(). Please see the
> changelog entry for details.
>
> An alternative fix would be to check whether rt6_peer_ptr() returns
> NULL before invoking inet_putpeer(), but properly initializing the
> peer looks cleaner to me.
This is fine for now, applied, thanks Patrick.
There was a built-in assumption that xfrm_fill_dst() would run to
completion before we'd try to release these things, because there in
xfrm6_policy.c's xfrm6_fill_dst, we'd do the rt6_transfer_peer().
But that's obviously not the case if errors happen meanwhile.
^ permalink raw reply
* Re: [Patch] netconsole: remove a redundant netconsole_target_put()
From: David Miller @ 2012-08-20 10:00 UTC (permalink / raw)
To: amwang; +Cc: netdev, stable
In-Reply-To: <1345309340-15499-1-git-send-email-amwang@redhat.com>
From: Cong Wang <amwang@redhat.com>
Date: Sun, 19 Aug 2012 01:02:20 +0800
> This netconsole_target_put() is obviously redundant, and it
> causes a kernel segfault when removing a bridge device which has
> netconsole running on it.
>
> This is caused by:
>
> commit 8d8fc29d02a33e4bd5f4fa47823c1fd386346093
> Author: Amerigo Wang <amwang@redhat.com>
> Date: Thu May 19 21:39:10 2011 +0000
>
> netpoll: disable netpoll when enslave a device
>
> Cc: David Miller <davem@davemloft.net>
> (for all 3.x stable releases)
> Cc: stable@vger.kernel.org
> Signed-off-by: Cong Wang <amwang@redhat.com>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH] net/core/dev.c: fix kernel-doc warning
From: David Miller @ 2012-08-20 10:01 UTC (permalink / raw)
To: rdunlap; +Cc: netdev
In-Reply-To: <5030351C.8080000@xenotime.net>
From: Randy Dunlap <rdunlap@xenotime.net>
Date: Sat, 18 Aug 2012 17:36:44 -0700
> From: Randy Dunlap <rdunlap@xenotime.net>
>
> Fix kernel-doc warning:
>
> Warning(net/core/dev.c:5745): No description found for parameter 'dev'
>
> Signed-off-by: Randy Dunlap <rdunlap@xenotime.net>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH net v2] net: tcp: move sk_rx_dst_set call after tcp_create_openreq_child()
From: David Miller @ 2012-08-20 10:04 UTC (permalink / raw)
To: eric.dumazet; +Cc: ncardwell, netdev, edumazet
In-Reply-To: <1345383675.5158.202.camel@edumazet-glaptop>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Sun, 19 Aug 2012 15:41:15 +0200
> On Sun, 2012-08-19 at 09:30 -0400, Neal Cardwell wrote:
>> This commit removes the sk_rx_dst_set calls from
>> tcp_create_openreq_child(), because at that point the icsk_af_ops
>> field of ipv6_mapped TCP sockets has not been set to its proper final
>> value.
>>
>> Instead, to make sure we get the right sk_rx_dst_set variant
>> appropriate for the address family of the new connection, we have
>> tcp_v{4,6}_syn_recv_sock() directly call the appropriate function
>> shortly after the call to tcp_create_openreq_child() returns.
>>
>> This also moves inet6_sk_rx_dst_set() to avoid a forward declaration
>> with the new approach.
>>
>> Signed-off-by: Neal Cardwell <ncardwell@google.com>
>> Reported-by: Artem Savkov <artem.savkov@gmail.com>
>> Cc: Eric Dumazet <edumazet@google.com>
>> ---
>> net/ipv4/tcp_ipv4.c | 1 +
>> net/ipv4/tcp_minisocks.c | 2 --
>> net/ipv6/tcp_ipv6.c | 25 +++++++++++++------------
>> 3 files changed, 14 insertions(+), 14 deletions(-)
>
> Thanks Neal !
>
> Acked-by: Eric Dumazet <edumazet@google.com>
Applied, thanks everyone.
^ permalink raw reply
* Re: [RFC PATCH 0/5] net: socket bind to file descriptor introduced
From: Stanislav Kinsbursky @ 2012-08-20 10:18 UTC (permalink / raw)
To: Eric W. Biederman
Cc: tglx@linutronix.de, mingo@redhat.com, davem@davemloft.net,
hpa@zytor.com, thierry.reding@avionic-design.de,
bfields@redhat.com, eric.dumazet@gmail.com, Pavel Emelianov,
neilb@suse.de, netdev@vger.kernel.org, x86@kernel.org,
linux-kernel@vger.kernel.org, paul.gortmaker@windriver.com,
viro@zeniv.linux.org.uk, gorcunov@openvz.org,
akpm@linux-foundation.org, tim.c.chen@linux.intel.com,
devel@openvz.org
In-Reply-To: <87y5lf7d37.fsf@xmission.com>
16.08.2012 07:03, Eric W. Biederman пишет:
> Stanislav Kinsbursky <skinsbursky@parallels.com> writes:
>
>> This patch set introduces new socket operation and new system call:
>> sys_fbind(), which allows to bind socket to opened file.
>> File to bind to can be created by sys_mknod(S_IFSOCK) and opened by
>> open(O_PATH).
>>
>> This system call is especially required for UNIX sockets, which has name
>> lenght limitation.
>>
>> The following series implements...
>
> Hmm. I just realized this patchset is even sillier than I thought.
>
> Stanislav is the problem you are ultimately trying to solve nfs clients
> in a container connecting to the wrong user space rpciod?
>
Hi, Eric.
The problem you mentioned was the reason why I started to think about this.
But currently I believe, that limitations in unix sockets connect or bind should
be removed, because it will be useful it least for CRIU project.
> Aka net/sunrpc/xprtsock.c:xs_setup_local only taking an absolute path
> and then creating a delayed work item to actually open the unix domain
> socket?
>
> The straight correct and straight forward thing to do appears to be:
> - Capture the root from current->fs in xs_setup_local.
> - In xs_local_finish_connect change current->fs.root to the captured
> version of root before kernel_connect, and restore current->fs.root
> after kernel_connect.
>
> It might not be a bad idea to implement open on unix domain sockets in
> a filesystem as create(AF_LOCAL)+connect() which would allow you to
> replace __sock_create + kernel_connect with a simple file_open_root.
>
I like the idea of introducing new family (AF_LOCAL_AT for example) and new
sockaddr for connecting or binding from specified root. The only thing I'm
worrying is passing file descriptor to unix bind or connect routine. Because
this approach doesn't provide easy way to use such family and sockaddr in kernel
(like in NFS example).
> But I think the simple scheme of:
> struct path old_root;
> old_root = current->fs.root;
> kernel_connect(...);
> current->fs.root = old_root;
>
> Is more than sufficient and will remove the need for anything
> except a purely local change to get nfs clients to connect from
> containers.
>
That was my first idea. And probably it would be worth to change all fs_struct
to support sockets with relative path.
What do you think about it?
> Eric
>
--
Best regards,
Stanislav Kinsbursky
^ permalink raw reply
* [PATCH] tcp: fix possible socket refcount problem
From: Eric Dumazet @ 2012-08-20 10:22 UTC (permalink / raw)
To: Fengguang Wu; +Cc: David Miller, networking
In-Reply-To: <1345380682.5158.201.camel@edumazet-glaptop>
From: Eric Dumazet <edumazet@google.com>
Commit 6f458dfb40 (tcp: improve latencies of timer triggered events)
added bug leading to following trace :
[ 2866.131281] IPv4: Attempt to release TCP socket in state 1 ffff880019ec0000
[ 2866.131726]
[ 2866.132188] =========================
[ 2866.132281] [ BUG: held lock freed! ]
[ 2866.132281] 3.6.0-rc1+ #622 Not tainted
[ 2866.132281] -------------------------
[ 2866.132281] kworker/0:1/652 is freeing memory ffff880019ec0000-ffff880019ec0a1f, with a lock still held there!
[ 2866.132281] (sk_lock-AF_INET-RPC){+.+...}, at: [<ffffffff81903619>] tcp_sendmsg+0x29/0xcc6
[ 2866.132281] 4 locks held by kworker/0:1/652:
[ 2866.132281] #0: (rpciod){.+.+.+}, at: [<ffffffff81083567>] process_one_work+0x1de/0x47f
[ 2866.132281] #1: ((&task->u.tk_work)){+.+.+.}, at: [<ffffffff81083567>] process_one_work+0x1de/0x47f
[ 2866.132281] #2: (sk_lock-AF_INET-RPC){+.+...}, at: [<ffffffff81903619>] tcp_sendmsg+0x29/0xcc6
[ 2866.132281] #3: (&icsk->icsk_retransmit_timer){+.-...}, at: [<ffffffff81078017>] run_timer_softirq+0x1ad/0x35f
[ 2866.132281]
[ 2866.132281] stack backtrace:
[ 2866.132281] Pid: 652, comm: kworker/0:1 Not tainted 3.6.0-rc1+ #622
[ 2866.132281] Call Trace:
[ 2866.132281] <IRQ> [<ffffffff810bc527>] debug_check_no_locks_freed+0x112/0x159
[ 2866.132281] [<ffffffff818a0839>] ? __sk_free+0xfd/0x114
[ 2866.132281] [<ffffffff811549fa>] kmem_cache_free+0x6b/0x13a
[ 2866.132281] [<ffffffff818a0839>] __sk_free+0xfd/0x114
[ 2866.132281] [<ffffffff818a08c0>] sk_free+0x1c/0x1e
[ 2866.132281] [<ffffffff81911e1c>] tcp_write_timer+0x51/0x56
[ 2866.132281] [<ffffffff81078082>] run_timer_softirq+0x218/0x35f
[ 2866.132281] [<ffffffff81078017>] ? run_timer_softirq+0x1ad/0x35f
[ 2866.132281] [<ffffffff810f5831>] ? rb_commit+0x58/0x85
[ 2866.132281] [<ffffffff81911dcb>] ? tcp_write_timer_handler+0x148/0x148
[ 2866.132281] [<ffffffff81070bd6>] __do_softirq+0xcb/0x1f9
[ 2866.132281] [<ffffffff81a0a00c>] ? _raw_spin_unlock+0x29/0x2e
[ 2866.132281] [<ffffffff81a1227c>] call_softirq+0x1c/0x30
[ 2866.132281] [<ffffffff81039f38>] do_softirq+0x4a/0xa6
[ 2866.132281] [<ffffffff81070f2b>] irq_exit+0x51/0xad
[ 2866.132281] [<ffffffff81a129cd>] do_IRQ+0x9d/0xb4
[ 2866.132281] [<ffffffff81a0a3ef>] common_interrupt+0x6f/0x6f
[ 2866.132281] <EOI> [<ffffffff8109d006>] ? sched_clock_cpu+0x58/0xd1
[ 2866.132281] [<ffffffff81a0a172>] ? _raw_spin_unlock_irqrestore+0x4c/0x56
[ 2866.132281] [<ffffffff81078692>] mod_timer+0x178/0x1a9
[ 2866.132281] [<ffffffff818a00aa>] sk_reset_timer+0x19/0x26
[ 2866.132281] [<ffffffff8190b2cc>] tcp_rearm_rto+0x99/0xa4
[ 2866.132281] [<ffffffff8190dfba>] tcp_event_new_data_sent+0x6e/0x70
[ 2866.132281] [<ffffffff8190f7ea>] tcp_write_xmit+0x7de/0x8e4
[ 2866.132281] [<ffffffff818a565d>] ? __alloc_skb+0xa0/0x1a1
[ 2866.132281] [<ffffffff8190f952>] __tcp_push_pending_frames+0x2e/0x8a
[ 2866.132281] [<ffffffff81904122>] tcp_sendmsg+0xb32/0xcc6
[ 2866.132281] [<ffffffff819229c2>] inet_sendmsg+0xaa/0xd5
[ 2866.132281] [<ffffffff81922918>] ? inet_autobind+0x5f/0x5f
[ 2866.132281] [<ffffffff810ee7f1>] ? trace_clock_local+0x9/0xb
[ 2866.132281] [<ffffffff8189adab>] sock_sendmsg+0xa3/0xc4
[ 2866.132281] [<ffffffff810f5de6>] ? rb_reserve_next_event+0x26f/0x2d5
[ 2866.132281] [<ffffffff8103e6a9>] ? native_sched_clock+0x29/0x6f
[ 2866.132281] [<ffffffff8103e6f8>] ? sched_clock+0x9/0xd
[ 2866.132281] [<ffffffff810ee7f1>] ? trace_clock_local+0x9/0xb
[ 2866.132281] [<ffffffff8189ae03>] kernel_sendmsg+0x37/0x43
[ 2866.132281] [<ffffffff8199ce49>] xs_send_kvec+0x77/0x80
[ 2866.132281] [<ffffffff8199cec1>] xs_sendpages+0x6f/0x1a0
[ 2866.132281] [<ffffffff8107826d>] ? try_to_del_timer_sync+0x55/0x61
[ 2866.132281] [<ffffffff8199d0d2>] xs_tcp_send_request+0x55/0xf1
[ 2866.132281] [<ffffffff8199bb90>] xprt_transmit+0x89/0x1db
[ 2866.132281] [<ffffffff81999bcd>] ? call_connect+0x3c/0x3c
[ 2866.132281] [<ffffffff81999d92>] call_transmit+0x1c5/0x20e
[ 2866.132281] [<ffffffff819a0d55>] __rpc_execute+0x6f/0x225
[ 2866.132281] [<ffffffff81999bcd>] ? call_connect+0x3c/0x3c
[ 2866.132281] [<ffffffff819a0f33>] rpc_async_schedule+0x28/0x34
[ 2866.132281] [<ffffffff810835d6>] process_one_work+0x24d/0x47f
[ 2866.132281] [<ffffffff81083567>] ? process_one_work+0x1de/0x47f
[ 2866.132281] [<ffffffff819a0f0b>] ? __rpc_execute+0x225/0x225
[ 2866.132281] [<ffffffff81083a6d>] worker_thread+0x236/0x317
[ 2866.132281] [<ffffffff81083837>] ? process_scheduled_works+0x2f/0x2f
[ 2866.132281] [<ffffffff8108b7b8>] kthread+0x9a/0xa2
[ 2866.132281] [<ffffffff81a12184>] kernel_thread_helper+0x4/0x10
[ 2866.132281] [<ffffffff81a0a4b0>] ? retint_restore_args+0x13/0x13
[ 2866.132281] [<ffffffff8108b71e>] ? __init_kthread_worker+0x5a/0x5a
[ 2866.132281] [<ffffffff81a12180>] ? gs_change+0x13/0x13
[ 2866.308506] IPv4: Attempt to release TCP socket in state 1 ffff880019ec0000
[ 2866.309689] =============================================================================
[ 2866.310254] BUG TCP (Not tainted): Object already free
[ 2866.310254] -----------------------------------------------------------------------------
[ 2866.310254]
The bug comes from the fact that timer set in sk_reset_timer() can run
before we actually do the sock_hold(). socket refcount reaches zero and
we free the socket too soon.
timer handler is not allowed to reduce socket refcnt if socket is owned
by the user, or we need to change sk_reset_timer() implementation.
We should take a reference on the socket in case TCP_DELACK_TIMER_DEFERRED
or TCP_DELACK_TIMER_DEFERRED bit are set in tsq_flags
Also fix a typo in tcp_delack_timer(), where TCP_WRITE_TIMER_DEFERRED
was used instead of TCP_DELACK_TIMER_DEFERRED.
For consistency, use same socket refcount change for TCP_MTU_REDUCED_DEFERRED,
even if not fired from a timer.
Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Tested-by: Fengguang Wu <fengguang.wu@intel.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
net/ipv4/tcp_ipv4.c | 8 +++++---
net/ipv4/tcp_output.c | 14 +++++++++-----
net/ipv4/tcp_timer.c | 6 ++++--
3 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 7678237..6278a11 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -417,10 +417,12 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info)
if (code == ICMP_FRAG_NEEDED) { /* PMTU discovery (RFC1191) */
tp->mtu_info = info;
- if (!sock_owned_by_user(sk))
+ if (!sock_owned_by_user(sk)) {
tcp_v4_mtu_reduced(sk);
- else
- set_bit(TCP_MTU_REDUCED_DEFERRED, &tp->tsq_flags);
+ } else {
+ if (!test_and_set_bit(TCP_MTU_REDUCED_DEFERRED, &tp->tsq_flags))
+ sock_hold(sk);
+ }
goto out;
}
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 20dfd89..d046326 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -910,14 +910,18 @@ void tcp_release_cb(struct sock *sk)
if (flags & (1UL << TCP_TSQ_DEFERRED))
tcp_tsq_handler(sk);
- if (flags & (1UL << TCP_WRITE_TIMER_DEFERRED))
+ if (flags & (1UL << TCP_WRITE_TIMER_DEFERRED)) {
tcp_write_timer_handler(sk);
-
- if (flags & (1UL << TCP_DELACK_TIMER_DEFERRED))
+ __sock_put(sk);
+ }
+ if (flags & (1UL << TCP_DELACK_TIMER_DEFERRED)) {
tcp_delack_timer_handler(sk);
-
- if (flags & (1UL << TCP_MTU_REDUCED_DEFERRED))
+ __sock_put(sk);
+ }
+ if (flags & (1UL << TCP_MTU_REDUCED_DEFERRED)) {
sk->sk_prot->mtu_reduced(sk);
+ __sock_put(sk);
+ }
}
EXPORT_SYMBOL(tcp_release_cb);
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index 6df36ad..b774a03 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -252,7 +252,8 @@ static void tcp_delack_timer(unsigned long data)
inet_csk(sk)->icsk_ack.blocked = 1;
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_DELAYEDACKLOCKED);
/* deleguate our work to tcp_release_cb() */
- set_bit(TCP_WRITE_TIMER_DEFERRED, &tcp_sk(sk)->tsq_flags);
+ if (!test_and_set_bit(TCP_DELACK_TIMER_DEFERRED, &tcp_sk(sk)->tsq_flags))
+ sock_hold(sk);
}
bh_unlock_sock(sk);
sock_put(sk);
@@ -481,7 +482,8 @@ static void tcp_write_timer(unsigned long data)
tcp_write_timer_handler(sk);
} else {
/* deleguate our work to tcp_release_cb() */
- set_bit(TCP_WRITE_TIMER_DEFERRED, &tcp_sk(sk)->tsq_flags);
+ if (!test_and_set_bit(TCP_WRITE_TIMER_DEFERRED, &tcp_sk(sk)->tsq_flags))
+ sock_hold(sk);
}
bh_unlock_sock(sk);
sock_put(sk);
^ permalink raw reply related
* Re: [PATCH 11/11] netlink: add documentation for memory mapped I/O
From: Jan Engelhardt @ 2012-08-20 10:32 UTC (permalink / raw)
To: Patrick McHardy; +Cc: Florian.Westphal, netdev, netfilter-devel
In-Reply-To: <1345443532-3707-12-git-send-email-kaber@trash.net>
On Monday 2012-08-20 08:18, Patrick McHardy wrote:
>+
>+RX and TX rings
>+----------------
>+
>+Each ring contains a number of continous memory blocks, containing frames of
>+fixed size dependant on the parameters used for ring setup.
dependent
>+The blocks are only visible to the kernel, from the point of view of user-space
>+the ring just contains the frames in a continous memory zone.
...to the kernel; from the user-space point of view, the ring...
continuous (multiple occurrences)
>+Ring frames
>+------------
>+
>+Each frames contain a frame header, consisting of a synchronization word and some
Each frame contains a frame header,
>+The possible values in the status word are:
>+
>+- NL_MMAP_STATUS_UNUSED:
>+ RX ring: frame belongs to the kernel and contains no message
The frame (mult)
>+ for user-space. Approriate action is to invoke poll()
>+ to wait for new messages.
The appropriate (mult)
>+ if (hdr->nm_status == NL_MMAP_STATUS_VALID)
>+ /* Regular memory mapped frame */
>+ nlh = (void *hdr) + NL_MMAP_HDRLEN;
(void *)hdr + NL_MMAP_HDRLEN
^ permalink raw reply
* Re: [PATCH 05/18] netfilter: nf_nat: add protoff argument to packet mangling functions
From: Patrick McHardy @ 2012-08-20 10:37 UTC (permalink / raw)
To: Jan Engelhardt; +Cc: netfilter-devel, netdev
In-Reply-To: <alpine.LNX.2.01.1208201000580.6101@frira.zrqbmnf.qr>
On Mon, 20 Aug 2012, Jan Engelhardt wrote:
>
> On Monday 2012-08-20 05:39, Patrick McHardy wrote:
>> index 0bb5a69..4b59a15 100644
>> --- a/include/linux/netfilter/nf_conntrack_amanda.h
>> +++ b/include/linux/netfilter/nf_conntrack_amanda.h
>> @@ -4,6 +4,7 @@
>>
>> extern unsigned int (*nf_nat_amanda_hook)(struct sk_buff *skb,
>> enum ip_conntrack_info ctinfo,
>> + unsigned int protoff,
>> unsigned int matchoff,
>> unsigned int matchlen,
>> struct nf_conntrack_expect *exp);
>
> What about using a structure to collect all the accumulating parameters,
> like we do for xtables match functions?
Yes, we could do that for the common parameters.
^ permalink raw reply
* Re: [PATCH 01/18] ipv4: fix path MTU discovery with connection tracking
From: Patrick McHardy @ 2012-08-20 10:59 UTC (permalink / raw)
To: Jan Engelhardt; +Cc: netfilter-devel, netdev
In-Reply-To: <alpine.LNX.2.01.1208201002270.6101@frira.zrqbmnf.qr>
On Mon, 20 Aug 2012, Jan Engelhardt wrote:
> On Monday 2012-08-20 05:39, Patrick McHardy wrote:
>
>> IPv4 conntrack defragments incoming packet at the PRE_ROUTING hook and
>> (in case of forwarded packets) refragments them at POST_ROUTING
>> independant of the IP_DF flag.
>
> "independent". (also in 06/18)
Fixed, thanks.
^ permalink raw reply
* Re: [PATCH v1 3/5] cgroup: Protect access to task_cls_classid() when built as module
From: Neil Horman @ 2012-08-20 11:08 UTC (permalink / raw)
To: Li Zefan
Cc: Daniel Wagner, netdev-u79uwXL29TY76Z2rM5mHXA,
cgroups-u79uwXL29TY76Z2rM5mHXA, Daniel Wagner, David S. Miller,
Gao feng, Jamal Hadi Salim, John Fastabend, Tejun Heo
In-Reply-To: <50318BF9.2080803-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
On Mon, Aug 20, 2012 at 08:59:37AM +0800, Li Zefan wrote:
> 于 2012/8/18 2:28, Neil Horman 写道:
> > On Fri, Aug 17, 2012 at 04:58:12PM +0200, Daniel Wagner wrote:
> >> From: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
> >>
> >> The module version of task_cls_classid() checks if net_cls_sbusys_id
> >> is valid to indentify when it is okay to access the controller.
> >>
> >> Instead relying on the subusys_id to be set, make it explicit
> >> with a jump label.
> >>
> >> Signed-off-by: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
> >> Cc: "David S. Miller" <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
> >> Cc: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
> >> Cc: Jamal Hadi Salim <jhs-jkUAjuhPggJWk0Htik3J/w@public.gmane.org>
> >> Cc: John Fastabend <john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> >> Cc: Li Zefan <lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
> >> Cc: Neil Horman <nhorman-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
> >> Cc: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> >> Cc: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> >> Cc: cgroups-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> >> ---
> >> include/net/cls_cgroup.h | 5 ++++-
> >> net/core/sock.c | 5 +++++
> >> net/sched/cls_cgroup.c | 9 +++++++++
> >> 3 files changed, 18 insertions(+), 1 deletion(-)
> >>
> >> diff --git a/include/net/cls_cgroup.h b/include/net/cls_cgroup.h
> >> index 401672c..bbbd957 100644
> >> --- a/include/net/cls_cgroup.h
> >> +++ b/include/net/cls_cgroup.h
> >> @@ -16,6 +16,7 @@
> >> #include <linux/cgroup.h>
> >> #include <linux/hardirq.h>
> >> #include <linux/rcupdate.h>
> >> +#include <linux/jump_label.h>
> >>
> >> #ifdef CONFIG_CGROUPS
> >> struct cgroup_cls_state
> >> @@ -44,6 +45,8 @@ static inline u32 task_cls_classid(struct task_struct *p)
> >> }
> >>
> >> #elif IS_MODULE(CONFIG_NET_CLS_CGROUP)
> >> +extern struct static_key cgroup_cls_enabled;
> >> +#define clscg_enabled static_key_false(&cgroup_cls_enabled)
> >>
> >> extern int net_cls_subsys_id;
> >>
> >> @@ -52,7 +55,7 @@ static inline u32 task_cls_classid(struct task_struct *p)
> >> int id;
> >> u32 classid = 0;
> >>
> >> - if (in_interrupt())
> >> + if (!clscg_enabled || in_interrupt())
> >> return 0;
> >>
> >> rcu_read_lock();
> >> diff --git a/net/core/sock.c b/net/core/sock.c
> >> index 8f67ced..8106e77 100644
> >> --- a/net/core/sock.c
> >> +++ b/net/core/sock.c
> >> @@ -327,6 +327,11 @@ int __sk_backlog_rcv(struct sock *sk, struct sk_buff *skb)
> >> EXPORT_SYMBOL(__sk_backlog_rcv);
> >>
> >> #if defined(CONFIG_CGROUPS)
> >> +#if IS_MODULE(CONFIG_NET_CLS_CGROUP)
> >> +struct static_key cgroup_cls_enabled = STATIC_KEY_INIT_FALSE;
> >> +EXPORT_SYMBOL_GPL(cgroup_cls_enabled);
> >> +#endif
> >> +
> >> #if !defined(CONFIG_NET_CLS_CGROUP)
> >> int net_cls_subsys_id = -1;
> >> EXPORT_SYMBOL_GPL(net_cls_subsys_id);
> >> diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
> >> index 7743ea8..0635894 100644
> >> --- a/net/sched/cls_cgroup.c
> >> +++ b/net/sched/cls_cgroup.c
> >> @@ -44,12 +44,21 @@ static struct cgroup_subsys_state *cgrp_create(struct cgroup *cgrp)
> >>
> >> if (cgrp->parent)
> >> cs->classid = cgrp_cls_state(cgrp->parent)->classid;
> >> +#if IS_MODULE(CONFIG_NET_CLS_CGROUP)
> >> + else if (!clscg_enabled)
> >> + static_key_slow_inc(&cgroup_cls_enabled);
> > This is racy I think. The read of the static key is atomic with other reads,
> > but the entire conditional is not atomic. If two cpus were creating cgroups in
> > parallel, it would be possible for both to read the static key as being zero
> > (the second cpu would read the key before the first cpu could increment it).
>
> static_key_slow_inc() is called only when we're creating the root cgroup, and that's
> module loading.
>
> so it's safe.
>
What makes you say that? It appears to me that we call ss->create (and
potential ss->destroy, depending on failure conditions) from cgroup_create,
which in turn is called from cgroup_mkdir, which is called for every cgroup
instance created, not just the root cgroup.
Neil
^ permalink raw reply
* Re: [PATCH v1 3/5] cgroup: Protect access to task_cls_classid() when built as module
From: Daniel Wagner @ 2012-08-20 11:29 UTC (permalink / raw)
To: Neil Horman
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, cgroups-u79uwXL29TY76Z2rM5mHXA,
Daniel Wagner, David S. Miller, Gao feng, Jamal Hadi Salim,
John Fastabend, Li Zefan, Tejun Heo
In-Reply-To: <20120817182855.GA11607-B26myB8xz7F8NnZeBjwnZQMhkBWG/bsMQH7oEaQurus@public.gmane.org>
On Fri, Aug 17, 2012 at 02:28:55PM -0400, Neil Horman wrote:
> On Fri, Aug 17, 2012 at 04:58:12PM +0200, Daniel Wagner wrote:
> > From: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
> >
> > The module version of task_cls_classid() checks if net_cls_sbusys_id
> > is valid to indentify when it is okay to access the controller.
> >
> > Instead relying on the subusys_id to be set, make it explicit
> > with a jump label.
> >
> > Signed-off-by: Daniel Wagner <daniel.wagner-98C5kh4wR6ohFhg+JK9F0w@public.gmane.org>
> > Cc: "David S. Miller" <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
> > Cc: Gao feng <gaofeng-BthXqXjhjHXQFUHtdCDX3A@public.gmane.org>
> > Cc: Jamal Hadi Salim <jhs-jkUAjuhPggJWk0Htik3J/w@public.gmane.org>
> > Cc: John Fastabend <john.r.fastabend-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> > Cc: Li Zefan <lizefan-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
> > Cc: Neil Horman <nhorman-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
> > Cc: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> > Cc: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> > Cc: cgroups-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> > ---
> > include/net/cls_cgroup.h | 5 ++++-
> > net/core/sock.c | 5 +++++
> > net/sched/cls_cgroup.c | 9 +++++++++
> > 3 files changed, 18 insertions(+), 1 deletion(-)
> >
> > diff --git a/include/net/cls_cgroup.h b/include/net/cls_cgroup.h
> > index 401672c..bbbd957 100644
> > --- a/include/net/cls_cgroup.h
> > +++ b/include/net/cls_cgroup.h
> > @@ -16,6 +16,7 @@
> > #include <linux/cgroup.h>
> > #include <linux/hardirq.h>
> > #include <linux/rcupdate.h>
> > +#include <linux/jump_label.h>
> >
> > #ifdef CONFIG_CGROUPS
> > struct cgroup_cls_state
> > @@ -44,6 +45,8 @@ static inline u32 task_cls_classid(struct task_struct *p)
> > }
> >
> > #elif IS_MODULE(CONFIG_NET_CLS_CGROUP)
> > +extern struct static_key cgroup_cls_enabled;
> > +#define clscg_enabled static_key_false(&cgroup_cls_enabled)
> >
> > extern int net_cls_subsys_id;
> >
> > @@ -52,7 +55,7 @@ static inline u32 task_cls_classid(struct task_struct *p)
> > int id;
> > u32 classid = 0;
> >
> > - if (in_interrupt())
> > + if (!clscg_enabled || in_interrupt())
> > return 0;
> >
> > rcu_read_lock();
> > diff --git a/net/core/sock.c b/net/core/sock.c
> > index 8f67ced..8106e77 100644
> > --- a/net/core/sock.c
> > +++ b/net/core/sock.c
> > @@ -327,6 +327,11 @@ int __sk_backlog_rcv(struct sock *sk, struct sk_buff *skb)
> > EXPORT_SYMBOL(__sk_backlog_rcv);
> >
> > #if defined(CONFIG_CGROUPS)
> > +#if IS_MODULE(CONFIG_NET_CLS_CGROUP)
> > +struct static_key cgroup_cls_enabled = STATIC_KEY_INIT_FALSE;
> > +EXPORT_SYMBOL_GPL(cgroup_cls_enabled);
> > +#endif
> > +
> > #if !defined(CONFIG_NET_CLS_CGROUP)
> > int net_cls_subsys_id = -1;
> > EXPORT_SYMBOL_GPL(net_cls_subsys_id);
> > diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
> > index 7743ea8..0635894 100644
> > --- a/net/sched/cls_cgroup.c
> > +++ b/net/sched/cls_cgroup.c
> > @@ -44,12 +44,21 @@ static struct cgroup_subsys_state *cgrp_create(struct cgroup *cgrp)
> >
> > if (cgrp->parent)
> > cs->classid = cgrp_cls_state(cgrp->parent)->classid;
> > +#if IS_MODULE(CONFIG_NET_CLS_CGROUP)
> > + else if (!clscg_enabled)
> > + static_key_slow_inc(&cgroup_cls_enabled);
> This is racy I think. The read of the static key is atomic with other reads,
> but the entire conditional is not atomic. If two cpus were creating cgroups in
> parallel, it would be possible for both to read the static key as being zero
> (the second cpu would read the key before the first cpu could increment it).
D'oh, That is racy.
> > +#endif
> >
> > return &cs->css;
> > }
> >
> > static void cgrp_destroy(struct cgroup *cgrp)
> > {
> > +#if IS_MODULE(CONFIG_NET_CLS_CGROUP)
> > + if (!cgrp->parent && clscg_enabled)
> > + static_key_slow_dec(&cgroup_cls_enabled);
> Ditto here with the race above. I think what you want is one of:
>
> 1) Use static_key_slow_[inc|dec] unconditionally
While the static_key_slow_inc() case will work, I am not so sure about
the static_key_slow_dec(), e.g. we could still access inside
task_cls_classid() a destroyed container.
> 2) Keep a separate internal counter to track the number of cgroup instances
> so that you only inc the static key on the first create and dec it on the last
> delete.
If I got you right, than this would not be different then direclty using
static_key_slow_[inc|dec].
> I would think (1) would be sufficent. It looks like static_key_slow_inc uses
> atomic_inc_not_zero to just do an inc anyway in the event that multiple inc
> events are made.
Would something like this work?
static inline u32 task_cls_classid(struct task_struct *p)
{
u32 classid;
struct cgroup_cls_state *css;
if (!clscg_enabled || in_interrupt())
return 0;
rcu_read_lock();
css = container_of(task_subsys_state(p, net_cls_subsys_id),
struct cgroup_cls_state, css);
if (!css)
classid = css->classid;
else
classid = 0;
rcu_read_unlock();
return classid;
}
Daniel
^ permalink raw reply
* Re: [PATCH v1 3/5] cgroup: Protect access to task_cls_classid() when built as module
From: Glauber Costa @ 2012-08-20 11:33 UTC (permalink / raw)
To: Daniel Wagner
Cc: Neil Horman, netdev-u79uwXL29TY76Z2rM5mHXA,
cgroups-u79uwXL29TY76Z2rM5mHXA, Daniel Wagner, David S. Miller,
Gao feng, Jamal Hadi Salim, John Fastabend, Li Zefan, Tejun Heo
In-Reply-To: <20120820112938.GA22415-rjQKm2AMs/APuY3F5OKgMy7zKzJi9e1+kcYEyfhdaNw@public.gmane.org>
On 08/20/2012 03:29 PM, Daniel Wagner wrote:
>> This is racy I think. The read of the static key is atomic with other reads,
>> > but the entire conditional is not atomic. If two cpus were creating cgroups in
>> > parallel, it would be possible for both to read the static key as being zero
>> > (the second cpu would read the key before the first cpu could increment it).
> D'oh, That is racy.
>
Take a look at how we solve this particular problem in memcg. By using a
pair of bits meaning "ever active" and "currently active", we can avoid
problems with the static key increments.
Nothing bad can't happen by increasing the static key more than once;
the problem is that you need to somehow take note of that to make sure
you decrement the as many times you incremented when you release it.
Two other important things to keep in mind while dealing with static
branches:
* You can't increase/decrease while holding the cgroup_lock. lockdep may
trigger, because the cgroup_lock holds the cpu_hotplug lock, that the
static branches update path will also take. (due to cpusets). Doing a
logical hotplug will stress this path, and make the problem visible.
Take a look at disarm_sock_keys() (mm/memcontrol.c) to see how we solve
this particular problem.
* If you have code in more than one call site, the update among them is
not atomic. Not sure if this one applies to your case, but it can lead
you to some very unpleasant to debug problems. We use one of those two
bits I mentioned ("currently active") to make sure objects are not
marked before all sites are already patched.
Hope our previous experience with this can help you.
^ permalink raw reply
* Re: [RFC PATCH 1/1] fair.c: Add/Export find_idlest_perfer_cpu API
From: Peter Zijlstra @ 2012-08-20 12:00 UTC (permalink / raw)
To: Shirley Ma; +Cc: linux-kernel, mingo, Michael S. Tsirkin, netdev, sri, vivek
In-Reply-To: <1345232770.16533.234.camel@oc3660625478.ibm.com>
On Fri, 2012-08-17 at 12:46 -0700, Shirley Ma wrote:
> Add/Export a new API for per-cpu thread model networking device driver
> to choose a preferred idlest cpu within allowed cpumask.
>
> The receiving CPUs of a networking device are not under cgroup controls.
> Normally the receiving work will be scheduled on the cpu on which the
> interrupts are received. When such a networking device uses per-cpu
> thread model, the cpu which is chose to process the packets might not be
> part of cgroup cpusets without using such an API here.
>
> On NUMA system, by using the preferred cpumask from the same NUMA node
> would help to reduce expensive cross memory access to/from the other
> NUMA node.
>
> KVM per-cpu vhost will be the first one to use this API. Any other
> device driver which uses per-cpu thread model and has cgroup cpuset
> control will use this API later.
How often will this be called and how do you obtain the cpumasks
provided to the function?
^ permalink raw reply
* Re: [PATCH] ipv4: Use netinet->inet_opt in inet_csk_route_child_sock()
From: Christoph Paasch @ 2012-08-20 12:11 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20120820.025147.936465141809418575.davem@davemloft.net>
On Monday 20 August 2012 02:51:47 David Miller wrote:
> From: Christoph Paasch <christoph.paasch@uclouvain.be>
> Date: Fri, 17 Aug 2012 23:35:12 +0200
>
> > @@ -404,7 +404,7 @@ struct dst_entry *inet_csk_route_child_sock(struct
> > sock *sk,>
> > {
> > const struct inet_request_sock *ireq = inet_rsk(req);
> > struct inet_sock *newinet = inet_sk(newsk);
> >
> > - struct ip_options_rcu *opt = ireq->opt;
> > + struct ip_options_rcu *opt = rcu_dereference(newinet->inet_opt);
> >
> > struct net *net = sock_net(sk);
>
> We're not inside of a rcu_read_lock() protected section, so this access
> is not legitimate. If you enabled RCU lock debugging, you would have
> triggered a warning in the kernel log.
Oh, sorry... I will resubmit a v2.
Although, I enabled CONFIG_PROVE_RCU (and all other RCU-related debug I could
find) and no warning was triggered.
By the way, in dccp_v4_request_recv_sock() is the code:
newinet->inet_opt = ireq->opt;
Shouldn't this rather be an rcu_assign_pointer() ?
And in cipso_v4_sock_delattr() I believe we should also rather access 'opt'
instead of doing cipso_v4_delopt(&sk_inet->inet_opt) ?
Christoph
--
IP Networking Lab --- http://inl.info.ucl.ac.be
MultiPath TCP in the Linux Kernel --- http://mptcp.info.ucl.ac.be
Université Catholique de Louvain
--
^ permalink raw reply
* Re: [PATCH 1/2] ipv6: do not hold route table lock when send ndisc probe
From: Cong Wang @ 2012-08-20 12:15 UTC (permalink / raw)
To: Debabrata Banerjee
Cc: netdev, Banerjee, Debabrata, David S. Miller, Hideaki YOSHIFUJI,
Patrick McHardy
In-Reply-To: <CAATkVEzKuTeUbU75B6EoSfFvGVsz_eK47XNWmsP5KcCvjTDEDA@mail.gmail.com>
On Fri, 2012-08-17 at 14:54 -0400, Debabrata Banerjee wrote:
> Well it get rids of the deadlock for sure, but I am not sure it
> doesn't break something else, one would have to know all of this code
> much better to tell. You'll notice read_unlock_bh(&table->tb6_lock)
> for the first lock in ip6_pol_route() has more in the critical section
> after the rt6_select() call, especially that rather scary BACKTRACK()
> macro.
>
Yeah, I noticed that, ->tb6_lock seems to protect lookup of ->tb6_root,
not sure if 'rt' may still valid after retaking this lock... Hmm,
probably calling ndisc_send_ns() inside a work is a better approach.
I will update the patch.
Thanks!
^ permalink raw reply
* WARNING: at include/net/mac80211.h:3630 rate_control_send_low+0xc1/0x1a1
From: Arnd Hannemann @ 2012-08-20 12:51 UTC (permalink / raw)
To: linux-wireless-u79uwXL29TY76Z2rM5mHXA; +Cc: netdev
Hi,
I just observed the above kernel warning after issuing an "wpa_cli reassociate",
followed by some "iwconfig" calls to check the status.
Kernel is 3.4.7, Hardware is x86 (32bit) and ath9k
WARNING comes from inline function "rate_lowest_index":
3629 /* warn when we cannot find a rate. */
3630 WARN_ON_ONCE(1);
Full stacktrace below:
[1793205.090602] wlan0: deauthenticating from XX:XX:XX:XX:XX:XX by local choice (reason=3)
[1793205.090754] ------------[ cut here ]------------
[1793205.105295] WARNING: at include/net/mac80211.h:3630 rate_control_send_low+0xc1/0x1a1 [mac80211]()
[1793205.132424] Modules linked in: aes_generic xt_TCPMSS ipt_ULOG ipt_MASQUERADE xt_LOG xt_time xt_connlimit xt_helper xt_realm xt_NFQUEUE xt_tcpmss xt_addrtype xt_pkttype iptab
le_raw xt_TPROXY nf_tproxy_core ip6_tables nf_defrag_ipv6 xt_hashlimit xt_comment xt_length xt_connmark xt_owner xt_recent xt_iprange xt_physdev xt_policy xt_multiport iptable_na
t nf_nat xt_conntrack nf_conntrack_tftp nf_conntrack_sip nf_conntrack_proto_sctp nf_conntrack_pptp nf_conntrack_proto_gre nf_conntrack_netlink nfnetlink nf_conntrack_irc nf_connt
rack_h323 nf_conntrack_ftp nf_conntrack_ipv4 nf_defrag_ipv4 nf_conntrack ath9k ath5k ath9k_common ath9k_hw mac80211 ath ohci_hcd ehci_hcd cfg80211
[1793205.313648] Pid: 1959, comm: wpa_supplicant Not tainted 3.4.7-ela1 #1
[1793205.333502] Call Trace:
[1793205.341407] [<c1016dee>] warn_slowpath_common+0x65/0x7a
[1793205.357935] [<d094178b>] ? rate_control_send_low+0xc1/0x1a1 [mac80211]
[1793205.378312] [<c1016e12>] warn_slowpath_null+0xf/0x13
[1793205.394073] [<d094178b>] rate_control_send_low+0xc1/0x1a1 [mac80211]
[1793205.414008] [<d095af6c>] minstrel_ht_get_rate+0x25/0x295 [mac80211]
[1793205.433675] [<d09414fb>] rate_control_get_rate+0x7e/0x24d [mac80211]
[1793205.453528] [<c102e7f4>] ? T.295+0xe/0x128
[1793205.466632] [<c1167ffe>] ? rb_insert_color+0x58/0xc5
[1793205.482397] [<d09494d1>] invoke_tx_handlers+0x78f/0xfa5 [mac80211]
[1793205.501799] [<d094a648>] ieee80211_tx+0x50/0x77 [mac80211]
[1793205.519112] [<d094a971>] ieee80211_xmit+0xae/0xb6 [mac80211]
[1793205.536956] [<d094a9bf>] ieee80211_tx_skb_tid+0x46/0x50 [mac80211]
[1793205.556368] [<d094e4d4>] ieee80211_send_deauth_disassoc+0xbb/0xc1 [mac80211]
[1793205.578365] [<d094e5ff>] ieee80211_set_disassoc+0x125/0x275 [mac80211]
[1793205.598803] [<d094e8b9>] ieee80211_mgd_deauth+0x92/0x102 [mac80211]
[1793205.618455] [<d0943b87>] ieee80211_deauth+0x10/0x12 [mac80211]
[1793205.636812] [<d0878348>] __cfg80211_mlme_deauth+0x84/0x90 [cfg80211]
[1793205.656702] [<d087a9d5>] __cfg80211_disconnect+0xc3/0x125 [cfg80211]
[1793205.676594] [<d087d330>] cfg80211_mgd_wext_siwessid+0xec/0x18d [cfg80211]
[1793205.697778] [<d087c639>] cfg80211_wext_siwessid+0x31/0x3e [cfg80211]
[1793205.717648] [<c1293b8a>] ioctl_standard_call+0x1e6/0x27a
[1793205.734374] [<c1293ccf>] wext_handle_ioctl+0xb1/0x132
[1793205.750374] [<d087c608>] ? cfg80211_wext_giwessid+0x4a/0x4a [cfg80211]
[1793205.770755] [<c11df9db>] dev_ioctl+0x53f/0x57c
[1793205.784892] [<c10683f8>] ? do_sync_write+0x93/0xce
[1793205.800077] [<c11d0250>] ? kernel_sendmsg+0x37/0x37
[1793205.815514] [<c11d0428>] sock_ioctl+0x1d8/0x1e4
[1793205.829892] [<c11d0250>] ? kernel_sendmsg+0x37/0x37
[1793205.845341] [<c10733b8>] do_vfs_ioctl+0x424/0x463
[1793205.860263] [<c11d0b76>] ? sys_send+0x18/0x1a
[1793205.874146] [<c11d1ad4>] ? sys_socketcall+0xc9/0x19c
[1793205.889848] [<c1073425>] sys_ioctl+0x2e/0x48
[1793205.903477] [<c129d095>] syscall_call+0x7/0xb
[1793205.917356] [<c1290000>] ? rsi_parse+0xbf/0x331
[1793205.931752] ---[ end trace 9c8890d6ce64a00b ]---
[1793205.966909] cfg80211: Calling CRDA to update world regulatory domain
[1793205.986669] wlan0: authenticate with XX:XX:XX:XX:XX:XY
Best regards
Arnd
--
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
* [PATCH v2] ipv4: Use newinet->inet_opt in inet_csk_route_child_sock()
From: Christoph Paasch @ 2012-08-20 12:52 UTC (permalink / raw)
To: David Miller; +Cc: netdev
Since 0e734419923bd ("ipv4: Use inet_csk_route_child_sock() in DCCP and
TCP."), inet_csk_route_child_sock() is called instead of
inet_csk_route_req().
However, after creating the child-sock in tcp/dccp_v4_syn_recv_sock(),
ireq->opt is set to NULL, before calling inet_csk_route_child_sock().
Thus, inside inet_csk_route_child_sock() opt is always NULL and the
SRR-options are not respected anymore.
Packets sent by the server won't have the correct destination-IP.
This patch fixes it by accessing newinet->inet_opt instead of ireq->opt
inside inet_csk_route_child_sock().
Reported-by: Luca Boccassi <luca.boccassi@gmail.com>
Signed-off-by: Christoph Paasch <christoph.paasch@uclouvain.be>
---
v2:
* Added rcu_read_(un)lock()
* Fixed typo in the patch-subject
* Added "Reported-by"
---
net/ipv4/inet_connection_sock.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index db0cf17..7f75f21 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -404,12 +404,15 @@ struct dst_entry *inet_csk_route_child_sock(struct sock *sk,
{
const struct inet_request_sock *ireq = inet_rsk(req);
struct inet_sock *newinet = inet_sk(newsk);
- struct ip_options_rcu *opt = ireq->opt;
+ struct ip_options_rcu *opt;
struct net *net = sock_net(sk);
struct flowi4 *fl4;
struct rtable *rt;
fl4 = &newinet->cork.fl.u.ip4;
+
+ rcu_read_lock();
+ opt = rcu_dereference(newinet->inet_opt);
flowi4_init_output(fl4, sk->sk_bound_dev_if, sk->sk_mark,
RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE,
sk->sk_protocol, inet_sk_flowi_flags(sk),
@@ -421,11 +424,13 @@ struct dst_entry *inet_csk_route_child_sock(struct sock *sk,
goto no_route;
if (opt && opt->opt.is_strictroute && rt->rt_gateway)
goto route_err;
+ rcu_read_unlock();
return &rt->dst;
route_err:
ip_rt_put(rt);
no_route:
+ rcu_read_unlock();
IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES);
return NULL;
}
--
1.7.9.5
^ permalink raw reply related
* [PATCH 0/3] ipvs: IPv6 fragment handling for IPVS
From: Jesper Dangaard Brouer @ 2012-08-20 13:08 UTC (permalink / raw)
To: netdev, Patrick McHardy, Hans Schillstrom, lvs-devel,
Julian Anastasov, Simon Horman
Cc: Jesper Dangaard Brouer, Wensong Zhang, netfilter-devel
The following patchset implement IPv6 fragment handling for IPVS.
This work is based upon patches from Hans Schillstrom. I have taken
over the patchset, in close agreement with Hans, because he don't have
(gotten allocated) time to complete his work.
I have cleaned up the patchset, changed the API a bit, fixed a refcnt
bug, and rebased on top of Julians recent changes. (All with Hans'es
knowledge)
Patch01: is just unrelated trivial fixes.
Patch02: Fix faulty IPv6 extension header handling in IPVS
Patch03: Complete IPv6 fragment handling for IPVS
This patchset is based upon:
Homes ipvs-next tree:
git://git.kernel.org/pub/scm/linux/kernel/git/horms/ipvs-next.git
On top of commit 3654e61137db891f5312e6dd813b961484b5fdf3:
ipvs: add pmtu_disc option to disable IP DF for TUN packets
---
Jesper Dangaard Brouer (3):
ipvs: Complete IPv6 fragment handling for IPVS
ipvs: Fix faulty IPv6 extension header handling in IPVS
ipvs: Trivial changes, use compressed IPv6 address in output
include/net/ip_vs.h | 191 +++++++++++----
net/netfilter/ipvs/Kconfig | 7 -
net/netfilter/ipvs/ip_vs_conn.c | 15 -
net/netfilter/ipvs/ip_vs_core.c | 384 +++++++++++++++++--------------
net/netfilter/ipvs/ip_vs_dh.c | 2
net/netfilter/ipvs/ip_vs_lblc.c | 2
net/netfilter/ipvs/ip_vs_lblcr.c | 2
net/netfilter/ipvs/ip_vs_pe_sip.c | 27 ++
net/netfilter/ipvs/ip_vs_proto.c | 6
net/netfilter/ipvs/ip_vs_proto_ah_esp.c | 9 -
net/netfilter/ipvs/ip_vs_proto_sctp.c | 42 +--
net/netfilter/ipvs/ip_vs_proto_tcp.c | 40 +--
net/netfilter/ipvs/ip_vs_proto_udp.c | 41 +--
net/netfilter/ipvs/ip_vs_sched.c | 2
net/netfilter/ipvs/ip_vs_sh.c | 2
net/netfilter/ipvs/ip_vs_xmit.c | 75 +++---
net/netfilter/xt_ipvs.c | 4
17 files changed, 489 insertions(+), 362 deletions(-)
--
Best regards,
Jesper Dangaard Brouer
MSc.CS, Sr. Network Kernel Developer at Red Hat
Author of http://www.iptv-analyzer.org
LinkedIn: http://www.linkedin.com/in/brouer
^ permalink raw reply
* [PATCH 1/3] ipvs: Trivial changes, use compressed IPv6 address in output
From: Jesper Dangaard Brouer @ 2012-08-20 13:08 UTC (permalink / raw)
To: netdev, Patrick McHardy, Hans Schillstrom, lvs-devel,
Julian Anastasov, Simon Horman
Cc: Jesper Dangaard Brouer, Wensong Zhang, netfilter-devel
In-Reply-To: <20120820130732.1509.13080.stgit@dragon>
Have not converted the proc file output to compressed IPv6 addresses.
Move trivial fixes to this first patch.
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
---
include/net/ip_vs.h | 2 +-
net/netfilter/ipvs/ip_vs_proto.c | 6 +++---
net/netfilter/ipvs/ip_vs_sched.c | 2 +-
net/netfilter/ipvs/ip_vs_xmit.c | 10 +++++-----
4 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index ee75ccd..aba0bb2 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -165,7 +165,7 @@ static inline const char *ip_vs_dbg_addr(int af, char *buf, size_t buf_len,
int len;
#ifdef CONFIG_IP_VS_IPV6
if (af == AF_INET6)
- len = snprintf(&buf[*idx], buf_len - *idx, "[%pI6]",
+ len = snprintf(&buf[*idx], buf_len - *idx, "[%pI6c]",
&addr->in6) + 1;
else
#endif
diff --git a/net/netfilter/ipvs/ip_vs_proto.c b/net/netfilter/ipvs/ip_vs_proto.c
index 50d8218..939f7fb 100644
--- a/net/netfilter/ipvs/ip_vs_proto.c
+++ b/net/netfilter/ipvs/ip_vs_proto.c
@@ -280,17 +280,17 @@ ip_vs_tcpudp_debug_packet_v6(struct ip_vs_protocol *pp,
if (ih == NULL)
sprintf(buf, "TRUNCATED");
else if (ih->nexthdr == IPPROTO_FRAGMENT)
- sprintf(buf, "%pI6->%pI6 frag", &ih->saddr, &ih->daddr);
+ sprintf(buf, "%pI6c->%pI6c frag", &ih->saddr, &ih->daddr);
else {
__be16 _ports[2], *pptr;
pptr = skb_header_pointer(skb, offset + sizeof(struct ipv6hdr),
sizeof(_ports), _ports);
if (pptr == NULL)
- sprintf(buf, "TRUNCATED %pI6->%pI6",
+ sprintf(buf, "TRUNCATED %pI6c->%pI6c",
&ih->saddr, &ih->daddr);
else
- sprintf(buf, "%pI6:%u->%pI6:%u",
+ sprintf(buf, "%pI6c:%u->%pI6c:%u",
&ih->saddr, ntohs(pptr[0]),
&ih->daddr, ntohs(pptr[1]));
}
diff --git a/net/netfilter/ipvs/ip_vs_sched.c b/net/netfilter/ipvs/ip_vs_sched.c
index 08dbdd5..d6bf20d 100644
--- a/net/netfilter/ipvs/ip_vs_sched.c
+++ b/net/netfilter/ipvs/ip_vs_sched.c
@@ -159,7 +159,7 @@ void ip_vs_scheduler_err(struct ip_vs_service *svc, const char *msg)
svc->fwmark, msg);
#ifdef CONFIG_IP_VS_IPV6
} else if (svc->af == AF_INET6) {
- IP_VS_ERR_RL("%s: %s [%pI6]:%d - %s\n",
+ IP_VS_ERR_RL("%s: %s [%pI6c]:%d - %s\n",
svc->scheduler->name,
ip_vs_proto_name(svc->protocol),
&svc->addr.in6, ntohs(svc->port), msg);
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index 543a554..eef3432 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -319,7 +319,7 @@ __ip_vs_get_out_rt_v6(struct sk_buff *skb, struct ip_vs_dest *dest,
local = __ip_vs_is_local_route6(rt);
if (!((local ? IP_VS_RT_MODE_LOCAL : IP_VS_RT_MODE_NON_LOCAL) &
rt_mode)) {
- IP_VS_DBG_RL("Stopping traffic to %s address, dest: %pI6\n",
+ IP_VS_DBG_RL("Stopping traffic to %s address, dest: %pI6c\n",
local ? "local":"non-local", daddr);
dst_release(&rt->dst);
return NULL;
@@ -327,8 +327,8 @@ __ip_vs_get_out_rt_v6(struct sk_buff *skb, struct ip_vs_dest *dest,
if (local && !(rt_mode & IP_VS_RT_MODE_RDR) &&
!((ort = (struct rt6_info *) skb_dst(skb)) &&
__ip_vs_is_local_route6(ort))) {
- IP_VS_DBG_RL("Redirect from non-local address %pI6 to local "
- "requires NAT method, dest: %pI6\n",
+ IP_VS_DBG_RL("Redirect from non-local address %pI6c to local "
+ "requires NAT method, dest: %pI6c\n",
&ipv6_hdr(skb)->daddr, daddr);
dst_release(&rt->dst);
return NULL;
@@ -336,8 +336,8 @@ __ip_vs_get_out_rt_v6(struct sk_buff *skb, struct ip_vs_dest *dest,
if (unlikely(!local && (!skb->dev || skb->dev->flags & IFF_LOOPBACK) &&
ipv6_addr_type(&ipv6_hdr(skb)->saddr) &
IPV6_ADDR_LOOPBACK)) {
- IP_VS_DBG_RL("Stopping traffic from loopback address %pI6 "
- "to non-local address, dest: %pI6\n",
+ IP_VS_DBG_RL("Stopping traffic from loopback address %pI6c "
+ "to non-local address, dest: %pI6c\n",
&ipv6_hdr(skb)->saddr, daddr);
dst_release(&rt->dst);
return NULL;
^ permalink raw reply related
* [PATCH 3/3] ipvs: Complete IPv6 fragment handling for IPVS
From: Jesper Dangaard Brouer @ 2012-08-20 13:08 UTC (permalink / raw)
To: netdev, Patrick McHardy, Hans Schillstrom, lvs-devel,
Julian Anastasov, Simon Horman
Cc: Jesper Dangaard Brouer, Wensong Zhang, netfilter-devel
In-Reply-To: <20120820130732.1509.13080.stgit@dragon>
IPVS now supports fragmented packets, with support from nf_conntrack_reasm.c
Based on patch from: Hans Schillstrom.
IPVS do like conntrack i.e. use the skb->nfct_reasm
(i.e. when all fragments is collected, nf_ct_frag6_output()
starts a "re-play" of all fragments into the interrupted
PREROUTING chain at prio -399 (NF_IP6_PRI_CONNTRACK_DEFRAG+1)
with nfct_reasm pointing to the assembled packet.)
Notice, module nf_defrag_ipv6 must be loaded for this to work.
IPVS adds a new hook into prerouting chain at prio
-99 (NF_IP6_PRI_NAT_DST+1) to catch fragments, and copy fw-mark
info from the first packet with an upper layer header.
Also, for IPv6, handle all ICMPv6 NONE Informational Messages (via
ICMPV6_INFOMSG_MASK). This actually only extend our handling to
type ICMPV6_PARAMPROB (Parameter Problem), and future types.
- Fixed refcnt bug since last.
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
Signed-off-by: Hans Schillstrom <hans@schillstrom.com>
---
include/net/ip_vs.h | 16 ++++
net/netfilter/ipvs/Kconfig | 7 +-
net/netfilter/ipvs/ip_vs_conn.c | 2
net/netfilter/ipvs/ip_vs_core.c | 173 ++++++++++++++++++++++++++++-----------
net/netfilter/ipvs/ip_vs_xmit.c | 24 ++++-
5 files changed, 161 insertions(+), 61 deletions(-)
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index 8d5920f..50f377e 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -123,11 +123,27 @@ static inline struct sk_buff *skb_nfct_reasm(const struct sk_buff *skb)
{
return skb->nfct_reasm;
}
+static inline void *frag_safe_skb_hp(const struct sk_buff *skb, int offset,
+ int len, void *buffer,
+ const struct ip_vs_iphdr *ipvsh)
+{
+ if (unlikely(ipvsh->fragoffs && skb_nfct_reasm(skb)))
+ return skb_header_pointer(skb_nfct_reasm(skb), ipvsh->offs,
+ len, buffer);
+
+ return skb_header_pointer(skb, offset, len, buffer);
+}
#else
static inline struct sk_buff *skb_nfct_reasm(const struct sk_buff *skb)
{
return NULL;
}
+static inline void *frag_safe_skb_hp(const struct sk_buff *skb, int offset,
+ int len, void *buffer,
+ const struct ip_vs_iphdr *ipvsh)
+{
+ return skb_header_pointer(skb, offset, len, buffer);
+}
#endif
static inline void
diff --git a/net/netfilter/ipvs/Kconfig b/net/netfilter/ipvs/Kconfig
index 8b2cffd..0c3b167 100644
--- a/net/netfilter/ipvs/Kconfig
+++ b/net/netfilter/ipvs/Kconfig
@@ -28,12 +28,11 @@ if IP_VS
config IP_VS_IPV6
bool "IPv6 support for IPVS"
depends on IPV6 = y || IP_VS = IPV6
+ select IP6_NF_IPTABLES
---help---
- Add IPv6 support to IPVS. This is incomplete and might be dangerous.
+ Add IPv6 support to IPVS.
- See http://www.mindbasket.com/ipvs for more information.
-
- Say N if unsure.
+ Say Y if unsure.
config IP_VS_DEBUG
bool "IP virtual server debugging"
diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
index a00db99..30e764a 100644
--- a/net/netfilter/ipvs/ip_vs_conn.c
+++ b/net/netfilter/ipvs/ip_vs_conn.c
@@ -313,7 +313,7 @@ ip_vs_conn_fill_param_proto(int af, const struct sk_buff *skb,
__be16 _ports[2], *pptr;
struct net *net = skb_net(skb);
- pptr = skb_header_pointer(skb, iph->len, sizeof(_ports), _ports);
+ pptr = frag_safe_skb_hp(skb, iph->len, sizeof(_ports), _ports, iph);
if (pptr == NULL)
return 1;
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index 32c69ed..9f2e167 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -402,7 +402,7 @@ ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb,
/*
* IPv6 frags, only the first hit here.
*/
- pptr = skb_header_pointer(skb, iph->len, sizeof(_ports), _ports);
+ pptr = frag_safe_skb_hp(skb, iph->len, sizeof(_ports), _ports, iph);
if (pptr == NULL)
return NULL;
@@ -505,7 +505,7 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
int unicast;
#endif
- pptr = skb_header_pointer(skb, iph->len, sizeof(_ports), _ports);
+ pptr = frag_safe_skb_hp(skb, iph->len, sizeof(_ports), _ports, iph);
if (pptr == NULL) {
ip_vs_service_put(svc);
return NF_DROP;
@@ -651,14 +651,6 @@ static inline int ip_vs_gather_frags(struct sk_buff *skb, u_int32_t user)
return err;
}
-#ifdef CONFIG_IP_VS_IPV6
-static inline int ip_vs_gather_frags_v6(struct sk_buff *skb, u_int32_t user)
-{
- /* TODO IPv6: Find out what to do here for IPv6 */
- return 0;
-}
-#endif
-
static int ip_vs_route_me_harder(int af, struct sk_buff *skb)
{
#ifdef CONFIG_IP_VS_IPV6
@@ -729,10 +721,22 @@ void ip_vs_nat_icmp_v6(struct sk_buff *skb, struct ip_vs_protocol *pp,
struct ip_vs_conn *cp, int inout)
{
struct ipv6hdr *iph = ipv6_hdr(skb);
- unsigned int icmp_offset = sizeof(struct ipv6hdr);
- struct icmp6hdr *icmph = (struct icmp6hdr *)(skb_network_header(skb) +
- icmp_offset);
- struct ipv6hdr *ciph = (struct ipv6hdr *)(icmph + 1);
+ unsigned int icmp_offset = 0;
+ unsigned int offs = 0; /* header offset*/
+ int protocol;
+ struct icmp6hdr *icmph;
+ struct ipv6hdr *ciph;
+ unsigned short fragoffs;
+
+ ipv6_find_hdr(skb, &icmp_offset, IPPROTO_ICMPV6, &fragoffs, NULL);
+ icmph = (struct icmp6hdr *)(skb_network_header(skb) + icmp_offset);
+ offs = icmp_offset + sizeof(struct icmp6hdr);
+ ciph = (struct ipv6hdr *)(skb_network_header(skb) + offs);
+
+ protocol = ipv6_find_hdr(skb, &offs, -1, &fragoffs, NULL);
+
+ if (!skb_make_writable(skb, offs + sizeof(__u32)))
+ return;
if (inout) {
iph->saddr = cp->vaddr.in6;
@@ -743,10 +747,13 @@ void ip_vs_nat_icmp_v6(struct sk_buff *skb, struct ip_vs_protocol *pp,
}
/* the TCP/UDP/SCTP port */
- if (IPPROTO_TCP == ciph->nexthdr || IPPROTO_UDP == ciph->nexthdr ||
- IPPROTO_SCTP == ciph->nexthdr) {
- __be16 *ports = (void *)ciph + sizeof(struct ipv6hdr);
+ if (!fragoffs && (IPPROTO_TCP == protocol || IPPROTO_UDP == protocol ||
+ IPPROTO_SCTP == protocol)) {
+ __be16 *ports = (void *)(skb_network_header(skb) + offs);
+ IP_VS_DBG(11, "%s() changed port %d to %d\n", __func__,
+ ntohs(inout ? ports[1] : ports[0]),
+ ntohs(inout ? cp->vport : cp->dport));
if (inout)
ports[1] = cp->vport;
else
@@ -919,12 +926,12 @@ static int ip_vs_out_icmp_v6(struct sk_buff *skb, int *related,
union nf_inet_addr snet;
*related = 1;
-
- ic = skb_header_pointer(skb, ipvsh->len, sizeof(_icmph), &_icmph);
+ ic = frag_safe_skb_hp(skb, ipvsh->len, sizeof(_icmph), &_icmph, ipvsh);
if (ic == NULL)
return NF_DROP;
- IP_VS_DBG(12, "Outgoing ICMPv6 (%d,%d) %pI6c->%pI6c\n",
+ IP_VS_DBG(12, "Outgoing ICMPv6 %s(%d,%d) %pI6c->%pI6c\n",
+ ipvsh->flags & IP6T_FH_F_FRAG ? "Fragment " : "",
ic->icmp6_type, ntohs(icmpv6_id(ic)),
&ipvsh->saddr, &ipvsh->daddr);
@@ -935,12 +942,15 @@ static int ip_vs_out_icmp_v6(struct sk_buff *skb, int *related,
* this means that some packets will manage to get a long way
* down this stack and then be rejected, but that's life.
*/
- if ((ic->icmp6_type != ICMPV6_DEST_UNREACH) &&
- (ic->icmp6_type != ICMPV6_PKT_TOOBIG) &&
- (ic->icmp6_type != ICMPV6_TIME_EXCEED)) {
+ if (ic->icmp6_type & ICMPV6_INFOMSG_MASK) {
*related = 0;
return NF_ACCEPT;
}
+ /* Fragment header that is before ICMP header tells us that:
+ * it's not an error message since they can't be fragmented.
+ */
+ if (ipvsh->flags & IP6T_FH_F_FRAG)
+ return NF_DROP;
/* Now find the contained IP header */
ipvsh->len += sizeof(_icmph);
@@ -1095,6 +1105,12 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, int af)
ip_vs_fill_iph_skb(af, skb, &iph);
#ifdef CONFIG_IP_VS_IPV6
if (af == AF_INET6) {
+ if (!iph.fragoffs && skb_nfct_reasm(skb)) {
+ struct sk_buff *reasm = skb_nfct_reasm(skb);
+ /* Save fw mark for coming frags */
+ reasm->ipvs_property = 1;
+ reasm->mark = skb->mark;
+ }
if (unlikely(iph.protocol == IPPROTO_ICMPV6)) {
int related;
int verdict = ip_vs_out_icmp_v6(skb, &related,
@@ -1102,7 +1118,6 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, int af)
if (related)
return verdict;
- ip_vs_fill_iph_skb(af, skb, &iph);
}
} else
#endif
@@ -1112,7 +1127,6 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, int af)
if (related)
return verdict;
- ip_vs_fill_ip4hdr(skb_network_header(skb), &iph);
}
pd = ip_vs_proto_data_get(net, iph.protocol);
@@ -1145,8 +1159,8 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, int af)
pp->protocol == IPPROTO_SCTP)) {
__be16 _ports[2], *pptr;
- pptr = skb_header_pointer(skb, iph.len,
- sizeof(_ports), _ports);
+ pptr = frag_safe_skb_hp(skb, iph.len,
+ sizeof(_ports), _ports, &iph);
if (pptr == NULL)
return NF_ACCEPT; /* Not for me */
if (ip_vs_lookup_real_service(net, af, iph.protocol,
@@ -1432,20 +1446,21 @@ static int ip_vs_in_icmp_v6(struct sk_buff *skb, int *related,
unsigned int hooknum, struct ip_vs_iphdr *iph)
{
struct net *net = NULL;
+ const struct ipv6hdr _ip6h, *ip6h;
struct icmp6hdr _icmph, *ic;
struct ip_vs_iphdr ciph;
struct ip_vs_conn *cp;
struct ip_vs_protocol *pp;
struct ip_vs_proto_data *pd;
- unsigned int offset, verdict;
+ unsigned int offs_ciph, verdict;
*related = 1;
- ic = skb_header_pointer(skb, iph->len, sizeof(_icmph), &_icmph);
+ ic = frag_safe_skb_hp(skb, iph->len, sizeof(_icmph), &_icmph, iph);
if (ic == NULL)
return NF_DROP;
- IP_VS_DBG(12, "Incoming ICMPv6 (%d,%d) %pI6c->%pI6c\n",
+ IP_VS_DBG(12, "Incoming ICMPv6 %d(%d,%d) %pI6c->%pI6c\n", hooknum,
ic->icmp6_type, ntohs(icmpv6_id(ic)),
&iph->saddr, &iph->daddr);
@@ -1456,51 +1471,64 @@ static int ip_vs_in_icmp_v6(struct sk_buff *skb, int *related,
* this means that some packets will manage to get a long way
* down this stack and then be rejected, but that's life.
*/
- if ((ic->icmp6_type != ICMPV6_DEST_UNREACH) &&
- (ic->icmp6_type != ICMPV6_PKT_TOOBIG) &&
- (ic->icmp6_type != ICMPV6_TIME_EXCEED)) {
+ if (ic->icmp6_type & ICMPV6_INFOMSG_MASK) {
*related = 0;
return NF_ACCEPT;
}
+ /* Fragment header that is before ICMP header tells us that:
+ * it's not an error message since they can't be fragmented.
+ */
+ if (iph->flags & IP6T_FH_F_FRAG)
+ return NF_DROP;
/* Now find the contained IP header */
ciph.len = iph->len + sizeof(_icmph);
ciph.flags = 0;
ciph.fragoffs = 0;
+ offs_ciph = ciph.len; /* Save ip header offset */
+ ip6h = skb_header_pointer(skb, ciph.len, sizeof(_ip6h),
+ (void *)&_ip6h);
ciph.protocol = ipv6_find_hdr(skb, &ciph.len, -1, &ciph.fragoffs,
&ciph.flags);
- ciph.saddr = iph->saddr; /* con_in_get() handles reverse order */
- ciph.daddr = iph->daddr;
+ ciph.saddr.in6 = ip6h->saddr; /* con_in_get() handles reverse order */
+ ciph.daddr.in6 = ip6h->daddr;
net = skb_net(skb);
pd = ip_vs_proto_data_get(net, ciph.protocol);
- if (!pd)
- return NF_ACCEPT;
- pp = pd->pp;
- /* Is the embedded protocol header present?
- * If it's the second or later fragment we don't know what it is
+ /* Is not the embedded protocol header present?
+ * or it's the second or later fragment we don't know what it is
* i.e. just let it through.
*/
- if (ciph.fragoffs)
+ if (!pd || ciph.fragoffs)
return NF_ACCEPT;
+ pp = pd->pp;
- offset = ciph.len;
- IP_VS_DBG_PKT(11, AF_INET6, pp, skb, offset,
+ IP_VS_DBG_PKT(11, AF_INET6, pp, skb, offs_ciph,
"Checking incoming ICMPv6 for");
- /* The embedded headers contain source and dest in reverse order */
- cp = pp->conn_in_get(AF_INET6, skb, &ciph, 1);
+ /* The embedded headers contain source and dest in reverse order
+ * if not from localhost
+ */
+ cp = pp->conn_in_get(AF_INET6, skb, &ciph,
+ (hooknum == NF_INET_LOCAL_OUT) ? 0 : 1);
+
if (!cp)
return NF_ACCEPT;
+ /* VS/TUN, VS/DR and LOCALNODE just let it go */
+ if ((hooknum == NF_INET_LOCAL_OUT) &&
+ (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ)) {
+ __ip_vs_conn_put(cp);
+ return NF_ACCEPT;
+ }
/* do the statistics and put it back */
ip_vs_in_stats(cp, skb);
if (IPPROTO_TCP == ciph.protocol || IPPROTO_UDP == ciph.protocol ||
IPPROTO_SCTP == ciph.protocol)
- offset = ciph.len + (2 * sizeof(__u16));
+ offs_ciph = ciph.len;
- verdict = ip_vs_icmp_xmit_v6(skb, cp, pp, offset, hooknum, &ciph);
+ verdict = ip_vs_icmp_xmit_v6(skb, cp, pp, offs_ciph, hooknum, &ciph);
__ip_vs_conn_put(cp);
@@ -1562,6 +1590,12 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
#ifdef CONFIG_IP_VS_IPV6
if (af == AF_INET6) {
+ if (!iph.fragoffs && skb_nfct_reasm(skb)) {
+ struct sk_buff *reasm = skb_nfct_reasm(skb);
+ /* Save fw mark for coming frags. */
+ reasm->ipvs_property = 1;
+ reasm->mark = skb->mark;
+ }
if (unlikely(iph.protocol == IPPROTO_ICMPV6)) {
int related;
int verdict = ip_vs_in_icmp_v6(skb, &related, hooknum,
@@ -1587,12 +1621,12 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
pp = pd->pp;
/*
* Check if the packet belongs to an existing connection entry
- * Only sched first IPv6 fragment.
*/
cp = pp->conn_in_get(af, skb, &iph, 0);
- if (unlikely(!cp) && !iph.fragoffs) {
+ if (unlikely(!cp)) {
int v;
+ /* Schedule and create new connection entry into &cp */
if (!pp->conn_schedule(af, skb, pd, &v, &cp, &iph))
return v;
}
@@ -1685,6 +1719,39 @@ ip_vs_local_request4(unsigned int hooknum, struct sk_buff *skb,
#ifdef CONFIG_IP_VS_IPV6
/*
+ * AF_INET6 fragment handling
+ * Copy info from first fragment, to the rest of them.
+ */
+static unsigned int
+ip_vs_preroute_frag6(unsigned int hooknum, struct sk_buff *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ struct ip_vs_iphdr iphdr = { .len = 0, .flags = 0, };
+ struct sk_buff *reasm = skb_nfct_reasm(skb);
+ struct net *net;
+
+ /* Skip if not a "replay" from nf_ct_frag6_output or first fragment.
+ * ipvs_property is set when checking first fragment
+ * in ip_vs_in() and ip_vs_out().
+ */
+ if (reasm)
+ IP_VS_DBG(2, "Fragment recv prop:%d\n", reasm->ipvs_property);
+ if (!reasm || !reasm->ipvs_property)
+ return NF_ACCEPT;
+
+ net = skb_net(skb);
+ if (!net_ipvs(net)->enable)
+ return NF_ACCEPT;
+
+ /* Copy stored fw mark, saved in ip_vs_{in,out} */
+ skb->mark = reasm->mark;
+
+ return NF_ACCEPT;
+}
+
+/*
* AF_INET6 handler in NF_INET_LOCAL_IN chain
* Schedule and forward packets from remote clients
*/
@@ -1823,6 +1890,14 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
.priority = 100,
},
#ifdef CONFIG_IP_VS_IPV6
+ /* After mangle & nat fetch 2:nd fragment and following */
+ {
+ .hook = ip_vs_preroute_frag6,
+ .owner = THIS_MODULE,
+ .pf = NFPROTO_IPV6,
+ .hooknum = NF_INET_PRE_ROUTING,
+ .priority = NF_IP6_PRI_NAT_DST + 1,
+ },
/* After packet filtering, change source only for VS/NAT */
{
.hook = ip_vs_reply6,
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index 925cca2..422b92f 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -497,7 +497,9 @@ ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
skb->dev = net->loopback_dev;
}
- icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
+ /* only send ICMP too big on first fragment */
+ if (!iph->fragoffs)
+ icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
dst_release(&rt->dst);
IP_VS_DBG_RL("%s(): frag needed\n", __func__);
goto tx_error;
@@ -667,7 +669,7 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
EnterFunction(10);
/* check if it is a connection of no-client-port */
- if (unlikely(cp->flags & IP_VS_CONN_F_NO_CPORT)) {
+ if (unlikely(cp->flags & IP_VS_CONN_F_NO_CPORT && !iph->fragoffs)) {
__be16 _pt, *p;
p = skb_header_pointer(skb, iph->len, sizeof(_pt), &_pt);
if (p == NULL)
@@ -693,7 +695,7 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
if (ct && !nf_ct_is_untracked(ct)) {
IP_VS_DBG_RL_PKT(10, AF_INET6, pp, skb, 0,
- "ip_vs_nat_xmit_v6(): "
+ "ip_vs_nat_xmit_v6(): "\
"stopping DNAT to local address");
goto tx_error_put;
}
@@ -717,7 +719,9 @@ ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
skb->dev = net->loopback_dev;
}
- icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
+ /* only send ICMP too big on first fragment */
+ if (!iph->fragoffs)
+ icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
IP_VS_DBG_RL_PKT(0, AF_INET6, pp, skb, 0,
"ip_vs_nat_xmit_v6(): frag needed for");
goto tx_error_put;
@@ -952,7 +956,9 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
skb->dev = net->loopback_dev;
}
- icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
+ /* only send ICMP too big on first fragment */
+ if (!ipvsh->fragoffs)
+ icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
IP_VS_DBG_RL("%s(): frag needed\n", __func__);
goto tx_error_put;
}
@@ -1118,7 +1124,9 @@ ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
skb->dev = net->loopback_dev;
}
- icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
+ /* only send ICMP too big on first fragment */
+ if (!iph->fragoffs)
+ icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
dst_release(&rt->dst);
IP_VS_DBG_RL("%s(): frag needed\n", __func__);
goto tx_error;
@@ -1356,7 +1364,9 @@ ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
skb->dev = net->loopback_dev;
}
- icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
+ /* only send ICMP too big on first fragment */
+ if (!iph->fragoffs)
+ icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
IP_VS_DBG_RL("%s(): frag needed\n", __func__);
goto tx_error_put;
}
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox