* Re: SYN attack, with FIN flag set
From: Denys Fedoryshchenko @ 2011-12-03 9:07 UTC (permalink / raw)
To: Michael Tokarev; +Cc: Eric Dumazet, netdev
In-Reply-To: <4ED9E5FA.30204@msgid.tls.msk.ru>
On Sat, 03 Dec 2011 13:03:54 +0400, Michael Tokarev wrote:
> On 03.12.2011 12:53, Eric Dumazet wrote:
> []
>> TCP stack first tries to lookup a socket, given the tuple found in
>> incoming packet.
>>
>> This is where your machine is hit : we find the listener socket and
>> lock
>> it.
>>
>> Then, once socket was found and locked, state machine handle various
>> possible states.
>>
>> In your case, you want to bypass the lookup, and eventually bypass
>> the
>> IP route lookup as well (to keep IP route cache small)
>>
>> iptables -t raw -I PREROUTING -p tcp --tcp-flags SYN,FIN SYN,FIN -j
>> DROP
>
> Maybe it makes some sence to add a basic "sanity" check rule
> before the socket lookup?
>
> The question here is why SYN+FIN results in worse behavour than
> SYN alone - in the default setup, without iptables rules? As
> far as I understand, "regular" SYN attack is handled just fine,
> but SYN+FIN attack makes the machine to "choke", and it is not
> obvious how to fix it -- naive --syn iptables rule does not help.
>
> The price for the sanity check appears to be small since there's
> already a check for RST.
>
> Just asking, not suggesting anything... ;)
>
> Thanks,
>
> /mjt
No,no, as i understand it is just threating SYN+FIN as plain SYN.
I think if it incurr additional expenses (verification), no need maybe
to fix it, it is job of iptables.
But is FIN to listening socket - legitimate? Shouldn't it be dropped?
---
System administrator
Denys Fedoryshchenko
Virtual ISP S.A.L.
^ permalink raw reply
* Re: SYN attack, with FIN flag set
From: Michael Tokarev @ 2011-12-03 9:03 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Denys Fedoryshchenko, netdev
In-Reply-To: <1322902401.2762.85.camel@edumazet-laptop>
On 03.12.2011 12:53, Eric Dumazet wrote:
[]
> TCP stack first tries to lookup a socket, given the tuple found in
> incoming packet.
>
> This is where your machine is hit : we find the listener socket and lock
> it.
>
> Then, once socket was found and locked, state machine handle various
> possible states.
>
> In your case, you want to bypass the lookup, and eventually bypass the
> IP route lookup as well (to keep IP route cache small)
>
> iptables -t raw -I PREROUTING -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
Maybe it makes some sence to add a basic "sanity" check rule
before the socket lookup?
The question here is why SYN+FIN results in worse behavour than
SYN alone - in the default setup, without iptables rules? As
far as I understand, "regular" SYN attack is handled just fine,
but SYN+FIN attack makes the machine to "choke", and it is not
obvious how to fix it -- naive --syn iptables rule does not help.
The price for the sanity check appears to be small since there's
already a check for RST.
Just asking, not suggesting anything... ;)
Thanks,
/mjt
^ permalink raw reply
* Re: SYN attack, with FIN flag set
From: Eric Dumazet @ 2011-12-03 8:53 UTC (permalink / raw)
To: Denys Fedoryshchenko; +Cc: netdev
In-Reply-To: <b3ae04aef6b0ce233e8e8978782d1ccc@visp.net.lb>
Le samedi 03 décembre 2011 à 10:18 +0200, Denys Fedoryshchenko a écrit :
> On Sat, 03 Dec 2011 08:55:02 +0100, Eric Dumazet wrote:
> > Le samedi 03 décembre 2011 à 08:27 +0100, Eric Dumazet a écrit :
> >
> >> I believe netfilter tcp conntrack considers SYN|FIN as INVALID
> >>
> >
> > Or if you cannot afford conntracking, just do
> >
> > iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
>
> Sure i did,thanks, but i just was curious, why connection with such
> flags are threated as SYN.
>
TCP stack first tries to lookup a socket, given the tuple found in
incoming packet.
This is where your machine is hit : we find the listener socket and lock
it.
Then, once socket was found and locked, state machine handle various
possible states.
In your case, you want to bypass the lookup, and eventually bypass the
IP route lookup as well (to keep IP route cache small)
iptables -t raw -I PREROUTING -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
^ permalink raw reply
* [PATCH] iwlegacy: Use kcalloc instead of kzalloc to allocate array
From: Thomas Meyer @ 2011-11-29 21:08 UTC (permalink / raw)
To: linville, linux-wireless, netdev, linux-kernel
The advantage of kcalloc is, that will prevent integer overflows which could
result from the multiplication of number of elements and size and it is also
a bit nicer to read.
The semantic patch that makes this change is available
in https://lkml.org/lkml/2011/11/25/107
Signed-off-by: Thomas Meyer <thomas@m3y3r.de>
---
diff -u -p a/drivers/net/wireless/iwlegacy/iwl-tx.c b/drivers/net/wireless/iwlegacy/iwl-tx.c
--- a/drivers/net/wireless/iwlegacy/iwl-tx.c 2011-11-13 11:07:38.540345582 +0100
+++ b/drivers/net/wireless/iwlegacy/iwl-tx.c 2011-11-28 19:55:42.036442592 +0100
@@ -297,8 +297,8 @@ static int iwl_legacy_tx_queue_alloc(str
/* Driver private data, only for Tx (not command) queues,
* not shared with device. */
if (id != priv->cmd_queue) {
- txq->txb = kzalloc(sizeof(txq->txb[0]) *
- TFD_QUEUE_SIZE_MAX, GFP_KERNEL);
+ txq->txb = kcalloc(TFD_QUEUE_SIZE_MAX, sizeof(txq->txb[0]),
+ GFP_KERNEL);
if (!txq->txb) {
IWL_ERR(priv, "kmalloc for auxiliary BD "
"structures failed\n");
^ permalink raw reply
* Re: SYN attack, with FIN flag set
From: Denys Fedoryshchenko @ 2011-12-03 8:18 UTC (permalink / raw)
To: Eric Dumazet; +Cc: netdev
In-Reply-To: <1322898902.2762.81.camel@edumazet-laptop>
On Sat, 03 Dec 2011 08:55:02 +0100, Eric Dumazet wrote:
> Le samedi 03 décembre 2011 à 08:27 +0100, Eric Dumazet a écrit :
>
>> I believe netfilter tcp conntrack considers SYN|FIN as INVALID
>>
>
> Or if you cannot afford conntracking, just do
>
> iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
Sure i did,thanks, but i just was curious, why connection with such
flags are threated as SYN.
---
System administrator
Denys Fedoryshchenko
Virtual ISP S.A.L.
^ permalink raw reply
* Re: SYN attack, with FIN flag set
From: Eric Dumazet @ 2011-12-03 7:55 UTC (permalink / raw)
To: Denys Fedoryshchenko; +Cc: netdev
In-Reply-To: <1322897233.2762.79.camel@edumazet-laptop>
Le samedi 03 décembre 2011 à 08:27 +0100, Eric Dumazet a écrit :
> I believe netfilter tcp conntrack considers SYN|FIN as INVALID
>
Or if you cannot afford conntracking, just do
iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
^ permalink raw reply
* Re: [PATCH 2/9] infiniband: addr: Consolidate code to fetch neighbout hardware address from dst.
From: Eric Dumazet @ 2011-12-03 7:30 UTC (permalink / raw)
To: David Miller; +Cc: roland, netdev
In-Reply-To: <20111202.215214.2206154836146990479.davem@davemloft.net>
Le vendredi 02 décembre 2011 à 21:52 -0500, David Miller a écrit :
> IPV4 should do exactly what the IPV6 code does here, which is
> use the neighbour obtained via the dst entry.
>
> And now that the two code paths do the same thing, use a common
> helper function to perform the operation.
>
> Signed-off-by: David S. Miller <davem@davemloft.net>
> ---
> drivers/infiniband/core/addr.c | 47 +++++++++++++++++----------------------
> 1 files changed, 21 insertions(+), 26 deletions(-)
Acked-by: Eric Dumazet <eric.dumazet@gmail.com>
^ permalink raw reply
* Re: SYN attack, with FIN flag set
From: Eric Dumazet @ 2011-12-03 7:27 UTC (permalink / raw)
To: Denys Fedoryshchenko; +Cc: netdev
In-Reply-To: <1755dc626dee301261ef4fe4cd66fd47@visp.net.lb>
Le samedi 03 décembre 2011 à 00:29 +0200, Denys Fedoryshchenko a écrit :
> Hi
>
> Recently i started to get SYN attacks, and managed them.
> syncookies didn't helped, here is "perf report" info:
> - 26.89% swapper [kernel.kallsyms] [k] _raw_spin_lock
> - _raw_spin_lock
> - 94.97% tcp_v4_rcv
> ip_local_deliver_finish
> ip_local_deliver
> ip_rcv_finish
> ip_rcv
> __netif_receive_skb
> process_backlog
> net_rx_action
> __do_softirq
> call_softirq
> do_softirq
> + irq_exit
>
> But then i got attack that made server to choke and bypassed "--syn"
> rule, and i was surprised, that stack are handling invalid combination
> of flags, SYN+FIN.
> Is it valid behaviour?
>
> in tcp_input.c, tcp_rcv_state_process(), it just does check for rst (to
> discard), but maybe packet with fin set should be discarded too?
I believe netfilter tcp conntrack considers SYN|FIN as INVALID
Yes, we could drop SYN|FIN messages, but what prevents attacker to just
use SYN messages to attack your machine ?
^ permalink raw reply
* Re: [PATCH net-next] r8169: Support for byte queue limits
From: Eric Dumazet @ 2011-12-03 6:48 UTC (permalink / raw)
To: igorm
Cc: netdev, davem, Realtek linux nic maintainers, Francois Romieu,
Tom Herbert
In-Reply-To: <CAFdo_mUZembr4MEGUt9efNtfnuCs4ddHUCDjLE64WnWwytTpzw@mail.gmail.com>
Le vendredi 02 décembre 2011 à 22:54 +0100, Igor Maravić a écrit :
> >
> > Reread what I said : "BQL must be lightweight"
> >
> > Not : "No lock should be used"
> >
> > OK ?
> >
>
> I'm out of ideas.
>
> Do you think, if I remove netdev_reset_queue(tp->dev); from
> rtl8169_init_ring_indexes,
> and spin_locks, of course, that would be a good solution.
>
> As far as I could see in marvell/sky2.c, sfc/tx.c and intel/e1000e/netdev.c
> netdev_completed is called with out any lock.
> Please correct me if I'm wrong.
These drivers have a clean and separate start_xmit() and xmit_completion
path, each one being correctly serialized. No extra lock needed.
In the case of r8169, we are still trying to get the driver in a clean
state (without races).
Then, we'll add BQL, and it will be as easy as other drivers.
^ permalink raw reply
* Re: [PATCH] ipv4: make sure RTO_ONLINK is saved in routing cache
From: David Miller @ 2011-12-03 6:32 UTC (permalink / raw)
To: ja; +Cc: netdev
In-Reply-To: <1322861982-3780-1-git-send-email-ja@ssi.bg>
From: Julian Anastasov <ja@ssi.bg>
Date: Fri, 2 Dec 2011 23:39:42 +0200
> __mkroute_output fails to work with the original tos
> and uses value with stripped RTO_ONLINK bit. Make sure we put
> the original TOS bits into rt_key_tos because it used to match
> cached route.
>
> Signed-off-by: Julian Anastasov <ja@ssi.bg>
Applied, thanks a lot Julian.
^ permalink raw reply
* [BUG] net: kernel BUG at include/net/netns/generic.h:40!
From: Sasha Levin @ 2011-12-03 6:06 UTC (permalink / raw)
To: linux-kernel, netdev
Hi all,
I got the following when trying a clone():
[ 126.413983] ------------[ cut here ]------------
[ 126.414023] kernel BUG at include/net/netns/generic.h:40!
[ 126.414023] invalid opcode: 0000 [#1] PREEMPT SMP
[ 126.414023] CPU 0
[ 126.414023] Pid: 2507, comm: trinity Not tainted 3.2.0-rc3-next-20111202-sasha-00003-gc9d4348 #17
[ 126.414023] RIP: 0010:[<ffffffff8235762e>] [<ffffffff8235762e>] get_cfcnfg+0xee/0x100
[ 126.414023] RSP: 0018:ffff88001108db00 EFLAGS: 00010212
[ 126.414023] RAX: 0000000000000001 RBX: 0000000000000010 RCX: 0000000000000000
[ 126.414023] RDX: 0000000000000001 RSI: ffffffff82c1ff20 RDI: 0000000000000282
[ 126.414023] RBP: ffff88001108db20 R08: 0000000000000003 R09: 0000000000000001
[ 126.414023] R10: 0000000000000000 R11: 0000000000000001 R12: ffff88001107ed80
[ 126.414023] R13: ffffffff82db4b20 R14: 0000000000000000 R15: 0000000000000010
[ 126.414023] FS: 00007f77a32d7700(0000) GS:ffff880013a00000(0000) knlGS:0000000000000000
[ 126.414023] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
[ 126.414023] CR2: 00007f77a2e054d0 CR3: 0000000011029000 CR4: 00000000000006f0
[ 126.414023] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 126.414023] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[ 126.414023] Process trinity (pid: 2507, threadinfo ffff88001108c000, task ffff8800115c1610)
[ 126.414023] Stack:
[ 126.414023] ffffffff82357557 ffffffff8203cc20 ffff8800110b4000 00000000ffffffd9
[ 126.414023] ffff88001108db80 ffffffff823579ae ffff88001108db80 ffffffff8216292d
[ 126.414023] 0000000000000001 ffff8800115c1610 ffff88001108db80 ffff8800110b4000
[ 126.414023] Call Trace:
[ 126.414023] [<ffffffff82357557>] ? get_cfcnfg+0x17/0x100
[ 126.414023] [<ffffffff8203cc20>] ? lockdep_rtnl_is_held+0x10/0x20
[ 126.414023] [<ffffffff823579ae>] caif_device_notify+0x2e/0x380
[ 126.414023] [<ffffffff8216292d>] ? packet_notifier+0x19d/0x220
[ 126.414023] [<ffffffff810d5a73>] notifier_call_chain+0x93/0xf0
[ 126.414023] [<ffffffff810d5fd1>] raw_notifier_call_chain+0x11/0x20
[ 126.414023] [<ffffffff820296d2>] call_netdevice_notifiers+0x32/0x60
[ 126.414023] [<ffffffff82030c06>] register_netdevice+0x196/0x300
[ 126.414023] [<ffffffff82030d89>] register_netdev+0x19/0x30
[ 126.414023] [<ffffffff81afe29a>] loopback_net_init+0x4a/0xa0
[ 126.414023] [<ffffffff82024c92>] ops_init+0x42/0x180
[ 126.414023] [<ffffffff82024e3b>] setup_net+0x6b/0x100
[ 126.414023] [<ffffffff82025296>] copy_net_ns+0x86/0x110
[ 126.414023] [<ffffffff810d5009>] create_new_namespaces+0xd9/0x190
[ 126.414023] [<ffffffff810d51d4>] copy_namespaces+0x84/0xc0
[ 126.414023] [<ffffffff810d343c>] ? __mutex_init+0x5c/0x70
[ 126.414023] [<ffffffff810ad531>] copy_process+0xa31/0x1490
[ 126.414023] [<ffffffff810ae043>] do_fork+0x73/0x350
[ 126.414023] [<ffffffff810e828d>] ? trace_hardirqs_on+0xd/0x10
[ 126.414023] [<ffffffff823e361d>] ? retint_swapgs+0x13/0x1b
[ 126.414023] [<ffffffff8104bd63>] sys_clone+0x23/0x30
[ 126.414023] [<ffffffff823e4273>] stub_clone+0x13/0x20
[ 126.414023] [<ffffffff823e3ed2>] ? system_call_fastpath+0x16/0x1b
[ 126.414023] Code: 20 d9 fe 85 c0 75 8f 48 c7 c2 68 62 93 82 be 27 00 00 00 48 c7 c7 fa 49 a2 82 c6 05 a0 f2 bc 01 01 e8 47 5e d9 fe e9 6b ff ff ff <0f> 0b 0f 0b 66 66 66 66 66 2e 0f 1f 84 00 00 00 00 00 55 48 89
[ 126.414023] RIP [<ffffffff8235762e>] get_cfcnfg+0xee/0x100
[ 126.414023] RSP <ffff88001108db00>
[ 126.475257] ---[ end trace c62732ec90be8c83 ]---
Please let me know if I can help debugging this issue.
--
Sasha.
^ permalink raw reply
* Re: [PATCH] ARM: at91/net: add macb ethernet controller in 9g45 DT
From: Jean-Christophe PLAGNIOL-VILLARD @ 2011-12-03 5:56 UTC (permalink / raw)
To: Nicolas Ferre
Cc: netdev, devicetree-discuss, linux-kernel, grant.likely, jamie,
linux-arm-kernel
In-Reply-To: <1322848237-23154-1-git-send-email-nicolas.ferre@atmel.com>
On 18:50 Fri 02 Dec , Nicolas Ferre wrote:
> Add the Cadence macb ethernet controller in at91sam9g45 .dtsi and
> enable it in at91sam9m10g45ek board device tree file.
>
> Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
> ---
> arch/arm/boot/dts/at91sam9g45.dtsi | 7 +++++++
> arch/arm/boot/dts/at91sam9m10g45ek.dts | 6 ++++++
> 2 files changed, 13 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi
> index e89b1d7..67f94d3 100644
> --- a/arch/arm/boot/dts/at91sam9g45.dtsi
> +++ b/arch/arm/boot/dts/at91sam9g45.dtsi
> @@ -101,6 +101,13 @@
> atmel,use-dma-tx;
> status = "disabled";
> };
> +
> + macb0: ethernet@fffbc000 {
> + compatible = "cdns,at32ap7000-macb", "cdns,macb";
> + reg = <0xfffbc000 0x100>;
> + interrupts = <25 4>;
why?
> + status = "disabled";
> + };
> };
> };
> };
> diff --git a/arch/arm/boot/dts/at91sam9m10g45ek.dts b/arch/arm/boot/dts/at91sam9m10g45ek.dts
> index 85b34f5..17377a2 100644
> --- a/arch/arm/boot/dts/at91sam9m10g45ek.dts
> +++ b/arch/arm/boot/dts/at91sam9m10g45ek.dts
> @@ -30,6 +30,12 @@
> usart1: serial@fff90000 {
> status = "okay";
> };
> +
> + macb0: ethernet@fffbc000 {
> + local-mac-address = [3a 0e 03 04 05 06];
please drop this is not supposed to be in the dts but updated for each board
Best Regards,
J.
^ permalink raw reply
* Re: Udp packets received with improper length
From: David Miller @ 2011-12-03 2:54 UTC (permalink / raw)
To: gerrit; +Cc: fsmail, netdev
In-Reply-To: <20111203023256.GA4259@gerrit.erg.abdn.ac.uk>
From: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Date: Fri, 2 Dec 2011 19:32:57 -0700
> You are correct. What I had failed to see is the try_again case with
> multiple corruped datagrams. In this case the code is not correct,
> len could already have been modified in the previous
> iteration. Reverting the commit is the sanest option. Thank you.
Thanks for confirming my analysis.
^ permalink raw reply
* [PATCH 9/9] infiniband: ipoib: Sanitize neighbour handling in ipoib_main.c
From: David Miller @ 2011-12-03 2:52 UTC (permalink / raw)
To: roland; +Cc: netdev
Reduce the number of dst_get_neighbour_noref() calls within a single
call chain. Primarily by passing the neighbour pointer down to the
helper functions.
Handle dst_get_neighbour_noref() returning NULL in ipoib_start_xmit()
by incrementing the dropped counter and freeing the packet. We don't
want it to fall through into the ARP/RARP/multicast handling, since
that should only happen when skb_dst() is NULL.
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/infiniband/ulp/ipoib/ipoib_main.c | 24 ++++++++++++------------
1 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index eef6786..3514ca0 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -556,15 +556,13 @@ static int path_rec_start(struct net_device *dev,
}
/* called with rcu_read_lock */
-static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
+static void neigh_add_path(struct sk_buff *skb, struct neighbour *n, struct net_device *dev)
{
struct ipoib_dev_priv *priv = netdev_priv(dev);
struct ipoib_path *path;
struct ipoib_neigh *neigh;
- struct neighbour *n;
unsigned long flags;
- n = dst_get_neighbour_noref(skb_dst(skb));
neigh = ipoib_neigh_alloc(n, skb->dev);
if (!neigh) {
++dev->stats.tx_dropped;
@@ -638,16 +636,13 @@ err_drop:
}
/* called with rcu_read_lock */
-static void ipoib_path_lookup(struct sk_buff *skb, struct net_device *dev)
+static void ipoib_path_lookup(struct sk_buff *skb, struct neighbour *n, struct net_device *dev)
{
struct ipoib_dev_priv *priv = netdev_priv(skb->dev);
- struct dst_entry *dst = skb_dst(skb);
- struct neighbour *n;
/* Look up path record for unicasts */
- n = dst_get_neighbour_noref(dst);
if (n->ha[4] != 0xff) {
- neigh_add_path(skb, dev);
+ neigh_add_path(skb, n, dev);
return;
}
@@ -723,12 +718,17 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
unsigned long flags;
rcu_read_lock();
- if (likely(skb_dst(skb)))
+ if (likely(skb_dst(skb))) {
n = dst_get_neighbour_noref(skb_dst(skb));
-
+ if (!n) {
+ ++dev->stats.tx_dropped;
+ dev_kfree_skb_any(skb);
+ goto unlock;
+ }
+ }
if (likely(n)) {
if (unlikely(!*to_ipoib_neigh(n))) {
- ipoib_path_lookup(skb, dev);
+ ipoib_path_lookup(skb, n, dev);
goto unlock;
}
@@ -751,7 +751,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
list_del(&neigh->list);
ipoib_neigh_free(dev, neigh);
spin_unlock_irqrestore(&priv->lock, flags);
- ipoib_path_lookup(skb, dev);
+ ipoib_path_lookup(skb, n, dev);
goto unlock;
}
--
1.7.7.3
^ permalink raw reply related
* [PATCH 8/9] cxgb4i: Handle dst_get_neighbour_noref() returning NULL.
From: David Miller @ 2011-12-03 2:52 UTC (permalink / raw)
To: roland; +Cc: netdev
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/scsi/cxgbi/cxgb4i/cxgb4i.c | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
index c8fd13a..5a4a3bf 100644
--- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
+++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
@@ -1127,6 +1127,7 @@ static int init_act_open(struct cxgbi_sock *csk)
struct net_device *ndev = cdev->ports[csk->port_id];
struct port_info *pi = netdev_priv(ndev);
struct sk_buff *skb = NULL;
+ struct neighbour *n;
unsigned int step;
log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK,
@@ -1141,7 +1142,12 @@ static int init_act_open(struct cxgbi_sock *csk)
cxgbi_sock_set_flag(csk, CTPF_HAS_ATID);
cxgbi_sock_get(csk);
- csk->l2t = cxgb4_l2t_get(lldi->l2t, dst_get_neighbour_noref(csk->dst), ndev, 0);
+ n = dst_get_neighbour_noref(csk->dst);
+ if (!n) {
+ pr_err("%s, can't get neighbour of csk->dst.\n", ndev->name);
+ goto rel_resource;
+ }
+ csk->l2t = cxgb4_l2t_get(lldi->l2t, n, ndev, 0);
if (!csk->l2t) {
pr_err("%s, cannot alloc l2t.\n", ndev->name);
goto rel_resource;
--
1.7.7.3
^ permalink raw reply related
* [PATCH 7/9] libcxgbi: Handle dst_get_neighbour_noref() returning NULL.
From: David Miller @ 2011-12-03 2:52 UTC (permalink / raw)
To: roland; +Cc: netdev
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/scsi/cxgbi/libcxgbi.c | 10 ++++++++--
1 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c
index a026a2f..1d25a87 100644
--- a/drivers/scsi/cxgbi/libcxgbi.c
+++ b/drivers/scsi/cxgbi/libcxgbi.c
@@ -472,6 +472,7 @@ static struct cxgbi_sock *cxgbi_check_route(struct sockaddr *dst_addr)
struct net_device *ndev;
struct cxgbi_device *cdev;
struct rtable *rt = NULL;
+ struct neighbour *n;
struct flowi4 fl4;
struct cxgbi_sock *csk = NULL;
unsigned int mtu = 0;
@@ -493,7 +494,12 @@ static struct cxgbi_sock *cxgbi_check_route(struct sockaddr *dst_addr)
goto err_out;
}
dst = &rt->dst;
- ndev = dst_get_neighbour_noref(dst)->dev;
+ n = dst_get_neighbour_noref(dst);
+ if (!n) {
+ err = -ENODEV;
+ goto rel_rt;
+ }
+ ndev = n->dev;
if (rt->rt_flags & (RTCF_MULTICAST | RTCF_BROADCAST)) {
pr_info("multi-cast route %pI4, port %u, dev %s.\n",
@@ -507,7 +513,7 @@ static struct cxgbi_sock *cxgbi_check_route(struct sockaddr *dst_addr)
ndev = ip_dev_find(&init_net, daddr->sin_addr.s_addr);
mtu = ndev->mtu;
pr_info("rt dev %s, loopback -> %s, mtu %u.\n",
- dst_get_neighbour_noref(dst)->dev->name, ndev->name, mtu);
+ n->dev->name, ndev->name, mtu);
}
cdev = cxgbi_device_find_by_netdev(ndev, &port);
--
1.7.7.3
^ permalink raw reply related
* [PATCH 6/9] infiniband: cxgb4: Consolidate 3 copies of the same operation into 1 helper function.
From: David Miller @ 2011-12-03 2:52 UTC (permalink / raw)
To: roland; +Cc: netdev
Three pieces of code do the same thing, create a l2t entry and then
import this information into the c4iw_ep object.
Create a helper function and call it from these 3 locations instead.
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/infiniband/hw/cxgb4/cm.c | 220 ++++++++++++++------------------------
1 files changed, 80 insertions(+), 140 deletions(-)
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c
index e61c802..0668bb3 100644
--- a/drivers/infiniband/hw/cxgb4/cm.c
+++ b/drivers/infiniband/hw/cxgb4/cm.c
@@ -1556,6 +1556,67 @@ static void get_4tuple(struct cpl_pass_accept_req *req,
return;
}
+static int import_ep(struct c4iw_ep *ep, __be32 peer_ip, struct dst_entry *dst,
+ struct c4iw_dev *cdev, bool clear_mpa_v1)
+{
+ struct neighbour *n;
+ int err, step;
+
+ rcu_read_lock();
+ n = dst_get_neighbour_noref(dst);
+ err = -ENODEV;
+ if (!n)
+ goto out;
+ err = -ENOMEM;
+ if (n->dev->flags & IFF_LOOPBACK) {
+ struct net_device *pdev;
+
+ pdev = ip_dev_find(&init_net, peer_ip);
+ ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t,
+ n, pdev, 0);
+ if (!ep->l2t)
+ goto out;
+ ep->mtu = pdev->mtu;
+ ep->tx_chan = cxgb4_port_chan(pdev);
+ ep->smac_idx = (cxgb4_port_viid(pdev) & 0x7F) << 1;
+ step = cdev->rdev.lldi.ntxq /
+ cdev->rdev.lldi.nchan;
+ ep->txq_idx = cxgb4_port_idx(pdev) * step;
+ step = cdev->rdev.lldi.nrxq /
+ cdev->rdev.lldi.nchan;
+ ep->ctrlq_idx = cxgb4_port_idx(pdev);
+ ep->rss_qid = cdev->rdev.lldi.rxq_ids[
+ cxgb4_port_idx(pdev) * step];
+ dev_put(pdev);
+ } else {
+ ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t,
+ n, n->dev, 0);
+ if (!ep->l2t)
+ goto out;
+ ep->mtu = dst_mtu(ep->dst);
+ ep->tx_chan = cxgb4_port_chan(n->dev);
+ ep->smac_idx = (cxgb4_port_viid(n->dev) & 0x7F) << 1;
+ step = cdev->rdev.lldi.ntxq /
+ cdev->rdev.lldi.nchan;
+ ep->txq_idx = cxgb4_port_idx(n->dev) * step;
+ ep->ctrlq_idx = cxgb4_port_idx(n->dev);
+ step = cdev->rdev.lldi.nrxq /
+ cdev->rdev.lldi.nchan;
+ ep->rss_qid = cdev->rdev.lldi.rxq_ids[
+ cxgb4_port_idx(n->dev) * step];
+
+ if (clear_mpa_v1) {
+ ep->retry_with_mpa_v1 = 0;
+ ep->tried_with_mpa_v1 = 0;
+ }
+ }
+ err = 0;
+out:
+ rcu_read_unlock();
+
+ return err;
+}
+
static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb)
{
struct c4iw_ep *child_ep, *parent_ep;
@@ -1563,18 +1624,11 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb)
unsigned int stid = GET_POPEN_TID(ntohl(req->tos_stid));
struct tid_info *t = dev->rdev.lldi.tids;
unsigned int hwtid = GET_TID(req);
- struct neighbour *neigh;
struct dst_entry *dst;
- struct l2t_entry *l2t;
struct rtable *rt;
__be32 local_ip, peer_ip;
__be16 local_port, peer_port;
- struct net_device *pdev;
- u32 tx_chan, smac_idx;
- u16 rss_qid;
- u32 mtu;
- int step;
- int txq_idx, ctrlq_idx;
+ int err;
parent_ep = lookup_stid(t, stid);
PDBG("%s parent ep %p tid %u\n", __func__, parent_ep, hwtid);
@@ -1596,49 +1650,24 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb)
goto reject;
}
dst = &rt->dst;
- rcu_read_lock();
- neigh = dst_get_neighbour_noref(dst);
- if (neigh->dev->flags & IFF_LOOPBACK) {
- pdev = ip_dev_find(&init_net, peer_ip);
- BUG_ON(!pdev);
- l2t = cxgb4_l2t_get(dev->rdev.lldi.l2t, neigh, pdev, 0);
- mtu = pdev->mtu;
- tx_chan = cxgb4_port_chan(pdev);
- smac_idx = (cxgb4_port_viid(pdev) & 0x7F) << 1;
- step = dev->rdev.lldi.ntxq / dev->rdev.lldi.nchan;
- txq_idx = cxgb4_port_idx(pdev) * step;
- ctrlq_idx = cxgb4_port_idx(pdev);
- step = dev->rdev.lldi.nrxq / dev->rdev.lldi.nchan;
- rss_qid = dev->rdev.lldi.rxq_ids[cxgb4_port_idx(pdev) * step];
- dev_put(pdev);
- } else {
- l2t = cxgb4_l2t_get(dev->rdev.lldi.l2t, neigh, neigh->dev, 0);
- mtu = dst_mtu(dst);
- tx_chan = cxgb4_port_chan(neigh->dev);
- smac_idx = (cxgb4_port_viid(neigh->dev) & 0x7F) << 1;
- step = dev->rdev.lldi.ntxq / dev->rdev.lldi.nchan;
- txq_idx = cxgb4_port_idx(neigh->dev) * step;
- ctrlq_idx = cxgb4_port_idx(neigh->dev);
- step = dev->rdev.lldi.nrxq / dev->rdev.lldi.nchan;
- rss_qid = dev->rdev.lldi.rxq_ids[
- cxgb4_port_idx(neigh->dev) * step];
- }
- rcu_read_unlock();
- if (!l2t) {
- printk(KERN_ERR MOD "%s - failed to allocate l2t entry!\n",
+
+ child_ep = alloc_ep(sizeof(*child_ep), GFP_KERNEL);
+ if (!child_ep) {
+ printk(KERN_ERR MOD "%s - failed to allocate ep entry!\n",
__func__);
dst_release(dst);
goto reject;
}
- child_ep = alloc_ep(sizeof(*child_ep), GFP_KERNEL);
- if (!child_ep) {
- printk(KERN_ERR MOD "%s - failed to allocate ep entry!\n",
+ err = import_ep(child_ep, peer_ip, dst, dev, false);
+ if (err) {
+ printk(KERN_ERR MOD "%s - failed to allocate l2t entry!\n",
__func__);
- cxgb4_l2t_release(l2t);
dst_release(dst);
+ kfree(child_ep);
goto reject;
}
+
state_set(&child_ep->com, CONNECTING);
child_ep->com.dev = dev;
child_ep->com.cm_id = NULL;
@@ -1651,18 +1680,11 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb)
c4iw_get_ep(&parent_ep->com);
child_ep->parent_ep = parent_ep;
child_ep->tos = GET_POPEN_TOS(ntohl(req->tos_stid));
- child_ep->l2t = l2t;
child_ep->dst = dst;
child_ep->hwtid = hwtid;
- child_ep->tx_chan = tx_chan;
- child_ep->smac_idx = smac_idx;
- child_ep->rss_qid = rss_qid;
- child_ep->mtu = mtu;
- child_ep->txq_idx = txq_idx;
- child_ep->ctrlq_idx = ctrlq_idx;
PDBG("%s tx_chan %u smac_idx %u rss_qid %u\n", __func__,
- tx_chan, smac_idx, rss_qid);
+ child_ep->tx_chan, child_ep->smac_idx, child_ep->rss_qid);
init_timer(&child_ep->timer);
cxgb4_insert_tid(t, child_ep, hwtid);
@@ -1792,11 +1814,8 @@ static int is_neg_adv_abort(unsigned int status)
static int c4iw_reconnect(struct c4iw_ep *ep)
{
- int err = 0;
struct rtable *rt;
- struct net_device *pdev;
- struct neighbour *neigh;
- int step;
+ int err = 0;
PDBG("%s qp %p cm_id %p\n", __func__, ep->com.qp, ep->com.cm_id);
init_timer(&ep->timer);
@@ -1824,47 +1843,10 @@ static int c4iw_reconnect(struct c4iw_ep *ep)
}
ep->dst = &rt->dst;
- rcu_read_lock();
- neigh = dst_get_neighbour_noref(ep->dst);
-
- /* get a l2t entry */
- if (neigh->dev->flags & IFF_LOOPBACK) {
- PDBG("%s LOOPBACK\n", __func__);
- pdev = ip_dev_find(&init_net,
- ep->com.cm_id->remote_addr.sin_addr.s_addr);
- ep->l2t = cxgb4_l2t_get(ep->com.dev->rdev.lldi.l2t,
- neigh, pdev, 0);
- ep->mtu = pdev->mtu;
- ep->tx_chan = cxgb4_port_chan(pdev);
- ep->smac_idx = (cxgb4_port_viid(pdev) & 0x7F) << 1;
- step = ep->com.dev->rdev.lldi.ntxq /
- ep->com.dev->rdev.lldi.nchan;
- ep->txq_idx = cxgb4_port_idx(pdev) * step;
- step = ep->com.dev->rdev.lldi.nrxq /
- ep->com.dev->rdev.lldi.nchan;
- ep->ctrlq_idx = cxgb4_port_idx(pdev);
- ep->rss_qid = ep->com.dev->rdev.lldi.rxq_ids[
- cxgb4_port_idx(pdev) * step];
- dev_put(pdev);
- } else {
- ep->l2t = cxgb4_l2t_get(ep->com.dev->rdev.lldi.l2t,
- neigh, neigh->dev, 0);
- ep->mtu = dst_mtu(ep->dst);
- ep->tx_chan = cxgb4_port_chan(neigh->dev);
- ep->smac_idx = (cxgb4_port_viid(neigh->dev) & 0x7F) << 1;
- step = ep->com.dev->rdev.lldi.ntxq /
- ep->com.dev->rdev.lldi.nchan;
- ep->txq_idx = cxgb4_port_idx(neigh->dev) * step;
- ep->ctrlq_idx = cxgb4_port_idx(neigh->dev);
- step = ep->com.dev->rdev.lldi.nrxq /
- ep->com.dev->rdev.lldi.nchan;
- ep->rss_qid = ep->com.dev->rdev.lldi.rxq_ids[
- cxgb4_port_idx(neigh->dev) * step];
- }
- rcu_read_unlock();
- if (!ep->l2t) {
+ err = import_ep(ep, ep->com.cm_id->remote_addr.sin_addr.s_addr,
+ ep->dst, ep->com.dev, false);
+ if (err) {
printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__);
- err = -ENOMEM;
goto fail4;
}
@@ -2240,13 +2222,10 @@ err:
int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
{
- int err = 0;
struct c4iw_dev *dev = to_c4iw_dev(cm_id->device);
struct c4iw_ep *ep;
struct rtable *rt;
- struct net_device *pdev;
- struct neighbour *neigh;
- int step;
+ int err = 0;
if ((conn_param->ord > c4iw_max_read_depth) ||
(conn_param->ird > c4iw_max_read_depth)) {
@@ -2307,49 +2286,10 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
}
ep->dst = &rt->dst;
- rcu_read_lock();
- neigh = dst_get_neighbour_noref(ep->dst);
-
- /* get a l2t entry */
- if (neigh->dev->flags & IFF_LOOPBACK) {
- PDBG("%s LOOPBACK\n", __func__);
- pdev = ip_dev_find(&init_net,
- cm_id->remote_addr.sin_addr.s_addr);
- ep->l2t = cxgb4_l2t_get(ep->com.dev->rdev.lldi.l2t,
- neigh, pdev, 0);
- ep->mtu = pdev->mtu;
- ep->tx_chan = cxgb4_port_chan(pdev);
- ep->smac_idx = (cxgb4_port_viid(pdev) & 0x7F) << 1;
- step = ep->com.dev->rdev.lldi.ntxq /
- ep->com.dev->rdev.lldi.nchan;
- ep->txq_idx = cxgb4_port_idx(pdev) * step;
- step = ep->com.dev->rdev.lldi.nrxq /
- ep->com.dev->rdev.lldi.nchan;
- ep->ctrlq_idx = cxgb4_port_idx(pdev);
- ep->rss_qid = ep->com.dev->rdev.lldi.rxq_ids[
- cxgb4_port_idx(pdev) * step];
- dev_put(pdev);
- } else {
- ep->l2t = cxgb4_l2t_get(ep->com.dev->rdev.lldi.l2t,
- neigh, neigh->dev, 0);
- ep->mtu = dst_mtu(ep->dst);
- ep->tx_chan = cxgb4_port_chan(neigh->dev);
- ep->smac_idx = (cxgb4_port_viid(neigh->dev) & 0x7F) << 1;
- step = ep->com.dev->rdev.lldi.ntxq /
- ep->com.dev->rdev.lldi.nchan;
- ep->txq_idx = cxgb4_port_idx(neigh->dev) * step;
- ep->ctrlq_idx = cxgb4_port_idx(neigh->dev);
- step = ep->com.dev->rdev.lldi.nrxq /
- ep->com.dev->rdev.lldi.nchan;
- ep->rss_qid = ep->com.dev->rdev.lldi.rxq_ids[
- cxgb4_port_idx(neigh->dev) * step];
- ep->retry_with_mpa_v1 = 0;
- ep->tried_with_mpa_v1 = 0;
- }
- rcu_read_unlock();
- if (!ep->l2t) {
+ err = import_ep(ep, cm_id->remote_addr.sin_addr.s_addr,
+ ep->dst, ep->com.dev, true);
+ if (err) {
printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__);
- err = -ENOMEM;
goto fail4;
}
--
1.7.7.3
^ permalink raw reply related
* [PATCH 5/9] infiniband: nes: Use dst's neighbour entry.
From: David Miller @ 2011-12-03 2:52 UTC (permalink / raw)
To: roland; +Cc: netdev
Do this instead of performing a by-hand lookup.
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/infiniband/hw/nes/nes_cm.c | 14 +++++---------
1 files changed, 5 insertions(+), 9 deletions(-)
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index 686667a..b1e6cae 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -1348,7 +1348,8 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi
else
netdev = nesvnic->netdev;
- neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, netdev);
+ rcu_read_lock();
+ neigh = dst_get_neighbour_noref(&rt->dst);
if (neigh) {
if (neigh->nud_state & NUD_VALID) {
nes_debug(NES_DBG_CM, "Neighbor MAC address for 0x%08X"
@@ -1359,7 +1360,6 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi
if (!memcmp(nesadapter->arp_table[arpindex].mac_addr,
neigh->ha, ETH_ALEN)) {
/* Mac address same as in nes_arp_table */
- neigh_release(neigh);
ip_rt_put(rt);
return rc;
}
@@ -1373,15 +1373,11 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi
dst_ip, NES_ARP_ADD);
rc = nes_arp_table(nesvnic->nesdev, dst_ip, NULL,
NES_ARP_RESOLVE);
+ } else {
+ neigh_event_send(neigh, NULL);
}
- neigh_release(neigh);
- }
-
- if ((neigh == NULL) || (!(neigh->nud_state & NUD_VALID))) {
- rcu_read_lock();
- neigh_event_send(dst_get_neighbour_noref(&rt->dst), NULL);
- rcu_read_unlock();
}
+ rcu_read_unlock();
ip_rt_put(rt);
return rc;
}
--
1.7.7.3
^ permalink raw reply related
* [PATCH 4/9] cxgb3: Handle NULL dst neighbour in cxgb3_offload.c
From: David Miller @ 2011-12-03 2:52 UTC (permalink / raw)
To: roland; +Cc: netdev
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c | 18 +++++++++++++++---
1 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c
index 596cfe3..65e4b28 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c
+++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c
@@ -1072,8 +1072,11 @@ static int is_offloading(struct net_device *dev)
static void cxgb_neigh_update(struct neighbour *neigh)
{
- struct net_device *dev = neigh->dev;
+ struct net_device *dev;
+ if (!neigh)
+ return;
+ dev = neigh->dev;
if (dev && (is_offloading(dev))) {
struct t3cdev *tdev = dev2t3cdev(dev);
@@ -1107,6 +1110,7 @@ static void set_l2t_ix(struct t3cdev *tdev, u32 tid, struct l2t_entry *e)
static void cxgb_redirect(struct dst_entry *old, struct dst_entry *new)
{
struct net_device *olddev, *newdev;
+ struct neighbour *n;
struct tid_info *ti;
struct t3cdev *tdev;
u32 tid;
@@ -1114,8 +1118,16 @@ static void cxgb_redirect(struct dst_entry *old, struct dst_entry *new)
struct l2t_entry *e;
struct t3c_tid_entry *te;
- olddev = dst_get_neighbour_noref(old)->dev;
- newdev = dst_get_neighbour_noref(new)->dev;
+ n = dst_get_neighbour_noref(old);
+ if (!n)
+ return;
+ olddev = n->dev;
+
+ n = dst_get_neighbour_noref(new);
+ if (!n)
+ return;
+ newdev = n->dev;
+
if (!is_offloading(olddev))
return;
if (!is_offloading(newdev)) {
--
1.7.7.3
^ permalink raw reply related
* [PATCH 3/9] cxgb3: Rework t3_l2t_get to take a dst_entry instead of a neighbour.
From: David Miller @ 2011-12-03 2:52 UTC (permalink / raw)
To: roland; +Cc: netdev
This way we consolidate the RCU locking down into the place where it
actually matters, and also we can make the code handle
dst_get_neighbour_noref() returning NULL properly.
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/infiniband/hw/cxgb3/iwch_cm.c | 15 +---------
drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c | 2 +-
drivers/net/ethernet/chelsio/cxgb3/l2t.c | 27 ++++++++++++++-----
drivers/net/ethernet/chelsio/cxgb3/l2t.h | 2 +-
drivers/scsi/cxgbi/cxgb3i/cxgb3i.c | 2 +-
5 files changed, 25 insertions(+), 23 deletions(-)
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c
index 23686df..740dcc0 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_cm.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c
@@ -1338,7 +1338,6 @@ static int pass_accept_req(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
struct iwch_ep *child_ep, *parent_ep = ctx;
struct cpl_pass_accept_req *req = cplhdr(skb);
unsigned int hwtid = GET_TID(req);
- struct neighbour *neigh;
struct dst_entry *dst;
struct l2t_entry *l2t;
struct rtable *rt;
@@ -1375,10 +1374,7 @@ static int pass_accept_req(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
goto reject;
}
dst = &rt->dst;
- rcu_read_lock();
- neigh = dst_get_neighbour_noref(dst);
- l2t = t3_l2t_get(tdev, neigh, neigh->dev);
- rcu_read_unlock();
+ l2t = t3_l2t_get(tdev, dst, NULL);
if (!l2t) {
printk(KERN_ERR MOD "%s - failed to allocate l2t entry!\n",
__func__);
@@ -1889,7 +1885,6 @@ static int is_loopback_dst(struct iw_cm_id *cm_id)
int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
{
struct iwch_dev *h = to_iwch_dev(cm_id->device);
- struct neighbour *neigh;
struct iwch_ep *ep;
struct rtable *rt;
int err = 0;
@@ -1947,13 +1942,7 @@ int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
goto fail3;
}
ep->dst = &rt->dst;
-
- rcu_read_lock();
- neigh = dst_get_neighbour_noref(ep->dst);
-
- /* get a l2t entry */
- ep->l2t = t3_l2t_get(ep->com.tdev, neigh, neigh->dev);
- rcu_read_unlock();
+ ep->l2t = t3_l2t_get(ep->com.tdev, ep->dst, NULL);
if (!ep->l2t) {
printk(KERN_ERR MOD "%s - cannot alloc l2e.\n", __func__);
err = -ENOMEM;
diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c
index 6ed9f87..596cfe3 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c
+++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c
@@ -1132,7 +1132,7 @@ static void cxgb_redirect(struct dst_entry *old, struct dst_entry *new)
}
/* Add new L2T entry */
- e = t3_l2t_get(tdev, dst_get_neighbour_noref(new), newdev);
+ e = t3_l2t_get(tdev, new, newdev);
if (!e) {
printk(KERN_ERR "%s: couldn't allocate new l2t entry!\n",
__func__);
diff --git a/drivers/net/ethernet/chelsio/cxgb3/l2t.c b/drivers/net/ethernet/chelsio/cxgb3/l2t.c
index 70fec8b..3fa3c88 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/l2t.c
+++ b/drivers/net/ethernet/chelsio/cxgb3/l2t.c
@@ -298,18 +298,31 @@ static inline void reuse_entry(struct l2t_entry *e, struct neighbour *neigh)
spin_unlock(&e->lock);
}
-struct l2t_entry *t3_l2t_get(struct t3cdev *cdev, struct neighbour *neigh,
+struct l2t_entry *t3_l2t_get(struct t3cdev *cdev, struct dst_entry *dst,
struct net_device *dev)
{
struct l2t_entry *e = NULL;
+ struct neighbour *neigh;
+ struct port_info *p;
struct l2t_data *d;
int hash;
- u32 addr = *(u32 *) neigh->primary_key;
- int ifidx = neigh->dev->ifindex;
- struct port_info *p = netdev_priv(dev);
- int smt_idx = p->port_id;
+ u32 addr;
+ int ifidx;
+ int smt_idx;
rcu_read_lock();
+ neigh = dst_get_neighbour_noref(dst);
+ if (!neigh)
+ goto done_rcu;
+
+ addr = *(u32 *) neigh->primary_key;
+ ifidx = neigh->dev->ifindex;
+
+ if (!dev)
+ dev = neigh->dev;
+ p = netdev_priv(dev);
+ smt_idx = p->port_id;
+
d = L2DATA(cdev);
if (!d)
goto done_rcu;
@@ -323,7 +336,7 @@ struct l2t_entry *t3_l2t_get(struct t3cdev *cdev, struct neighbour *neigh,
l2t_hold(d, e);
if (atomic_read(&e->refcnt) == 1)
reuse_entry(e, neigh);
- goto done;
+ goto done_unlock;
}
/* Need to allocate a new entry */
@@ -344,7 +357,7 @@ struct l2t_entry *t3_l2t_get(struct t3cdev *cdev, struct neighbour *neigh,
e->vlan = VLAN_NONE;
spin_unlock(&e->lock);
}
-done:
+done_unlock:
write_unlock_bh(&d->lock);
done_rcu:
rcu_read_unlock();
diff --git a/drivers/net/ethernet/chelsio/cxgb3/l2t.h b/drivers/net/ethernet/chelsio/cxgb3/l2t.h
index c5f5479..c4e8643 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/l2t.h
+++ b/drivers/net/ethernet/chelsio/cxgb3/l2t.h
@@ -109,7 +109,7 @@ static inline void set_arp_failure_handler(struct sk_buff *skb,
void t3_l2e_free(struct l2t_data *d, struct l2t_entry *e);
void t3_l2t_update(struct t3cdev *dev, struct neighbour *neigh);
-struct l2t_entry *t3_l2t_get(struct t3cdev *cdev, struct neighbour *neigh,
+struct l2t_entry *t3_l2t_get(struct t3cdev *cdev, struct dst_entry *dst,
struct net_device *dev);
int t3_l2t_send_slow(struct t3cdev *dev, struct sk_buff *skb,
struct l2t_entry *e);
diff --git a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
index 88902d3..36739da 100644
--- a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
+++ b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
@@ -966,7 +966,7 @@ static int init_act_open(struct cxgbi_sock *csk)
csk->saddr.sin_addr.s_addr = chba->ipv4addr;
csk->rss_qid = 0;
- csk->l2t = t3_l2t_get(t3dev, dst_get_neighbour_noref(dst), ndev);
+ csk->l2t = t3_l2t_get(t3dev, dst, ndev);
if (!csk->l2t) {
pr_err("NO l2t available.\n");
return -EINVAL;
--
1.7.7.3
^ permalink raw reply related
* [PATCH 2/9] infiniband: addr: Consolidate code to fetch neighbout hardware address from dst.
From: David Miller @ 2011-12-03 2:52 UTC (permalink / raw)
To: roland; +Cc: netdev
IPV4 should do exactly what the IPV6 code does here, which is
use the neighbour obtained via the dst entry.
And now that the two code paths do the same thing, use a common
helper function to perform the operation.
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/infiniband/core/addr.c | 47 +++++++++++++++++----------------------
1 files changed, 21 insertions(+), 26 deletions(-)
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
index 70154f7..1612cfd 100644
--- a/drivers/infiniband/core/addr.c
+++ b/drivers/infiniband/core/addr.c
@@ -178,6 +178,25 @@ static void queue_req(struct addr_req *req)
mutex_unlock(&lock);
}
+static int dst_fetch_ha(struct dst_entry *dst, struct rdma_dev_addr *addr)
+{
+ struct neighbour *n;
+ int ret;
+
+ rcu_read_lock();
+ n = dst_get_neighbour_noref(dst);
+ if (!n || !(n->nud_state & NUD_VALID)) {
+ if (n)
+ neigh_event_send(n, NULL);
+ ret = -ENODATA;
+ } else {
+ ret = rdma_copy_addr(addr, dst->dev, n->ha);
+ }
+ rcu_read_unlock();
+
+ return ret;
+}
+
static int addr4_resolve(struct sockaddr_in *src_in,
struct sockaddr_in *dst_in,
struct rdma_dev_addr *addr)
@@ -185,7 +204,6 @@ static int addr4_resolve(struct sockaddr_in *src_in,
__be32 src_ip = src_in->sin_addr.s_addr;
__be32 dst_ip = dst_in->sin_addr.s_addr;
struct rtable *rt;
- struct neighbour *neigh;
struct flowi4 fl4;
int ret;
@@ -214,20 +232,7 @@ static int addr4_resolve(struct sockaddr_in *src_in,
goto put;
}
- neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, rt->dst.dev);
- if (!neigh || !(neigh->nud_state & NUD_VALID)) {
- rcu_read_lock();
- neigh_event_send(dst_get_neighbour_noref(&rt->dst), NULL);
- rcu_read_unlock();
- ret = -ENODATA;
- if (neigh)
- goto release;
- goto put;
- }
-
- ret = rdma_copy_addr(addr, neigh->dev, neigh->ha);
-release:
- neigh_release(neigh);
+ ret = dst_fetch_ha(&rt->dst, addr);
put:
ip_rt_put(rt);
out:
@@ -240,7 +245,6 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
struct rdma_dev_addr *addr)
{
struct flowi6 fl6;
- struct neighbour *neigh;
struct dst_entry *dst;
int ret;
@@ -276,16 +280,7 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
goto put;
}
- rcu_read_lock();
- neigh = dst_get_neighbour_noref(dst);
- if (!neigh || !(neigh->nud_state & NUD_VALID)) {
- if (neigh)
- neigh_event_send(neigh, NULL);
- ret = -ENODATA;
- } else {
- ret = rdma_copy_addr(addr, dst->dev, neigh->ha);
- }
- rcu_read_unlock();
+ ret = dst_fetch_ha(dst, addr);
put:
dst_release(dst);
return ret;
--
1.7.7.3
^ permalink raw reply related
* Re: [PATCH] dccp: Fix compile warning in probe code.
From: Gerrit Renker @ 2011-12-03 2:52 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20111201.144650.173157123252154314.davem@davemloft.net>
Acked-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
I have compiled and tested this and added the patch to the test tree.
Thanks for the improvement.
| --- a/net/dccp/probe.c
| +++ b/net/dccp/probe.c
| @@ -152,6 +152,17 @@ static const struct file_operations dccpprobe_fops = {
| .llseek = noop_llseek,
| };
|
| +static __init int setup_jprobe(void)
| +{
| + int ret = register_jprobe(&dccp_send_probe);
| +
| + if (ret) {
| + request_module("dccp");
| + ret = register_jprobe(&dccp_send_probe);
| + }
| + return ret;
| +}
| +
| static __init int dccpprobe_init(void)
| {
| int ret = -ENOMEM;
| @@ -163,8 +174,7 @@ static __init int dccpprobe_init(void)
| if (!proc_net_fops_create(&init_net, procname, S_IRUSR, &dccpprobe_fops))
| goto err0;
|
| - try_then_request_module((ret = register_jprobe(&dccp_send_probe)) == 0,
| - "dccp");
| + ret = setup_jprobe();
| if (ret)
| goto err1;
|
| --
| 1.7.7.3
|
|
--
^ permalink raw reply
* [PATCH 1/9] net: Rename dst_get_neighbour{,_raw} to dst_get_neighbour_noref{,_raw}.
From: David Miller @ 2011-12-03 2:52 UTC (permalink / raw)
To: roland; +Cc: netdev
To reflect the fact that a refrence is not obtained to the
resulting neighbour entry.
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/infiniband/core/addr.c | 4 ++--
drivers/infiniband/hw/cxgb3/iwch_cm.c | 4 ++--
drivers/infiniband/hw/cxgb4/cm.c | 6 +++---
drivers/infiniband/hw/nes/nes_cm.c | 2 +-
drivers/infiniband/ulp/ipoib/ipoib_main.c | 8 ++++----
drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 4 ++--
drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c | 8 ++++----
drivers/s390/net/qeth_l3_main.c | 4 ++--
drivers/scsi/cxgbi/cxgb3i/cxgb3i.c | 2 +-
drivers/scsi/cxgbi/cxgb4i/cxgb4i.c | 2 +-
drivers/scsi/cxgbi/libcxgbi.c | 4 ++--
include/net/dst.h | 6 +++---
net/atm/clip.c | 2 +-
net/bridge/br_netfilter.c | 2 +-
net/core/dst.c | 2 +-
net/core/neighbour.c | 2 +-
net/decnet/dn_neigh.c | 2 +-
net/decnet/dn_route.c | 8 ++++----
net/ipv4/ip_gre.c | 2 +-
net/ipv4/ip_output.c | 2 +-
net/ipv4/route.c | 2 +-
net/ipv6/addrconf.c | 2 +-
net/ipv6/ip6_fib.c | 2 +-
net/ipv6/ip6_output.c | 6 +++---
net/ipv6/ndisc.c | 4 ++--
net/ipv6/route.c | 16 ++++++++--------
net/ipv6/sit.c | 4 ++--
net/sched/sch_teql.c | 2 +-
net/xfrm/xfrm_policy.c | 2 +-
29 files changed, 58 insertions(+), 58 deletions(-)
diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c
index a20c3c8..70154f7 100644
--- a/drivers/infiniband/core/addr.c
+++ b/drivers/infiniband/core/addr.c
@@ -217,7 +217,7 @@ static int addr4_resolve(struct sockaddr_in *src_in,
neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, rt->dst.dev);
if (!neigh || !(neigh->nud_state & NUD_VALID)) {
rcu_read_lock();
- neigh_event_send(dst_get_neighbour(&rt->dst), NULL);
+ neigh_event_send(dst_get_neighbour_noref(&rt->dst), NULL);
rcu_read_unlock();
ret = -ENODATA;
if (neigh)
@@ -277,7 +277,7 @@ static int addr6_resolve(struct sockaddr_in6 *src_in,
}
rcu_read_lock();
- neigh = dst_get_neighbour(dst);
+ neigh = dst_get_neighbour_noref(dst);
if (!neigh || !(neigh->nud_state & NUD_VALID)) {
if (neigh)
neigh_event_send(neigh, NULL);
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c
index c88b12b..23686df 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_cm.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c
@@ -1376,7 +1376,7 @@ static int pass_accept_req(struct t3cdev *tdev, struct sk_buff *skb, void *ctx)
}
dst = &rt->dst;
rcu_read_lock();
- neigh = dst_get_neighbour(dst);
+ neigh = dst_get_neighbour_noref(dst);
l2t = t3_l2t_get(tdev, neigh, neigh->dev);
rcu_read_unlock();
if (!l2t) {
@@ -1949,7 +1949,7 @@ int iwch_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
ep->dst = &rt->dst;
rcu_read_lock();
- neigh = dst_get_neighbour(ep->dst);
+ neigh = dst_get_neighbour_noref(ep->dst);
/* get a l2t entry */
ep->l2t = t3_l2t_get(ep->com.tdev, neigh, neigh->dev);
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c
index 0747004..e61c802 100644
--- a/drivers/infiniband/hw/cxgb4/cm.c
+++ b/drivers/infiniband/hw/cxgb4/cm.c
@@ -1597,7 +1597,7 @@ static int pass_accept_req(struct c4iw_dev *dev, struct sk_buff *skb)
}
dst = &rt->dst;
rcu_read_lock();
- neigh = dst_get_neighbour(dst);
+ neigh = dst_get_neighbour_noref(dst);
if (neigh->dev->flags & IFF_LOOPBACK) {
pdev = ip_dev_find(&init_net, peer_ip);
BUG_ON(!pdev);
@@ -1825,7 +1825,7 @@ static int c4iw_reconnect(struct c4iw_ep *ep)
ep->dst = &rt->dst;
rcu_read_lock();
- neigh = dst_get_neighbour(ep->dst);
+ neigh = dst_get_neighbour_noref(ep->dst);
/* get a l2t entry */
if (neigh->dev->flags & IFF_LOOPBACK) {
@@ -2308,7 +2308,7 @@ int c4iw_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
ep->dst = &rt->dst;
rcu_read_lock();
- neigh = dst_get_neighbour(ep->dst);
+ neigh = dst_get_neighbour_noref(ep->dst);
/* get a l2t entry */
if (neigh->dev->flags & IFF_LOOPBACK) {
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index 0a52d72..686667a 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -1379,7 +1379,7 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi
if ((neigh == NULL) || (!(neigh->nud_state & NUD_VALID))) {
rcu_read_lock();
- neigh_event_send(dst_get_neighbour(&rt->dst), NULL);
+ neigh_event_send(dst_get_neighbour_noref(&rt->dst), NULL);
rcu_read_unlock();
}
ip_rt_put(rt);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index d3ed89c..eef6786 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -564,7 +564,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
struct neighbour *n;
unsigned long flags;
- n = dst_get_neighbour(skb_dst(skb));
+ n = dst_get_neighbour_noref(skb_dst(skb));
neigh = ipoib_neigh_alloc(n, skb->dev);
if (!neigh) {
++dev->stats.tx_dropped;
@@ -645,7 +645,7 @@ static void ipoib_path_lookup(struct sk_buff *skb, struct net_device *dev)
struct neighbour *n;
/* Look up path record for unicasts */
- n = dst_get_neighbour(dst);
+ n = dst_get_neighbour_noref(dst);
if (n->ha[4] != 0xff) {
neigh_add_path(skb, dev);
return;
@@ -724,7 +724,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
rcu_read_lock();
if (likely(skb_dst(skb)))
- n = dst_get_neighbour(skb_dst(skb));
+ n = dst_get_neighbour_noref(skb_dst(skb));
if (likely(n)) {
if (unlikely(!*to_ipoib_neigh(n))) {
@@ -841,7 +841,7 @@ static int ipoib_hard_header(struct sk_buff *skb,
dst = skb_dst(skb);
n = NULL;
if (dst)
- n = dst_get_neighbour_raw(dst);
+ n = dst_get_neighbour_noref_raw(dst);
if ((!dst || !n) && daddr) {
struct ipoib_pseudoheader *phdr =
(struct ipoib_pseudoheader *) skb_push(skb, sizeof *phdr);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 873bff9..f7ff9dd 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -269,7 +269,7 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
skb->dev = dev;
if (dst)
- n = dst_get_neighbour_raw(dst);
+ n = dst_get_neighbour_noref_raw(dst);
if (!dst || !n) {
/* put pseudoheader back on for next time */
skb_push(skb, sizeof (struct ipoib_pseudoheader));
@@ -728,7 +728,7 @@ out:
rcu_read_lock();
if (dst)
- n = dst_get_neighbour(dst);
+ n = dst_get_neighbour_noref(dst);
if (n && !*to_ipoib_neigh(n)) {
struct ipoib_neigh *neigh = ipoib_neigh_alloc(n,
skb->dev);
diff --git a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c
index 7f7882d..6ed9f87 100644
--- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c
+++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_offload.c
@@ -969,7 +969,7 @@ static int nb_callback(struct notifier_block *self, unsigned long event,
case (NETEVENT_REDIRECT):{
struct netevent_redirect *nr = ctx;
cxgb_redirect(nr->old, nr->new);
- cxgb_neigh_update(dst_get_neighbour(nr->new));
+ cxgb_neigh_update(dst_get_neighbour_noref(nr->new));
break;
}
default:
@@ -1114,8 +1114,8 @@ static void cxgb_redirect(struct dst_entry *old, struct dst_entry *new)
struct l2t_entry *e;
struct t3c_tid_entry *te;
- olddev = dst_get_neighbour(old)->dev;
- newdev = dst_get_neighbour(new)->dev;
+ olddev = dst_get_neighbour_noref(old)->dev;
+ newdev = dst_get_neighbour_noref(new)->dev;
if (!is_offloading(olddev))
return;
if (!is_offloading(newdev)) {
@@ -1132,7 +1132,7 @@ static void cxgb_redirect(struct dst_entry *old, struct dst_entry *new)
}
/* Add new L2T entry */
- e = t3_l2t_get(tdev, dst_get_neighbour(new), newdev);
+ e = t3_l2t_get(tdev, dst_get_neighbour_noref(new), newdev);
if (!e) {
printk(KERN_ERR "%s: couldn't allocate new l2t entry!\n",
__func__);
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 6357892..b2a55e3 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -2759,7 +2759,7 @@ int inline qeth_l3_get_cast_type(struct qeth_card *card, struct sk_buff *skb)
rcu_read_lock();
dst = skb_dst(skb);
if (dst)
- n = dst_get_neighbour(dst);
+ n = dst_get_neighbour_noref(dst);
if (n) {
cast_type = n->type;
rcu_read_unlock();
@@ -2855,7 +2855,7 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr,
rcu_read_lock();
dst = skb_dst(skb);
if (dst)
- n = dst_get_neighbour(dst);
+ n = dst_get_neighbour_noref(dst);
if (ipv == 4) {
/* IPv4 */
hdr->hdr.l3.flags = qeth_l3_get_qeth_hdr_flags4(cast_type);
diff --git a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
index 000294a..88902d3 100644
--- a/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
+++ b/drivers/scsi/cxgbi/cxgb3i/cxgb3i.c
@@ -966,7 +966,7 @@ static int init_act_open(struct cxgbi_sock *csk)
csk->saddr.sin_addr.s_addr = chba->ipv4addr;
csk->rss_qid = 0;
- csk->l2t = t3_l2t_get(t3dev, dst_get_neighbour(dst), ndev);
+ csk->l2t = t3_l2t_get(t3dev, dst_get_neighbour_noref(dst), ndev);
if (!csk->l2t) {
pr_err("NO l2t available.\n");
return -EINVAL;
diff --git a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
index ac7a9b1..c8fd13a 100644
--- a/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
+++ b/drivers/scsi/cxgbi/cxgb4i/cxgb4i.c
@@ -1141,7 +1141,7 @@ static int init_act_open(struct cxgbi_sock *csk)
cxgbi_sock_set_flag(csk, CTPF_HAS_ATID);
cxgbi_sock_get(csk);
- csk->l2t = cxgb4_l2t_get(lldi->l2t, dst_get_neighbour(csk->dst), ndev, 0);
+ csk->l2t = cxgb4_l2t_get(lldi->l2t, dst_get_neighbour_noref(csk->dst), ndev, 0);
if (!csk->l2t) {
pr_err("%s, cannot alloc l2t.\n", ndev->name);
goto rel_resource;
diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c
index c10f74a..a026a2f 100644
--- a/drivers/scsi/cxgbi/libcxgbi.c
+++ b/drivers/scsi/cxgbi/libcxgbi.c
@@ -493,7 +493,7 @@ static struct cxgbi_sock *cxgbi_check_route(struct sockaddr *dst_addr)
goto err_out;
}
dst = &rt->dst;
- ndev = dst_get_neighbour(dst)->dev;
+ ndev = dst_get_neighbour_noref(dst)->dev;
if (rt->rt_flags & (RTCF_MULTICAST | RTCF_BROADCAST)) {
pr_info("multi-cast route %pI4, port %u, dev %s.\n",
@@ -507,7 +507,7 @@ static struct cxgbi_sock *cxgbi_check_route(struct sockaddr *dst_addr)
ndev = ip_dev_find(&init_net, daddr->sin_addr.s_addr);
mtu = ndev->mtu;
pr_info("rt dev %s, loopback -> %s, mtu %u.\n",
- dst_get_neighbour(dst)->dev->name, ndev->name, mtu);
+ dst_get_neighbour_noref(dst)->dev->name, ndev->name, mtu);
}
cdev = cxgbi_device_find_by_netdev(ndev, &port);
diff --git a/include/net/dst.h b/include/net/dst.h
index 6faec1a..01343b0 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -86,12 +86,12 @@ struct dst_entry {
};
};
-static inline struct neighbour *dst_get_neighbour(struct dst_entry *dst)
+static inline struct neighbour *dst_get_neighbour_noref(struct dst_entry *dst)
{
return rcu_dereference(dst->_neighbour);
}
-static inline struct neighbour *dst_get_neighbour_raw(struct dst_entry *dst)
+static inline struct neighbour *dst_get_neighbour_noref_raw(struct dst_entry *dst)
{
return rcu_dereference_raw(dst->_neighbour);
}
@@ -392,7 +392,7 @@ static inline void dst_confirm(struct dst_entry *dst)
struct neighbour *n;
rcu_read_lock();
- n = dst_get_neighbour(dst);
+ n = dst_get_neighbour_noref(dst);
neigh_confirm(n);
rcu_read_unlock();
}
diff --git a/net/atm/clip.c b/net/atm/clip.c
index c84ce7f..c12c258 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -338,7 +338,7 @@ static netdev_tx_t clip_start_xmit(struct sk_buff *skb,
dev->stats.tx_dropped++;
return NETDEV_TX_OK;
}
- n = dst_get_neighbour(dst);
+ n = dst_get_neighbour_noref(dst);
if (!n) {
pr_err("NO NEIGHBOUR !\n");
dev_kfree_skb(skb);
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index d6ec372..834dfab 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -356,7 +356,7 @@ static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb)
if (!skb->dev)
goto free_skb;
dst = skb_dst(skb);
- neigh = dst_get_neighbour(dst);
+ neigh = dst_get_neighbour_noref(dst);
if (neigh->hh.hh_len) {
neigh_hh_bridge(&neigh->hh, skb);
skb->dev = nf_bridge->physindev;
diff --git a/net/core/dst.c b/net/core/dst.c
index d5e2c4c..43d94ce 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -366,7 +366,7 @@ static void dst_ifdown(struct dst_entry *dst, struct net_device *dev,
dev_hold(dst->dev);
dev_put(dev);
rcu_read_lock();
- neigh = dst_get_neighbour(dst);
+ neigh = dst_get_neighbour_noref(dst);
if (neigh && neigh->dev == dev) {
neigh->dev = dst->dev;
dev_hold(dst->dev);
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index cdf8dc3..4af151e 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -1190,7 +1190,7 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new,
rcu_read_lock();
/* On shaper/eql skb->dst->neighbour != neigh :( */
- if (dst && (n2 = dst_get_neighbour(dst)) != NULL)
+ if (dst && (n2 = dst_get_neighbour_noref(dst)) != NULL)
n1 = n2;
n1->output(n1, skb);
rcu_read_unlock();
diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c
index 3532ac6..7d2fff2 100644
--- a/net/decnet/dn_neigh.c
+++ b/net/decnet/dn_neigh.c
@@ -202,7 +202,7 @@ static int dn_neigh_output_packet(struct sk_buff *skb)
{
struct dst_entry *dst = skb_dst(skb);
struct dn_route *rt = (struct dn_route *)dst;
- struct neighbour *neigh = dst_get_neighbour(dst);
+ struct neighbour *neigh = dst_get_neighbour_noref(dst);
struct net_device *dev = neigh->dev;
char mac_addr[ETH_ALEN];
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index 94f4ec0..f31ce72 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -244,7 +244,7 @@ static int dn_dst_gc(struct dst_ops *ops)
*/
static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu)
{
- struct neighbour *n = dst_get_neighbour(dst);
+ struct neighbour *n = dst_get_neighbour_noref(dst);
u32 min_mtu = 230;
struct dn_dev *dn;
@@ -713,7 +713,7 @@ out:
static int dn_to_neigh_output(struct sk_buff *skb)
{
struct dst_entry *dst = skb_dst(skb);
- struct neighbour *n = dst_get_neighbour(dst);
+ struct neighbour *n = dst_get_neighbour_noref(dst);
return n->output(n, skb);
}
@@ -728,7 +728,7 @@ static int dn_output(struct sk_buff *skb)
int err = -EINVAL;
- if ((neigh = dst_get_neighbour(dst)) == NULL)
+ if ((neigh = dst_get_neighbour_noref(dst)) == NULL)
goto error;
skb->dev = dev;
@@ -852,7 +852,7 @@ static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res)
}
rt->rt_type = res->type;
- if (dev != NULL && dst_get_neighbour(&rt->dst) == NULL) {
+ if (dev != NULL && dst_get_neighbour_noref(&rt->dst) == NULL) {
n = __neigh_lookup_errno(&dn_neigh_table, &rt->rt_gateway, dev);
if (IS_ERR(n))
return PTR_ERR(n);
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 2b32296..fe070c1 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -731,7 +731,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
}
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
else if (skb->protocol == htons(ETH_P_IPV6)) {
- struct neighbour *neigh = dst_get_neighbour(skb_dst(skb));
+ struct neighbour *neigh = dst_get_neighbour_noref(skb_dst(skb));
const struct in6_addr *addr6;
int addr_type;
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 0d5e567..ff302bd 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -206,7 +206,7 @@ static inline int ip_finish_output2(struct sk_buff *skb)
}
rcu_read_lock();
- neigh = dst_get_neighbour(dst);
+ neigh = dst_get_neighbour_noref(dst);
if (neigh) {
int res = neigh_output(neigh, skb);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 7047069..90402a2 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -419,7 +419,7 @@ static int rt_cache_seq_show(struct seq_file *seq, void *v)
int len, HHUptod;
rcu_read_lock();
- n = dst_get_neighbour(&r->dst);
+ n = dst_get_neighbour_noref(&r->dst);
HHUptod = (n && (n->nud_state & NUD_CONNECTED)) ? 1 : 0;
rcu_read_unlock();
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 5860517..058cc22 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -657,7 +657,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen,
* layer address of our nexhop router
*/
- if (dst_get_neighbour_raw(&rt->dst) == NULL)
+ if (dst_get_neighbour_noref_raw(&rt->dst) == NULL)
ifa->flags &= ~IFA_F_OPTIMISTIC;
ifa->idev = idev;
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 424f063..03d6916 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -1536,7 +1536,7 @@ static int fib6_age(struct rt6_info *rt, void *arg)
RT6_TRACE("aging clone %p\n", rt);
return -1;
} else if ((rt->rt6i_flags & RTF_GATEWAY) &&
- (!(dst_get_neighbour_raw(&rt->dst)->flags & NTF_ROUTER))) {
+ (!(dst_get_neighbour_noref_raw(&rt->dst)->flags & NTF_ROUTER))) {
RT6_TRACE("purging route %p via non-router but gateway\n",
rt);
return -1;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index a24e155..d63fd1e 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -136,7 +136,7 @@ static int ip6_finish_output2(struct sk_buff *skb)
}
rcu_read_lock();
- neigh = dst_get_neighbour(dst);
+ neigh = dst_get_neighbour_noref(dst);
if (neigh) {
int res = neigh_output(neigh, skb);
@@ -462,7 +462,7 @@ int ip6_forward(struct sk_buff *skb)
send redirects to source routed frames.
We don't send redirects to frames decapsulated from IPsec.
*/
- n = dst_get_neighbour(dst);
+ n = dst_get_neighbour_noref(dst);
if (skb->dev == dst->dev && n && opt->srcrt == 0 && !skb_sec_path(skb)) {
struct in6_addr *target = NULL;
struct rt6_info *rt;
@@ -982,7 +982,7 @@ static int ip6_dst_lookup_tail(struct sock *sk,
* dst entry of the nexthop router
*/
rcu_read_lock();
- n = dst_get_neighbour(*dst);
+ n = dst_get_neighbour_noref(*dst);
if (n && !(n->nud_state & NUD_VALID)) {
struct inet6_ifaddr *ifp;
struct flowi6 fl_gw6;
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index cfb9709..e72c8af 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1238,7 +1238,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
rt = rt6_get_dflt_router(&ipv6_hdr(skb)->saddr, skb->dev);
if (rt)
- neigh = dst_get_neighbour(&rt->dst);
+ neigh = dst_get_neighbour_noref(&rt->dst);
if (rt && lifetime == 0) {
neigh_clone(neigh);
@@ -1258,7 +1258,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
return;
}
- neigh = dst_get_neighbour(&rt->dst);
+ neigh = dst_get_neighbour_noref(&rt->dst);
if (neigh == NULL) {
ND_PRINTK0(KERN_ERR
"ICMPv6 RA: %s() got default router without neighbour.\n",
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 0e381bb..3cf5d75 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -385,7 +385,7 @@ static void rt6_probe(struct rt6_info *rt)
* to no more than one per minute.
*/
rcu_read_lock();
- neigh = rt ? dst_get_neighbour(&rt->dst) : NULL;
+ neigh = rt ? dst_get_neighbour_noref(&rt->dst) : NULL;
if (!neigh || (neigh->nud_state & NUD_VALID))
goto out;
read_lock_bh(&neigh->lock);
@@ -432,7 +432,7 @@ static inline int rt6_check_neigh(struct rt6_info *rt)
int m;
rcu_read_lock();
- neigh = dst_get_neighbour(&rt->dst);
+ neigh = dst_get_neighbour_noref(&rt->dst);
if (rt->rt6i_flags & RTF_NONEXTHOP ||
!(rt->rt6i_flags & RTF_GATEWAY))
m = 1;
@@ -785,7 +785,7 @@ static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort,
if (rt) {
rt->rt6i_flags |= RTF_CACHE;
- dst_set_neighbour(&rt->dst, neigh_clone(dst_get_neighbour_raw(&ort->dst)));
+ dst_set_neighbour(&rt->dst, neigh_clone(dst_get_neighbour_noref_raw(&ort->dst)));
}
return rt;
}
@@ -819,7 +819,7 @@ restart:
dst_hold(&rt->dst);
read_unlock_bh(&table->tb6_lock);
- if (!dst_get_neighbour_raw(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP))
+ if (!dst_get_neighbour_noref_raw(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP))
nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr);
else if (!(rt->dst.flags & DST_HOST))
nrt = rt6_alloc_clone(rt, &fl6->daddr);
@@ -1627,7 +1627,7 @@ void rt6_redirect(const struct in6_addr *dest, const struct in6_addr *src,
dst_confirm(&rt->dst);
/* Duplicate redirect: silently ignore. */
- if (neigh == dst_get_neighbour_raw(&rt->dst))
+ if (neigh == dst_get_neighbour_noref_raw(&rt->dst))
goto out;
nrt = ip6_rt_copy(rt, dest);
@@ -1719,7 +1719,7 @@ again:
1. It is connected route. Action: COW
2. It is gatewayed route or NONEXTHOP route. Action: clone it.
*/
- if (!dst_get_neighbour_raw(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP))
+ if (!dst_get_neighbour_noref_raw(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP))
nrt = rt6_alloc_cow(rt, daddr, saddr);
else
nrt = rt6_alloc_clone(rt, daddr);
@@ -2454,7 +2454,7 @@ static int rt6_fill_node(struct net *net,
goto nla_put_failure;
rcu_read_lock();
- n = dst_get_neighbour(&rt->dst);
+ n = dst_get_neighbour_noref(&rt->dst);
if (n)
NLA_PUT(skb, RTA_GATEWAY, 16, &n->primary_key);
rcu_read_unlock();
@@ -2651,7 +2651,7 @@ static int rt6_info_route(struct rt6_info *rt, void *p_arg)
seq_puts(m, "00000000000000000000000000000000 00 ");
#endif
rcu_read_lock();
- n = dst_get_neighbour(&rt->dst);
+ n = dst_get_neighbour_noref(&rt->dst);
if (n) {
seq_printf(m, "%pi6", n->primary_key);
} else {
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 50968f2..b7d14cc 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -680,7 +680,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
struct neighbour *neigh = NULL;
if (skb_dst(skb))
- neigh = dst_get_neighbour(skb_dst(skb));
+ neigh = dst_get_neighbour_noref(skb_dst(skb));
if (neigh == NULL) {
if (net_ratelimit())
@@ -705,7 +705,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
struct neighbour *neigh = NULL;
if (skb_dst(skb))
- neigh = dst_get_neighbour(skb_dst(skb));
+ neigh = dst_get_neighbour_noref(skb_dst(skb));
if (neigh == NULL) {
if (net_ratelimit())
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index ed1336e..4532659 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -277,7 +277,7 @@ static inline int teql_resolve(struct sk_buff *skb,
return 0;
rcu_read_lock();
- mn = dst_get_neighbour(dst);
+ mn = dst_get_neighbour_noref(dst);
res = mn ? __teql_resolve(skb, skb_res, dev, txq, mn) : 0;
rcu_read_unlock();
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 4fce1ce..82e803b 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1499,7 +1499,7 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy,
goto free_dst;
/* Copy neighbour for reachability confirmation */
- dst_set_neighbour(dst0, neigh_clone(dst_get_neighbour(dst)));
+ dst_set_neighbour(dst0, neigh_clone(dst_get_neighbour_noref(dst)));
xfrm_init_path((struct xfrm_dst *)dst0, dst, nfheader_len);
xfrm_init_pmtu(dst_prev);
--
1.7.7.3
^ permalink raw reply related
* Re: [PATCH] infiniband: addr: Avoid unnecessary neigh lookup.
From: David Miller @ 2011-12-03 2:48 UTC (permalink / raw)
To: roland; +Cc: netdev
In-Reply-To: <CAL1RGDU8=G_TKRirxm6pMni3H3a-FbvDz+pzG_oaZo-LYBQ0bg@mail.gmail.com>
From: Roland Dreier <roland@kernel.org>
Date: Fri, 2 Dec 2011 15:18:00 -0800
>> So if it's OK with you I'd like to merge this stuff directly in the
>> net-next tree after getting your ACK on each patch.
>
> Sure, that's fine, and for this particular patch:
>
> Acked-by: Roland Dreier <roland@purestorage.com>
Thanks for reviewing Roland.
I reread this code and it turns out that the ipv6 handling does
the same exact thing as what I transformed ipv4 to do, so it's
better to have a helper function and make ipv4 and ipv6 use it.
I've sanitized the neighbour handling in the entire Infiniband
stack tonight, and I'll send that series out for review right now.
It will include an updated version of this patch.
^ permalink raw reply
* Re: Udp packets received with improper length
From: Gerrit Renker @ 2011-12-03 2:32 UTC (permalink / raw)
To: David Miller; +Cc: fsmail, netdev
In-Reply-To: <20111201.141136.1615370877653045134.davem@davemloft.net>
Dave, -
| From: paul bilke <fsmail@conspiracy.net>
| Date: Mon, 28 Nov 2011 15:23:52 -0600
|
| > On 11/23/2011 2:14 PM, paul bilke wrote:
| >> We recently updated an embedded powerpc platform from 2.6.32 to 2.6.37. When deployed in the field devices with the new kernel have started receiving truncated UDP packets from their mates across noisy links. To test we wrote a simple client and
| >> server. The client sends 512 byte packets with a sequence number to the server listening on a UDP socket. On the client box we use netem to corrupt 100% of the packets sent(after transferring some data so arp cache is populated). The server then
| >> dumps the length received and the serial number from any packets that are received. Netem sometimes corrupts bits in the source MAC address so these packets arrive with valid UDP checksums and are delivered to the user application. With the
| >> server running on the 2.6.32 box we send a few million packets to it and only receive packets that are exactly 512 bytes long. When we do the same on the box running 2.6.37 we receive hundred of short packets, zero length and also 504 byte packets.
| >> When I use TCPdump on the box running 2.6.37 the truncate packets have valid checksums (Source MAC was corrupted by NETEM) and are of proper length (554 byte ethernet frame, 540 Byte IP portion and 520 byte UDP length) but the userland receives 504
| >> or 0 length in recvfrom. To see if this was just a powerpc related issue I repeated the test on x86 virtual machines. A vm running 2.6.18 (Centos 5) receives only 512 byte packets. On a vm running 2.6.40 (Fedora 15) I receive 512, 504 and 0 length
| >> packets.
| > <clip>
| >
| > Reverting commit 81d54ec8479a2c695760da81f05b5a9fb2dbe40a makes this problem disappear. The patch looks sane, the results are problematic.
|
| I think that commit is buggy. If we do a goto to "try_again", the length has already been
| truncated the first time around, so the calculation is not the same as what the original code
| calculates
|
| And indeed, checksum errors are how we can end up taking this code path.
|
| I'm reverting.
|
You are correct. What I had failed to see is the try_again case with multiple corruped datagrams. In this case the
code is not correct, len could already have been modified in the previous iteration. Reverting the commit is the
sanest option. Thank you.
Gerrit
^ permalink raw reply
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