* Re: [PATCH] ifb: add multi-queue support
From: Changli Gao @ 2009-11-11 10:57 UTC (permalink / raw)
To: Eric Dumazet
Cc: David S. Miller, Stephen Hemminger, Patrick McHardy, Tom Herbert,
netdev
In-Reply-To: <4AFA9235.1030004@gmail.com>
2009/11/11 Eric Dumazet <eric.dumazet@gmail.com>:
>
> Or even better, tq could be local to ifb_xmit()
>
> ifb_xmit() would purge it itself, and could use __skb_dequeue() and
> other lockless primitives.
>
> The whole :
>
> while ((skb = skb_dequeue(&pq->rq)) != NULL)
> skb_queue_tail(&pq->tq, skb);
>
> could be optimized a lot IMHO, its almost a skb_queue_splice() thing...
>
Thanks, it is a good idea. Any others?
--
Regards,
Changli Gao(xiaosuo@gmail.com)
^ permalink raw reply
* [PATCH] sunrpc: off-by-two stack buffer overflow in function rpc_uaddr2sockaddr()
From: Patroklos Argyroudis @ 2009-11-11 11:02 UTC (permalink / raw)
To: Andrew Morton
Cc: netdev, J. Bruce Fields, Trond Myklebust, Neil Brown, linux-nfs
In-Reply-To: <20091110152908.7558a471.akpm@linux-foundation.org>
There is an off-by-two stack buffer overflow in function rpc_uaddr2sockaddr()
of file net/sunrpc/addr.c in the Linux kernel SUNRPC implementation.
The function rpc_uaddr2sockaddr() that is used to convert a universal address
to a socket address takes as an argument the size_t variable uaddr_len (the
length of the universal address string). The stack buffer buf is declared in
line 315 to be of size RPCBIND_MAXUADDRLEN. If the passed argument uaddr_len is
equal to RPCBIND_MAXUADDRLEN then the check at line 319 passes and then at
lines 324 and 325 there are two out-of-bounds assignments:
319 if (uaddr_len > sizeof(buf))
320 return 0;
...
324 buf[uaddr_len] = '\n';
325 buf[uaddr_len + 1] = '\0';
Signed-off-by: Patroklos Argyroudis <argp@census-labs.com>
---
--- linux-2.6/net/sunrpc/addr.c.orig 2009-11-11 12:33:04.000000000 +0200
+++ linux-2.6/net/sunrpc/addr.c 2009-11-11 12:33:32.000000000 +0200
@@ -316,7 +316,7 @@ size_t rpc_uaddr2sockaddr(const char *ua
unsigned long portlo, porthi;
unsigned short port;
- if (uaddr_len > sizeof(buf))
+ if (uaddr_len > sizeof(buf) - 2)
return 0;
memcpy(buf, uaddr, uaddr_len);
^ permalink raw reply
* Oops from tcp_collapse() when using splice()
From: Karl Hiramoto @ 2009-11-11 11:22 UTC (permalink / raw)
To: netdev
Hi, the following oops occurs with both 2.6.28.9 and 2.6.30.9
userspace program is using splice() on two tcp sockets.
Internal error: Oops: 817 [#1]
Modules linked in: pppoe pppox br2684 crc_ccitt nf_nat_pptp nf_nat_proto_gre nf_conntrack_pptp nf_conntrack_proto_gre af_key ixp4xx_crypto ipt_MASQUERADE
CPU: 0 Not tainted (2.6.30.9 #1)
PC is at tcp_collapse+0x268/0x338
LR is at 0xc2c49640
pc : [<c020be4c>] lr : [<c2c49640>] psr: 80000013
sp : c0323c80 ip : c3a09920 fp : c0323cb8
r10: 20ec0490 r9 : 00000e2c r8 : c2d117a0
r7 : c2c49620 r6 : c2d11780 r5 : c2c49600 r4 : 00000074
r3 : 00000000 r2 : 20ec4594 r1 : 00004104 r0 : c2c49600
Flags: Nzcv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel
Control: 000039ff Table: 02efc000 DAC: 00000017
Process swapper (pid: 0, stack limit = 0xc0322260)
Stack: (0xc0323c80 to 0xc0324000)
3c80: c3a09920 c3a09920 c3a098c0 ffffc476 c3a098c0 c3a098c0 0000059a c2cded80
3ca0: c2eef054 c3a09c20 c2eef054 c0323cfc c0323cbc c020c114 c020bbf0 20ec0490
3cc0: 20ed15b0 18295345 00000000 c3a09c20 00000000 000008ec c3a098c0 0000059a
3ce0: c2cded80 c2eef054 c2cdeda0 c2eef054 c0323d30 c0323d00 c020c394 c020bf28
3d00: c2e5ec00 ffffffff c3a098c0 c2cded80 0000059a c2eef054 00000020 c2cdeda0
3d20: c2eef054 c0323d5c c0323d34 c02102f8 c020c1b4 00000000 c2cded80 c3a098c0
3d40: c2eef054 c03576fc c2eef040 0000cd2b c0323d8c c0323d60 c0215770 c020fddc
3d60: bf11dcfc 00000000 c0323d8c c0323d78 00000000 c2cded80 c3a098c0 c2eef054
3d80: c0323dc8 c0323d90 c021750c c021574c 0a430f2d 0000cd2b 00000005 c0357e58
3da0: c033dd04 c2cded80 00000000 c03576fc c0358518 c033b870 00000000 c0323dec
3dc0: c0323dcc c01fb6ac c0216e6c c2cded80 c2cded80 c2eef040 c2e5ec00 c0357a40
3de0: c0323e0c c0323df0 c01fbb68 c01fb55c 00000000 c01fb550 80000000 c0357a20
3e00: c0323e38 c0323e10 c01fb52c c01fbaf8 c2e5ec00 c2cded80 c0357a20 c2cded80
3e20: c03576fc c2e5ec00 c0357a40 c0323e64 c0323e3c c01fbab8 c01fb22c 00000000
3e40: c01fb220 80000000 c0357a20 c2cded80 c2e5ec00 00000800 c0323e94 c0323e68
3e60: c01ddf24 c01fb86c c2e5c600 c0323ecc 00000002 c033b888 ffffbe5e 00000040
3e80: 00000000 c033b86c c0323ec0 c0323e98 c01ddff4 c01ddb9c c033b888 00000040
3ea0: 00000100 0000012c c033b86c c033b87c ffffbe60 c0323eec c0323ec4 c01e095c
3ec0: c01ddf74 c0322000 0000000c 00000100 00000001 00000009 c034b72c 00000000
3ee0: c0323f20 c0323ef0 c00359dc c01e0900 c0323efc c0029608 00000003 00000000
3f00: 00000008 c03426a8 0001c608 690541f1 0001c49c c0323f30 c0323f24 c0035c98
3f20: c003597c c0323f48 c0323f34 c0020058 c0035c60 ffffffff 0000001f c0323fa0
3f40: c0323f4c c00209c4 c002000c c03273c8 c383e300 c0322000 00000000 c0021de8
3f60: c0322000 c0021de8 c03426a8 0001c608 690541f1 0001c49c c0323fa0 c0323fa4
3f80: c0323f94 c0021cb0 c0021dfc 60000013 ffffffff c0323fc0 c0323fa4 c0021cb0
3fa0: c0021df4 c034dfc4 c0342450 c001dd60 c0326344 c0323fd0 c0323fc4 c0263be4
3fc0: c0021c80 c0323ff4 c0323fd4 c00089c0 c0263b98 c00083ac c001dd60 000039fd
3fe0: c03426d8 c001e164 00000000 c0323ff8 00008034 c00087bc 00000000 00000000
Backtrace:
[<c020bbe4>] (tcp_collapse+0x0/0x338) from [<c020c114>] (tcp_prune_queue+0x1f8/0x28c)
[<c020bf1c>] (tcp_prune_queue+0x0/0x28c) from [<c020c394>] (tcp_data_queue+0x1ec/0xc3c)
[<c020c1a8>] (tcp_data_queue+0x0/0xc3c) from [<c02102f8>] (tcp_rcv_established+0x528/0x5e0)
[<c020fdd0>] (tcp_rcv_established+0x0/0x5e0) from [<c0215770>] (tcp_v4_do_rcv+0x30/0x1c4)
[<c0215740>] (tcp_v4_do_rcv+0x0/0x1c4) from [<c021750c>] (tcp_v4_rcv+0x6ac/0x754)
r7:c2eef054 r6:c3a098c0 r5:c2cded80 r4:00000000
[<c0216e60>] (tcp_v4_rcv+0x0/0x754) from [<c01fb6ac>] (ip_local_deliver_finish+0x15c/0x21c)
[<c01fb550>] (ip_local_deliver_finish+0x0/0x21c) from [<c01fbb68>] (ip_local_deliver+0x7c/0x88)
r8:c0357a40 r7:c2e5ec00 r6:c2eef040 r5:c2cded80 r4:c2cded80
[<c01fbaec>] (ip_local_deliver+0x0/0x88) from [<c01fb52c>] (ip_rcv_finish+0x30c/0x330)
r4:c0357a20
[<c01fb220>] (ip_rcv_finish+0x0/0x330) from [<c01fbab8>] (ip_rcv+0x258/0x28c)
r8:c0357a40 r7:c2e5ec00 r6:c03576fc r5:c2cded80 r4:c0357a20
[<c01fb860>] (ip_rcv+0x0/0x28c) from [<c01ddf24>] (netif_receive_skb+0x394/0x3d8)
r7:00000800 r6:c2e5ec00 r5:c2cded80 r4:c0357a20
[<c01ddb90>] (netif_receive_skb+0x0/0x3d8) from [<c01ddff4>] (process_backlog+0x8c/0xd8)
[<c01ddf68>] (process_backlog+0x0/0xd8) from [<c01e095c>] (net_rx_action+0x68/0x188)
[<c01e08f4>] (net_rx_action+0x0/0x188) from [<c00359dc>] (__do_softirq+0x6c/0xf8)
[<c0035970>] (__do_softirq+0x0/0xf8) from [<c0035c98>] (irq_exit+0x44/0x4c)
[<c0035c54>] (irq_exit+0x0/0x4c) from [<c0020058>] (asm_do_IRQ+0x58/0x6c)
[<c0020000>] (asm_do_IRQ+0x0/0x6c) from [<c00209c4>] (__irq_svc+0x24/0x80)
Exception stack(0xc0323f4c to 0xc0323f94)
3f40: c03273c8 c383e300 c0322000 00000000 c0021de8
3f60: c0322000 c0021de8 c03426a8 0001c608 690541f1 0001c49c c0323fa0 c0323fa4
3f80: c0323f94 c0021cb0 c0021dfc 60000013 ffffffff
r5:0000001f r4:ffffffff
[<c0021de8>] (default_idle+0x0/0x4c) from [<c0021cb0>] (cpu_idle+0x3c/0x58)
[<c0021c74>] (cpu_idle+0x0/0x58) from [<c0263be4>] (rest_init+0x58/0x6c)
r7:c0326344 r6:c001dd60 r5:c0342450 r4:c034dfc4
[<c0263b8c>] (rest_init+0x0/0x6c) from [<c00089c0>] (start_kernel+0x210/0x264)
[<c00087b0>] (start_kernel+0x0/0x264) from [<00008034>] (0x8034)
r6:c001e164 r5:c03426d8 r4:000039fd
Code: e50b302c e06a1002 5a000002 e3a03000 (e5833000)
^ permalink raw reply
* Re: Oops from tcp_collapse() when using splice()
From: Karl Hiramoto @ 2009-11-11 11:38 UTC (permalink / raw)
To: netdev
In-Reply-To: <4AFA9E81.3050508@hiramoto.org>
Karl Hiramoto wrote:
> Hi, the following oops occurs with both 2.6.28.9 and 2.6.30.9
>
> userspace program is using splice() on two tcp sockets.
>
Unable to handle kernel NULL pointer dereference at virtual address
00000000
pgd =
c0004000
[00000000]
*pgd=00000000
Internal error: Oops: 817
[#1]
Modules linked in: pppoe pppox br2684 crc_ccitt nf_nat_pptp
nf_nat_proto_gre nf_conntrack_pptp nf_conntrack_proto_gre af_key
ixp4xx_crypto ipt_MASQUERADEc
CPU: 0 Not tainted (2.6.30.9
#1)
PC is at
tcp_collapse+0x268/0x338
LR is at
0xc2f047c0
pc : [<c020be4c>] lr : [<c2f047c0>] psr:
80000013
sp : c0323c90 ip : c3881d40 fp :
c0323cc8
r10: c6762c80 r9 : 00000e2c r8 :
c3b85920
r7 : c2f047a0 r6 : c3b85900 r5 : c2f04780 r4 :
00000074
r3 : 00000000 r2 : c6766d84 r1 : 00004104 r0 :
c2f04780
Flags: Nzcv IRQs on FIQs on Mode SVC_32 ISA ARM Segment
kernel
Control: 000039ff Table: 02cd0000 DAC:
00000017
Process swapper (pid: 0, stack limit =
0xc0322260)
Stack: (0xc0323c90 to
0xc0324000)
3c80: c3881d40 c3881d40 c3881ce0
ffffc476
3ca0: c3881ce0 c3881ce0 0000059a c2dd2d80 c2ea1054 c3882040 c2ea1054
c0323d0c
3cc0: c0323ccc c020c114 c020bbf0 c6762c80 c6773da0 b87d516b 00000000
c3882040
3ce0: 00000000 000008ec c3881ce0 0000059a c2dd2d80 c2ea1054 c2dd2da0
c2ea1054
3d00: c0323d40 c0323d10 c020c394 c020bf28 c2e46000 ffffffff c3881ce0
c2dd2d80
3d20: 0000059a c2ea1054 00000020 c2dd2da0 c2ea1054 c0323d6c c0323d44
c02102f8
3d40: c020c1b4 00000000 c2dd2d80 c3881ce0 c2ea1054 c03576fc c2ea1040
0000e76d
3d60: c0323d9c c0323d70 c0215770 c020fddc bf11dcfc 00000000 c0323d9c
c0323d88
3d80: 00000000 c2dd2d80 c3881ce0 c2ea1054 c0323dd8 c0323da0 c021750c
c021574c
3da0: 0a430f30 0000e76d 00000005 c0357e58 c033dd04 c2dd2d80 00000000
c03576fc
3dc0: c0358518 c033b870 00000000 c0323dfc c0323ddc c01fb6ac c0216e6c
c2dd2d80
3de0: c2dd2d80 c2ea1040 c2e46000 c0357a40 c0323e1c c0323e00 c01fbb68
c01fb55c
3e00: 00000000 c01fb550 80000000 c0357a20 c0323e48 c0323e20 c01fb52c
c01fbaf8
3e20: c2e46000 c2dd2d80 c0357a20 c2dd2d80 c03576fc c2e46000 c0357a40
c0323e74
3e40: c0323e4c c01fbab8 c01fb22c 00000000 c01fb220 80000000 c0357a20
c2dd2d80
3e60: c2e46000 00000800 c0323ea4 c0323e78 c01ddf24 c01fb86c c2e57a00
c0323edc
3e80: 00000002 c033b888 ffffabd7 00000040 00000000 c033b86c c0323ed0
c0323ea8
3ea0: c01ddff4 c01ddb9c c033b888 00000040 00000100 0000012c c033b86c
c033b87c
3ec0: ffffabd9 c0323efc c0323ed4 c01e095c c01ddf74 c0322000 0000000c
00000100
3ee0: 00000001 00000009 c034b72c 00000000 c0323f30 c0323f00 c00359dc
c01e0900
3f00: c0323f0c c0029608 00000003 00000000 00000008 c03426a8 0001c608
690541f1
3f20: 0001c49c c0323f40 c0323f34 c0035c98 c003597c c0323f58 c0323f44
c0020058
3f40: c0035c60 ffffffff 0000001f c0323fc0 c0323f5c c00209c4 c002000c
c03273c8
3f60: c381a900 a0000013 00000000 c0021de8 c0322000 c0021de8 c03426a8
0001c608
3f80: 690541f1 0001c49c c0323fc0 c0323fa4 c0323fa4 c0021cb0 c0021de8
60000013
3fa0: ffffffff c034dfc4 c0342450 c001dd60 c0326344 c0323fd0 c0323fc4
c0263be4
3fc0: c0021c80 c0323ff4 c0323fd4 c00089c0 c0263b98 c00083ac c001dd60
000039fd
3fe0: c03426d8 c001e164 00000000 c0323ff8 00008034 c00087bc 00000000
00000000
Backtrace:
[<c020bbe4>] (tcp_collapse+0x0/0x338) from [<c020c114>]
(tcp_prune_queue+0x1f8/0x28c)
[<c020bf1c>] (tcp_prune_queue+0x0/0x28c) from [<c020c394>]
(tcp_data_queue+0x1ec/0xc3c)
[<c020c1a8>] (tcp_data_queue+0x0/0xc3c) from [<c02102f8>]
(tcp_rcv_established+0x528/0x5e0)
[<c020fdd0>] (tcp_rcv_established+0x0/0x5e0) from [<c0215770>]
(tcp_v4_do_rcv+0x30/0x1c4)
[<c0215740>] (tcp_v4_do_rcv+0x0/0x1c4) from [<c021750c>]
(tcp_v4_rcv+0x6ac/0x754)
r7:c2ea1054 r6:c3881ce0 r5:c2dd2d80 r4:00000000
[<c0216e60>] (tcp_v4_rcv+0x0/0x754) from [<c01fb6ac>]
(ip_local_deliver_finish+0x15c/0x21c)
[<c01fb550>] (ip_local_deliver_finish+0x0/0x21c) from [<c01fbb68>]
(ip_local_deliver+0x7c/0x88)
r8:c0357a40 r7:c2e46000 r6:c2ea1040 r5:c2dd2d80 r4:c2dd2d80
[<c01fbaec>] (ip_local_deliver+0x0/0x88) from [<c01fb52c>]
(ip_rcv_finish+0x30c/0x330)
r4:c0357a20
[<c01fb220>] (ip_rcv_finish+0x0/0x330) from [<c01fbab8>]
(ip_rcv+0x258/0x28c)
r8:c0357a40 r7:c2e46000 r6:c03576fc r5:c2dd2d80 r4:c0357a20
[<c01fb860>] (ip_rcv+0x0/0x28c) from [<c01ddf24>]
(netif_receive_skb+0x394/0x3d8)
r7:00000800 r6:c2e46000 r5:c2dd2d80 r4:c0357a20
[<c01ddb90>] (netif_receive_skb+0x0/0x3d8) from [<c01ddff4>]
(process_backlog+0x8c/0xd8)
[<c01ddf68>] (process_backlog+0x0/0xd8) from [<c01e095c>]
(net_rx_action+0x68/0x188)
[<c01e08f4>] (net_rx_action+0x0/0x188) from [<c00359dc>]
(__do_softirq+0x6c/0xf8)
[<c0035970>] (__do_softirq+0x0/0xf8) from [<c0035c98>] (irq_exit+0x44/0x4c)
[<c0035c54>] (irq_exit+0x0/0x4c) from [<c0020058>] (asm_do_IRQ+0x58/0x6c)
[<c0020000>] (asm_do_IRQ+0x0/0x6c) from [<c00209c4>] (__irq_svc+0x24/0x80)
Exception stack(0xc0323f5c to 0xc0323fa4)
3f40:
c03273c8
3f60: c381a900 a0000013 00000000 c0021de8 c0322000 c0021de8 c03426a8
0001c608
3f80: 690541f1 0001c49c c0323fc0 c0323fa4 c0323fa4 c0021cb0 c0021de8
60000013
3fa0: ffffffff
r5:0000001f r4:ffffffff
[<c0021c74>] (cpu_idle+0x0/0x58) from [<c0263be4>] (rest_init+0x58/0x6c)
r7:c0326344 r6:c001dd60 r5:c0342450 r4:c034dfc4
[<c0263b8c>] (rest_init+0x0/0x6c) from [<c00089c0>]
(start_kernel+0x210/0x264)
[<c00087b0>] (start_kernel+0x0/0x264) from [<00008034>] (0x8034)
r6:c001e164 r5:c03426d8 r4:000039fd
Code: e50b302c e06a1002 5a000002 e3a03000 (e5833000)
^ permalink raw reply
* Re: [PATCH 2/2] au1000-eth: convert to platform_driver model
From: Florian Fainelli @ 2009-11-11 11:54 UTC (permalink / raw)
To: Manuel Lauss; +Cc: Ralf Baechle, linux-mips, netdev, David Miller
In-Reply-To: <f861ec6f0911100120j12d86b0cs3ef9c2816019eaf9@mail.gmail.com>
Hi Manuel,
On Tuesday 10 November 2009 10:20:25 Manuel Lauss wrote:
> Hi Florian,
>
> On Tue, Nov 10, 2009 at 1:13 AM, Florian Fainelli <florian@openwrt.org>
wrote:
> > This patch converts the au1000-eth driver to become a full
> > platform-driver as it ought to be. We now pass PHY-speficic
> > configurations through platform_data but for compatibility
> > the driver still assumes the default settings (search for PHY1 on
> > MAC0) when no platform_data is passed. Tested on my MTX-1 board.
[snip]
> >
> > - phydev = tmp_phydev;
> > - break; /* found it */
> > + if (aup->phy1_search_mac0) {
> > + /* try harder to find a PHY */
> > + if (!phydev && (aup->mac_id == 1)) {
> > + /* no PHY found, maybe we have a dual
> > PHY? */ + printk (KERN_INFO DRV_NAME ": no
> > PHY found on MAC1, " + "let's see
> > if it's attached to MAC0...\n"); +
> > + /* find the first (lowest address)
> > non-attached PHY on + * the MAC0 MII bus
> > */
> > + for (phy_addr = 0; phy_addr <
> > PHY_MAX_ADDR; phy_addr++) { + if
> > (aup->mac_id == 1)
> > + break;
>
> aup->mac_id needs to be 1 for this loop to be executed in the first
> place, and here
> you immediately bail out if it is.
>From the reading of the comment, it seems to me like we should not do anything
in this for loop if we were using MAC1, but I may have misunderstood that, as
such I have added this break to "comply" with the comment.
> Also, how do you access the phy map of the other controller without use of
> the au_macs[] structure? (which is unused after this patch and could be
> removed, along
> with the NUM_ETH_INTERFACES constant)
We access the phy map of the other controller by using the correct mii bus
identifier, since we have registered a per-interface mdio bus or have I
overlooked something ?
>
> > + struct phy_device *const
> > tmp_phydev = +
> > aup->mii_bus->phy_map[phy_addr];
>
> My compiler complains about mixed code/declarations.
That declaration was already there and as this patch has no intent to clean
anything right now, I have left it as-is.
--
Florian
^ permalink raw reply
* Re: [PATCH 2/2] au1000-eth: convert to platform_driver model
From: Manuel Lauss @ 2009-11-11 12:00 UTC (permalink / raw)
To: Florian Fainelli; +Cc: Ralf Baechle, linux-mips, netdev, David Miller
In-Reply-To: <200911111254.16500.florian@openwrt.org>
On Wed, Nov 11, 2009 at 12:54 PM, Florian Fainelli <florian@openwrt.org> wrote:
> Hi Manuel,
>
> On Tuesday 10 November 2009 10:20:25 Manuel Lauss wrote:
>> Hi Florian,
>>
>> On Tue, Nov 10, 2009 at 1:13 AM, Florian Fainelli <florian@openwrt.org>
> wrote:
>> > This patch converts the au1000-eth driver to become a full
>> > platform-driver as it ought to be. We now pass PHY-speficic
>> > configurations through platform_data but for compatibility
>> > the driver still assumes the default settings (search for PHY1 on
>> > MAC0) when no platform_data is passed. Tested on my MTX-1 board.
> [snip]
>> >
>> > - phydev = tmp_phydev;
>> > - break; /* found it */
>> > + if (aup->phy1_search_mac0) {
>> > + /* try harder to find a PHY */
>> > + if (!phydev && (aup->mac_id == 1)) {
>> > + /* no PHY found, maybe we have a dual
>> > PHY? */ + printk (KERN_INFO DRV_NAME ": no
>> > PHY found on MAC1, " + "let's see
>> > if it's attached to MAC0...\n"); +
>> > + /* find the first (lowest address)
>> > non-attached PHY on + * the MAC0 MII bus
>> > */
>> > + for (phy_addr = 0; phy_addr <
>> > PHY_MAX_ADDR; phy_addr++) { + if
>> > (aup->mac_id == 1)
>> > + break;
>>
>> aup->mac_id needs to be 1 for this loop to be executed in the first
>> place, and here
>> you immediately bail out if it is.
>
> From the reading of the comment, it seems to me like we should not do anything
> in this for loop if we were using MAC1, but I may have misunderstood that, as
> such I have added this break to "comply" with the comment.
>
>> Also, how do you access the phy map of the other controller without use of
>> the au_macs[] structure? (which is unused after this patch and could be
>> removed, along
>> with the NUM_ETH_INTERFACES constant)
>
> We access the phy map of the other controller by using the correct mii bus
> identifier, since we have registered a per-interface mdio bus or have I
> overlooked something ?
Don't know, that's why I asked.
>>
>> > + struct phy_device *const
>> > tmp_phydev = +
>> > aup->mii_bus->phy_map[phy_addr];
>>
>> My compiler complains about mixed code/declarations.
>
> That declaration was already there and as this patch has no intent to clean
> anything right now, I have left it as-is.
The "if (aup->mac_id == 1)" you inserted before it causes it.
You're right though in that there's some cleanup potential after this
patch has gone in...
Manuel Lauss
^ permalink raw reply
* [patch] missing dev_put() on error path in vif_add()
From: Dan Carpenter @ 2009-11-11 12:03 UTC (permalink / raw)
To: netdev; +Cc: davem
The other error paths in front of this one have a dev_put() but this one
got missed.
Found by smatch static checker.
regards,
dan carpenter
Signed-off-by: Dan Carpenter <error27@gmail.com>
--- orig/net/ipv4/ipmr.c 2009-11-11 13:34:20.000000000 +0200
+++ devel/net/ipv4/ipmr.c 2009-11-11 13:34:59.000000000 +0200
@@ -483,8 +483,10 @@
return -EINVAL;
}
- if ((in_dev = __in_dev_get_rtnl(dev)) == NULL)
+ if ((in_dev = __in_dev_get_rtnl(dev)) == NULL) {
+ dev_put(dev);
return -EADDRNOTAVAIL;
+ }
IPV4_DEVCONF(in_dev->cnf, MC_FORWARDING)++;
ip_rt_multicast_event(in_dev);
^ permalink raw reply
* Re: [Bugme-new] [Bug 14546] New: Off-by-two stack buffer overflow in function rpc_uaddr2sockaddr() of net/sunrpc/addr.c
From: Fabio Olive Leite @ 2009-11-11 12:11 UTC (permalink / raw)
To: Patroklos Argyroudis
Cc: Chuck Lever, bugzilla-daemon-590EEB7GvNiWaY/ihj7yzEB+6BGkLq7r,
bugme-daemon-590EEB7GvNiWaY/ihj7yzEB+6BGkLq7r,
Linux Network Developers, J. Bruce Fields, Trond Myklebust,
Neil Brown, Andrew Morton, Linux NFS Mailing list
In-Reply-To: <20091111075128.GA28323@evola>
On 2009-11-11 Patroklos Argyroudis wrote:
> On Tue, Nov 10, 2009 at 06:38:05PM -0500, Chuck Lever wrote:
> > Why wouldn't you bump the size of the buffer by two as well?
> > Otherwise valid universal addresses that are RPCBIND_MAXUADDRLEN
> > bytes long will fail here.
> >
> > > memcpy(buf, uaddr, uaddr_len);
>
> There is no need to increase the size of the buffer since the new
> check (if (uaddr_len > sizeof(buf) - 2)) will terminate the function
> in case the valid universal address is RPCBIND_MAXUADDRLEN bytes.
Failing to convert a valid address is incorrect and unexpected. What
Chuck meant is that since it is valid to have an address up to
RPCBIND_MAXUADDRLEN bytes long, the function should be able to work on
that, by having an internal buffer that allows for the extra "\n\0".
Cheers,
Fábio Olivé
--
ex sed lex awk yacc, e pluribus unix, amem
na matemática das idéias, permuta é igual a adição
e um debate inteligente implementa a multiplicação
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [Bugme-new] [Bug 14546] New: Off-by-two stack buffer overflow in function rpc_uaddr2sockaddr() of net/sunrpc/addr.c
From: Fabio Olive Leite @ 2009-11-11 12:34 UTC (permalink / raw)
To: Patroklos Argyroudis
Cc: Chuck Lever, bugzilla-daemon-590EEB7GvNiWaY/ihj7yzEB+6BGkLq7r,
bugme-daemon-590EEB7GvNiWaY/ihj7yzEB+6BGkLq7r,
Linux Network Developers, J. Bruce Fields, Trond Myklebust,
Neil Brown, Andrew Morton, Linux NFS Mailing list
In-Reply-To: <20091111075128.GA28323@evola>
On 2009-11-11 Patroklos Argyroudis wrote:
> There is no need to increase the size of the buffer since the new
> check (if (uaddr_len > sizeof(buf) - 2)) will terminate the function
> in case the valid universal address is RPCBIND_MAXUADDRLEN bytes.
On a second note, why is '\n' needed there? You should only need '\0',
as a '\n' at the end is not required by any of the string functions used
to convert the address.
I believe you could go with buf[RPCBIND_MAXUADDRLEN+1] for the extra
NUL only.
Cheers,
Fábio Olivé
--
ex sed lex awk yacc, e pluribus unix, amem
na matemática das idéias, permuta é igual a adição
e um debate inteligente implementa a multiplicação
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" 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] net/atm: move all compat_ioctl handling to atm/ioctl.c
From: Arnd Bergmann @ 2009-11-11 13:30 UTC (permalink / raw)
To: David Miller; +Cc: dwmw2, linux-kernel, netdev, eric.dumazet
In-Reply-To: <20091110.204118.12070030.davem@davemloft.net>
We have two implementations of the compat_ioctl handling for ATM, the
one that we have had for ages in fs/compat_ioctl.c and the one added to
net/atm/ioctl.c by David Woodhouse. Unfortunately, both versions are
incomplete, and in practice we use a very confusing combination of the
two.
For ioctl numbers that have the same identifier on 32 and 64 bit systems,
we go directly through the compat_ioctl socket operation, for those that
differ, we do a conversion in fs/compat_ioctl.c.
This patch moves both variants into the vcc_compat_ioctl() function,
while preserving the current behaviour. It also kills off the COMPATIBLE_IOCTL
definitions that we never use here.
Doing it this way is clearly not a good solution, but I hope it is a
step into the right direction, so that someone is able to clean up this
mess for real.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: David Woodhouse <dwmw2@infradead.org>
---
net/atm/ioctl.c | 188 +++++++++++++++++++++++++++++++++++++++++++++++-
net/socket.c | 218 -------------------------------------------------------
2 files changed, 186 insertions(+), 220 deletions(-)
diff --git a/net/atm/ioctl.c b/net/atm/ioctl.c
index 4da8892..4539c5c 100644
--- a/net/atm/ioctl.c
+++ b/net/atm/ioctl.c
@@ -191,8 +191,192 @@ int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
}
#ifdef CONFIG_COMPAT
-int vcc_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
+/*
+ * FIXME:
+ * The compat_ioctl handling is duplicated, using both these conversion
+ * routines and the compat argument to the actual handlers. Both
+ * versions are somewhat incomplete and should be merged, e.g. by
+ * moving the ioctl number translation into the actual handlers and
+ * killing the conversion code.
+ *
+ * -arnd, November 2009
+ */
+struct atmif_sioc32 {
+ compat_int_t number;
+ compat_int_t length;
+ compat_caddr_t arg;
+};
+
+struct atm_iobuf32 {
+ compat_int_t length;
+ compat_caddr_t buffer;
+};
+
+#define ATM_GETLINKRATE32 _IOW('a', ATMIOC_ITF+1, struct atmif_sioc32)
+#define ATM_GETNAMES32 _IOW('a', ATMIOC_ITF+3, struct atm_iobuf32)
+#define ATM_GETTYPE32 _IOW('a', ATMIOC_ITF+4, struct atmif_sioc32)
+#define ATM_GETESI32 _IOW('a', ATMIOC_ITF+5, struct atmif_sioc32)
+#define ATM_GETADDR32 _IOW('a', ATMIOC_ITF+6, struct atmif_sioc32)
+#define ATM_RSTADDR32 _IOW('a', ATMIOC_ITF+7, struct atmif_sioc32)
+#define ATM_ADDADDR32 _IOW('a', ATMIOC_ITF+8, struct atmif_sioc32)
+#define ATM_DELADDR32 _IOW('a', ATMIOC_ITF+9, struct atmif_sioc32)
+#define ATM_GETCIRANGE32 _IOW('a', ATMIOC_ITF+10, struct atmif_sioc32)
+#define ATM_SETCIRANGE32 _IOW('a', ATMIOC_ITF+11, struct atmif_sioc32)
+#define ATM_SETESI32 _IOW('a', ATMIOC_ITF+12, struct atmif_sioc32)
+#define ATM_SETESIF32 _IOW('a', ATMIOC_ITF+13, struct atmif_sioc32)
+#define ATM_GETSTAT32 _IOW('a', ATMIOC_SARCOM+0, struct atmif_sioc32)
+#define ATM_GETSTATZ32 _IOW('a', ATMIOC_SARCOM+1, struct atmif_sioc32)
+#define ATM_GETLOOP32 _IOW('a', ATMIOC_SARCOM+2, struct atmif_sioc32)
+#define ATM_SETLOOP32 _IOW('a', ATMIOC_SARCOM+3, struct atmif_sioc32)
+#define ATM_QUERYLOOP32 _IOW('a', ATMIOC_SARCOM+4, struct atmif_sioc32)
+
+static struct {
+ unsigned int cmd32;
+ unsigned int cmd;
+} atm_ioctl_map[] = {
+ { ATM_GETLINKRATE32, ATM_GETLINKRATE },
+ { ATM_GETNAMES32, ATM_GETNAMES },
+ { ATM_GETTYPE32, ATM_GETTYPE },
+ { ATM_GETESI32, ATM_GETESI },
+ { ATM_GETADDR32, ATM_GETADDR },
+ { ATM_RSTADDR32, ATM_RSTADDR },
+ { ATM_ADDADDR32, ATM_ADDADDR },
+ { ATM_DELADDR32, ATM_DELADDR },
+ { ATM_GETCIRANGE32, ATM_GETCIRANGE },
+ { ATM_SETCIRANGE32, ATM_SETCIRANGE },
+ { ATM_SETESI32, ATM_SETESI },
+ { ATM_SETESIF32, ATM_SETESIF },
+ { ATM_GETSTAT32, ATM_GETSTAT },
+ { ATM_GETSTATZ32 ATM_GETSTATZ },
+ { ATM_GETLOOP32, ATM_GETLOOP },
+ { ATM_SETLOOP32, ATM_SETLOOP },
+ { ATM_QUERYLOOP32, ATM_QUERYLOOP },
+};
+
+#define NR_ATM_IOCTL ARRAY_SIZE(atm_ioctl_map)
+
+static int do_atm_iobuf(struct socket *sock, unsigned int cmd,
+ unsigned long arg)
+{
+ struct atm_iobuf __user *iobuf;
+ struct atm_iobuf32 __user *iobuf32;
+ u32 data;
+ void __user *datap;
+ int len, err;
+
+ iobuf = compat_alloc_user_space(sizeof(*iobuf));
+ iobuf32 = compat_ptr(arg);
+
+ if (get_user(len, &iobuf32->length) ||
+ get_user(data, &iobuf32->buffer))
+ return -EFAULT;
+ datap = compat_ptr(data);
+ if (put_user(len, &iobuf->length) ||
+ put_user(datap, &iobuf->buffer))
+ return -EFAULT;
+
+ err = do_vcc_ioctl(sock, cmd, (unsigned long) iobuf, 0);
+
+ if (!err) {
+ if (copy_in_user(&iobuf32->length, &iobuf->length,
+ sizeof(int)))
+ err = -EFAULT;
+ }
+
+ return err;
+}
+
+static int do_atmif_sioc(struct socket *sock, unsigned int cmd,
+ unsigned long arg)
+{
+ struct atmif_sioc __user *sioc;
+ struct atmif_sioc32 __user *sioc32;
+ u32 data;
+ void __user *datap;
+ int err;
+
+ sioc = compat_alloc_user_space(sizeof(*sioc));
+ sioc32 = compat_ptr(arg);
+
+ if (copy_in_user(&sioc->number, &sioc32->number, 2 * sizeof(int))
+ || get_user(data, &sioc32->arg))
+ return -EFAULT;
+ datap = compat_ptr(data);
+ if (put_user(datap, &sioc->arg))
+ return -EFAULT;
+
+ err = do_vcc_ioctl(sock, cmd, (unsigned long) sioc, 0);
+
+ if (!err) {
+ if (copy_in_user(&sioc32->length, &sioc->length,
+ sizeof(int)))
+ err = -EFAULT;
+ }
+ return err;
+}
+
+static int do_atm_ioctl(struct socket *sock, unsigned int cmd32,
+ unsigned long arg)
{
- return do_vcc_ioctl(sock, cmd, arg, 1);
+ int i;
+ unsigned int cmd = 0;
+
+ switch (cmd32) {
+ case SONET_GETSTAT:
+ case SONET_GETSTATZ:
+ case SONET_GETDIAG:
+ case SONET_SETDIAG:
+ case SONET_CLRDIAG:
+ case SONET_SETFRAMING:
+ case SONET_GETFRAMING:
+ case SONET_GETFRSENSE:
+ return do_atmif_sioc(sock, cmd32, arg);
+ }
+
+ for (i = 0; i < NR_ATM_IOCTL; i++) {
+ if (cmd32 == atm_ioctl_map[i].cmd32) {
+ cmd = atm_ioctl_map[i].cmd;
+ break;
+ }
+ }
+ if (i == NR_ATM_IOCTL)
+ return -EINVAL;
+
+ switch (cmd) {
+ case ATM_GETNAMES:
+ return do_atm_iobuf(sock, cmd, arg);
+
+ case ATM_GETLINKRATE:
+ case ATM_GETTYPE:
+ case ATM_GETESI:
+ case ATM_GETADDR:
+ case ATM_RSTADDR:
+ case ATM_ADDADDR:
+ case ATM_DELADDR:
+ case ATM_GETCIRANGE:
+ case ATM_SETCIRANGE:
+ case ATM_SETESI:
+ case ATM_SETESIF:
+ case ATM_GETSTAT:
+ case ATM_GETSTATZ:
+ case ATM_GETLOOP:
+ case ATM_SETLOOP:
+ case ATM_QUERYLOOP:
+ return do_atmif_sioc(sock, cmd, arg);
+ }
+
+ return -EINVAL;
+}
+
+int vcc_compat_ioctl(struct socket *sock, unsigned int cmd,
+ unsigned long arg)
+{
+ int ret;
+
+ ret = do_vcc_ioctl(sock, cmd, arg, 1);
+ if (ret != -ENOIOCTLCMD)
+ return ret;
+
+ return do_atm_ioctl(sock, cmd, arg);
}
#endif
diff --git a/net/socket.c b/net/socket.c
index 05c4828..402abb3 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -100,14 +100,6 @@
#include <linux/if_tun.h>
#include <linux/ipv6_route.h>
#include <linux/route.h>
-#include <linux/atmdev.h>
-#include <linux/atmarp.h>
-#include <linux/atmsvc.h>
-#include <linux/atmlec.h>
-#include <linux/atmclip.h>
-#include <linux/atmmpc.h>
-#include <linux/atm_tcp.h>
-#include <linux/sonet.h>
#include <linux/sockios.h>
#include <linux/atalk.h>
@@ -2917,173 +2909,6 @@ static int old_bridge_ioctl(compat_ulong_t __user *argp)
return -EINVAL;
}
-struct atmif_sioc32 {
- compat_int_t number;
- compat_int_t length;
- compat_caddr_t arg;
-};
-
-struct atm_iobuf32 {
- compat_int_t length;
- compat_caddr_t buffer;
-};
-
-#define ATM_GETLINKRATE32 _IOW('a', ATMIOC_ITF+1, struct atmif_sioc32)
-#define ATM_GETNAMES32 _IOW('a', ATMIOC_ITF+3, struct atm_iobuf32)
-#define ATM_GETTYPE32 _IOW('a', ATMIOC_ITF+4, struct atmif_sioc32)
-#define ATM_GETESI32 _IOW('a', ATMIOC_ITF+5, struct atmif_sioc32)
-#define ATM_GETADDR32 _IOW('a', ATMIOC_ITF+6, struct atmif_sioc32)
-#define ATM_RSTADDR32 _IOW('a', ATMIOC_ITF+7, struct atmif_sioc32)
-#define ATM_ADDADDR32 _IOW('a', ATMIOC_ITF+8, struct atmif_sioc32)
-#define ATM_DELADDR32 _IOW('a', ATMIOC_ITF+9, struct atmif_sioc32)
-#define ATM_GETCIRANGE32 _IOW('a', ATMIOC_ITF+10, struct atmif_sioc32)
-#define ATM_SETCIRANGE32 _IOW('a', ATMIOC_ITF+11, struct atmif_sioc32)
-#define ATM_SETESI32 _IOW('a', ATMIOC_ITF+12, struct atmif_sioc32)
-#define ATM_SETESIF32 _IOW('a', ATMIOC_ITF+13, struct atmif_sioc32)
-#define ATM_GETSTAT32 _IOW('a', ATMIOC_SARCOM+0, struct atmif_sioc32)
-#define ATM_GETSTATZ32 _IOW('a', ATMIOC_SARCOM+1, struct atmif_sioc32)
-#define ATM_GETLOOP32 _IOW('a', ATMIOC_SARCOM+2, struct atmif_sioc32)
-#define ATM_SETLOOP32 _IOW('a', ATMIOC_SARCOM+3, struct atmif_sioc32)
-#define ATM_QUERYLOOP32 _IOW('a', ATMIOC_SARCOM+4, struct atmif_sioc32)
-
-static struct {
- unsigned int cmd32;
- unsigned int cmd;
-} atm_ioctl_map[] = {
- { ATM_GETLINKRATE32, ATM_GETLINKRATE },
- { ATM_GETNAMES32, ATM_GETNAMES },
- { ATM_GETTYPE32, ATM_GETTYPE },
- { ATM_GETESI32, ATM_GETESI },
- { ATM_GETADDR32, ATM_GETADDR },
- { ATM_RSTADDR32, ATM_RSTADDR },
- { ATM_ADDADDR32, ATM_ADDADDR },
- { ATM_DELADDR32, ATM_DELADDR },
- { ATM_GETCIRANGE32, ATM_GETCIRANGE },
- { ATM_SETCIRANGE32, ATM_SETCIRANGE },
- { ATM_SETESI32, ATM_SETESI },
- { ATM_SETESIF32, ATM_SETESIF },
- { ATM_GETSTAT32, ATM_GETSTAT },
- { ATM_GETSTATZ32, ATM_GETSTATZ },
- { ATM_GETLOOP32, ATM_GETLOOP },
- { ATM_SETLOOP32, ATM_SETLOOP },
- { ATM_QUERYLOOP32, ATM_QUERYLOOP }
-};
-
-#define NR_ATM_IOCTL ARRAY_SIZE(atm_ioctl_map)
-
-static int do_atm_iobuf(struct net *net, struct socket *sock,
- unsigned int cmd, unsigned long arg)
-{
- struct atm_iobuf __user *iobuf;
- struct atm_iobuf32 __user *iobuf32;
- u32 data;
- void __user *datap;
- int len, err;
-
- iobuf = compat_alloc_user_space(sizeof(*iobuf));
- iobuf32 = compat_ptr(arg);
-
- if (get_user(len, &iobuf32->length) ||
- get_user(data, &iobuf32->buffer))
- return -EFAULT;
- datap = compat_ptr(data);
- if (put_user(len, &iobuf->length) ||
- put_user(datap, &iobuf->buffer))
- return -EFAULT;
-
- err = sock_do_ioctl(net, sock, cmd, (unsigned long)iobuf);
-
- if (!err) {
- if (copy_in_user(&iobuf32->length, &iobuf->length,
- sizeof(int)))
- err = -EFAULT;
- }
-
- return err;
-}
-
-static int do_atmif_sioc(struct net *net, struct socket *sock,
- unsigned int cmd, unsigned long arg)
-{
- struct atmif_sioc __user *sioc;
- struct atmif_sioc32 __user *sioc32;
- u32 data;
- void __user *datap;
- int err;
-
- sioc = compat_alloc_user_space(sizeof(*sioc));
- sioc32 = compat_ptr(arg);
-
- if (copy_in_user(&sioc->number, &sioc32->number, 2 * sizeof(int)) ||
- get_user(data, &sioc32->arg))
- return -EFAULT;
- datap = compat_ptr(data);
- if (put_user(datap, &sioc->arg))
- return -EFAULT;
-
- err = sock_do_ioctl(net, sock, cmd, (unsigned long) sioc);
-
- if (!err) {
- if (copy_in_user(&sioc32->length, &sioc->length,
- sizeof(int)))
- err = -EFAULT;
- }
- return err;
-}
-
-static int do_atm_ioctl(struct net *net, struct socket *sock,
- unsigned int cmd32, unsigned long arg)
-{
- int i;
- unsigned int cmd = 0;
-
- switch (cmd32) {
- case SONET_GETSTAT:
- case SONET_GETSTATZ:
- case SONET_GETDIAG:
- case SONET_SETDIAG:
- case SONET_CLRDIAG:
- case SONET_SETFRAMING:
- case SONET_GETFRAMING:
- case SONET_GETFRSENSE:
- return do_atmif_sioc(net, sock, cmd32, arg);
- }
-
- for (i = 0; i < NR_ATM_IOCTL; i++) {
- if (cmd32 == atm_ioctl_map[i].cmd32) {
- cmd = atm_ioctl_map[i].cmd;
- break;
- }
- }
- if (i == NR_ATM_IOCTL)
- return -EINVAL;
-
- switch (cmd) {
- case ATM_GETNAMES:
- return do_atm_iobuf(net, sock, cmd, arg);
-
- case ATM_GETLINKRATE:
- case ATM_GETTYPE:
- case ATM_GETESI:
- case ATM_GETADDR:
- case ATM_RSTADDR:
- case ATM_ADDADDR:
- case ATM_DELADDR:
- case ATM_GETCIRANGE:
- case ATM_SETCIRANGE:
- case ATM_SETESI:
- case ATM_SETESIF:
- case ATM_GETSTAT:
- case ATM_GETSTATZ:
- case ATM_GETLOOP:
- case ATM_SETLOOP:
- case ATM_QUERYLOOP:
- return do_atmif_sioc(net, sock, cmd, arg);
- }
-
- return -EINVAL;
-}
-
static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
unsigned int cmd, unsigned long arg)
{
@@ -3173,49 +2998,6 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
case SIOCSMIIREG:
return dev_ifsioc(net, sock, cmd, argp);
- case ATM_GETLINKRATE32:
- case ATM_GETNAMES32:
- case ATM_GETTYPE32:
- case ATM_GETESI32:
- case ATM_GETADDR32:
- case ATM_RSTADDR32:
- case ATM_ADDADDR32:
- case ATM_DELADDR32:
- case ATM_GETCIRANGE32:
- case ATM_SETCIRANGE32:
- case ATM_SETESI32:
- case ATM_SETESIF32:
- case ATM_GETSTAT32:
- case ATM_GETSTATZ32:
- case ATM_GETLOOP32:
- case ATM_SETLOOP32:
- case ATM_QUERYLOOP32:
- case SONET_GETSTAT:
- case SONET_GETSTATZ:
- case SONET_GETDIAG:
- case SONET_SETDIAG:
- case SONET_CLRDIAG:
- case SONET_SETFRAMING:
- case SONET_GETFRAMING:
- case SONET_GETFRSENSE:
- return do_atm_ioctl(net, sock, cmd, arg);
-
- case ATMSIGD_CTRL:
- case ATMARPD_CTRL:
- case ATMLEC_CTRL:
- case ATMLEC_MCAST:
- case ATMLEC_DATA:
- case ATM_SETSC:
- case SIOCSIFATMTCP:
- case SIOCMKCLIP:
- case ATMARP_MKIP:
- case ATMARP_SETENTRY:
- case ATMARP_ENCAP:
- case ATMTCP_CREATE:
- case ATMTCP_REMOVE:
- case ATMMPC_CTRL:
- case ATMMPC_DATA:
-
case SIOCSARP:
case SIOCGARP:
case SIOCDARP:
--
1.6.3.3
^ permalink raw reply related
* Re: [PATCH] net/atm: move all compat_ioctl handling to atm/ioctl.c
From: David Woodhouse @ 2009-11-11 13:34 UTC (permalink / raw)
To: Arnd Bergmann; +Cc: David Miller, linux-kernel, netdev, eric.dumazet
In-Reply-To: <200911111430.44361.arnd@arndb.de>
On Wed, 2009-11-11 at 14:30 +0100, Arnd Bergmann wrote:
>
> +struct atmif_sioc32 {
> + compat_int_t number;
> + compat_int_t length;
> + compat_caddr_t arg;
> +};
> +
> +struct atm_iobuf32 {
> + compat_int_t length;
> + compat_caddr_t buffer;
> +};
We already have compat_atmif_sioc and compat_atm_iobuf structures
defined -- do those need to be duplicated?
Other than that, it looks sane. I wish I'd noticed that we already had
half a COMPAT implementation when I added the new bits. Thanks.
--
David Woodhouse Open Source Technology Centre
David.Woodhouse@intel.com Intel Corporation
^ permalink raw reply
* [PATCH] net/compat: fix dev_ifsioc emulation corner cases
From: Arnd Bergmann @ 2009-11-11 13:39 UTC (permalink / raw)
To: David Miller, linux-kernel, Patrick Ohly; +Cc: netdev
In-Reply-To: <20091110.204118.12070030.davem@davemloft.net>
Handling for SIOCSHWTSTAMP is broken on architectures
with a split user/kernel address space like s390,
because it passes a real user pointer while using
set_fs(KERNEL_DS).
A similar problem might arise the next time somebody
adds code to dev_ifsioc.
Split up dev_ifsioc into three separate functions for
SIOCSHWTSTAMP, SIOC*IFMAP and all other numbers so
we can get rid of set_fs in all potentially affected
cases.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Cc: Patrick Ohly <patrick.ohly@intel.com>
Cc: David S. Miller <davem@davemloft.net>
---
net/socket.c | 117 +++++++++++++++++++++++++++++++++++----------------------
1 files changed, 72 insertions(+), 45 deletions(-)
Resending this one as well, rebased to current net-next.
Please tell me if you want a backport to 2.6.32 or -stable
for this one.
diff --git a/net/socket.c b/net/socket.c
index befd9f5..05c4828 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -2723,38 +2723,15 @@ static int siocdevprivate_ioctl(struct net *net, unsigned int cmd,
static int dev_ifsioc(struct net *net, struct socket *sock,
unsigned int cmd, struct compat_ifreq __user *uifr32)
{
- struct ifreq ifr;
- struct compat_ifmap __user *uifmap32;
- mm_segment_t old_fs;
+ struct ifreq __user *uifr;
int err;
- uifmap32 = &uifr32->ifr_ifru.ifru_map;
- switch (cmd) {
- case SIOCSIFMAP:
- err = copy_from_user(&ifr, uifr32, sizeof(ifr.ifr_name));
- err |= __get_user(ifr.ifr_map.mem_start, &uifmap32->mem_start);
- err |= __get_user(ifr.ifr_map.mem_end, &uifmap32->mem_end);
- err |= __get_user(ifr.ifr_map.base_addr, &uifmap32->base_addr);
- err |= __get_user(ifr.ifr_map.irq, &uifmap32->irq);
- err |= __get_user(ifr.ifr_map.dma, &uifmap32->dma);
- err |= __get_user(ifr.ifr_map.port, &uifmap32->port);
- if (err)
- return -EFAULT;
- break;
- case SIOCSHWTSTAMP:
- if (copy_from_user(&ifr, uifr32, sizeof(*uifr32)))
- return -EFAULT;
- ifr.ifr_data = compat_ptr(uifr32->ifr_ifru.ifru_data);
- break;
- default:
- if (copy_from_user(&ifr, uifr32, sizeof(*uifr32)))
- return -EFAULT;
- break;
- }
- old_fs = get_fs();
- set_fs (KERNEL_DS);
- err = sock_do_ioctl(net, sock, cmd, (unsigned long)&ifr);
- set_fs (old_fs);
+ uifr = compat_alloc_user_space(sizeof(*uifr));
+ if (copy_in_user(uifr, uifr32, sizeof(*uifr32)))
+ return -EFAULT;
+
+ err = sock_do_ioctl(net, sock, cmd, (unsigned long)uifr);
+
if (!err) {
switch (cmd) {
case SIOCGIFFLAGS:
@@ -2771,18 +2748,7 @@ static int dev_ifsioc(struct net *net, struct socket *sock,
case SIOCGIFTXQLEN:
case SIOCGMIIPHY:
case SIOCGMIIREG:
- if (copy_to_user(uifr32, &ifr, sizeof(*uifr32)))
- return -EFAULT;
- break;
- case SIOCGIFMAP:
- err = copy_to_user(uifr32, &ifr, sizeof(ifr.ifr_name));
- err |= __put_user(ifr.ifr_map.mem_start, &uifmap32->mem_start);
- err |= __put_user(ifr.ifr_map.mem_end, &uifmap32->mem_end);
- err |= __put_user(ifr.ifr_map.base_addr, &uifmap32->base_addr);
- err |= __put_user(ifr.ifr_map.irq, &uifmap32->irq);
- err |= __put_user(ifr.ifr_map.dma, &uifmap32->dma);
- err |= __put_user(ifr.ifr_map.port, &uifmap32->port);
- if (err)
+ if (copy_in_user(uifr32, uifr, sizeof(*uifr32)))
err = -EFAULT;
break;
}
@@ -2790,6 +2756,65 @@ static int dev_ifsioc(struct net *net, struct socket *sock,
return err;
}
+static int compat_sioc_ifmap(struct net *net, unsigned int cmd,
+ struct compat_ifreq __user *uifr32)
+{
+ struct ifreq ifr;
+ struct compat_ifmap __user *uifmap32;
+ mm_segment_t old_fs;
+ int err;
+
+ uifmap32 = &uifr32->ifr_ifru.ifru_map;
+ err = copy_from_user(&ifr, uifr32, sizeof(ifr.ifr_name));
+ err |= __get_user(ifr.ifr_map.mem_start, &uifmap32->mem_start);
+ err |= __get_user(ifr.ifr_map.mem_end, &uifmap32->mem_end);
+ err |= __get_user(ifr.ifr_map.base_addr, &uifmap32->base_addr);
+ err |= __get_user(ifr.ifr_map.irq, &uifmap32->irq);
+ err |= __get_user(ifr.ifr_map.dma, &uifmap32->dma);
+ err |= __get_user(ifr.ifr_map.port, &uifmap32->port);
+ if (err)
+ return -EFAULT;
+
+ old_fs = get_fs();
+ set_fs (KERNEL_DS);
+ err = dev_ioctl(net, cmd, (void __user *)&ifr);
+ set_fs (old_fs);
+
+ if (cmd == SIOCGIFMAP && !err) {
+ err = copy_to_user(uifr32, &ifr, sizeof(ifr.ifr_name));
+ err |= __put_user(ifr.ifr_map.mem_start, &uifmap32->mem_start);
+ err |= __put_user(ifr.ifr_map.mem_end, &uifmap32->mem_end);
+ err |= __put_user(ifr.ifr_map.base_addr, &uifmap32->base_addr);
+ err |= __put_user(ifr.ifr_map.irq, &uifmap32->irq);
+ err |= __put_user(ifr.ifr_map.dma, &uifmap32->dma);
+ err |= __put_user(ifr.ifr_map.port, &uifmap32->port);
+ if (err)
+ err = -EFAULT;
+ }
+ return err;
+}
+
+static int compat_siocshwtstamp(struct net *net, struct compat_ifreq __user *uifr32)
+{
+ void __user *uptr;
+ compat_uptr_t uptr32;
+ struct ifreq __user *uifr;
+
+ uifr = compat_alloc_user_space(sizeof (*uifr));
+ if (copy_in_user(uifr, uifr32, sizeof(struct compat_ifreq)))
+ return -EFAULT;
+
+ if (get_user(uptr32, &uifr32->ifr_data))
+ return -EFAULT;
+
+ uptr = compat_ptr(uptr32);
+
+ if (put_user(uptr, &uifr->ifr_data))
+ return -EFAULT;
+
+ return dev_ioctl(net, SIOCSHWTSTAMP, uifr);
+}
+
struct rtentry32 {
u32 rt_pad1;
struct sockaddr rt_dst; /* target address */
@@ -3081,6 +3106,9 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
return ethtool_ioctl(net, argp);
case SIOCWANDEV:
return compat_siocwandev(net, argp);
+ case SIOCGIFMAP:
+ case SIOCSIFMAP:
+ return compat_sioc_ifmap(net, cmd, argp);
case SIOCBONDENSLAVE:
case SIOCBONDRELEASE:
case SIOCBONDSETHWADDR:
@@ -3095,6 +3123,8 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
return do_siocgstamp(net, sock, cmd, argp);
case SIOCGSTAMPNS:
return do_siocgstampns(net, sock, cmd, argp);
+ case SIOCSHWTSTAMP:
+ return compat_siocshwtstamp(net, argp);
case FIOSETOWN:
case SIOCSPGRP:
@@ -3121,12 +3151,9 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
case SIOCADDMULTI:
case SIOCDELMULTI:
case SIOCGIFINDEX:
- case SIOCGIFMAP:
- case SIOCSIFMAP:
case SIOCGIFADDR:
case SIOCSIFADDR:
case SIOCSIFHWBROADCAST:
- case SIOCSHWTSTAMP:
case SIOCDIFADDR:
case SIOCGIFBRDADDR:
case SIOCSIFBRDADDR:
--
1.6.3.3
^ permalink raw reply related
* [PATCH v3] net/atm: move all compat_ioctl handling to atm/ioctl.c
From: Arnd Bergmann @ 2009-11-11 13:45 UTC (permalink / raw)
To: David Woodhouse; +Cc: David Miller, linux-kernel, netdev, eric.dumazet
In-Reply-To: <1257946490.25961.1396.camel@macbook.infradead.org>
We have two implementations of the compat_ioctl handling for ATM, the
one that we have had for ages in fs/compat_ioctl.c and the one added to
net/atm/ioctl.c by David Woodhouse. Unfortunately, both versions are
incomplete, and in practice we use a very confusing combination of the
two.
For ioctl numbers that have the same identifier on 32 and 64 bit systems,
we go directly through the compat_ioctl socket operation, for those that
differ, we do a conversion in fs/compat_ioctl.c.
This patch moves both variants into the vcc_compat_ioctl() function,
while preserving the current behaviour. It also kills off the COMPATIBLE_IOCTL
definitions that we never use here.
Doing it this way is clearly not a good solution, but I hope it is a
step into the right direction, so that someone is able to clean up this
mess for real.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: David Woodhouse <dwmw2@infradead.org>
---
history:
v3: now with the duplicate data structures removed.
v2: ported to net-next, which has the code in net/socket.c
net/atm/ioctl.c | 177 ++++++++++++++++++++++++++++++++++++++++++++-
net/socket.c | 218 -------------------------------------------------------
2 files changed, 175 insertions(+), 220 deletions(-)
diff --git a/net/atm/ioctl.c b/net/atm/ioctl.c
index 4da8892..2ea4099 100644
--- a/net/atm/ioctl.c
+++ b/net/atm/ioctl.c
@@ -191,8 +191,181 @@ int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
}
#ifdef CONFIG_COMPAT
-int vcc_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
+/*
+ * FIXME:
+ * The compat_ioctl handling is duplicated, using both these conversion
+ * routines and the compat argument to the actual handlers. Both
+ * versions are somewhat incomplete and should be merged, e.g. by
+ * moving the ioctl number translation into the actual handlers and
+ * killing the conversion code.
+ *
+ * -arnd, November 2009
+ */
+#define ATM_GETLINKRATE32 _IOW('a', ATMIOC_ITF+1, struct compat_atmif_sioc)
+#define ATM_GETNAMES32 _IOW('a', ATMIOC_ITF+3, struct compat_atm_iobuf)
+#define ATM_GETTYPE32 _IOW('a', ATMIOC_ITF+4, struct compat_atmif_sioc)
+#define ATM_GETESI32 _IOW('a', ATMIOC_ITF+5, struct compat_atmif_sioc)
+#define ATM_GETADDR32 _IOW('a', ATMIOC_ITF+6, struct compat_atmif_sioc)
+#define ATM_RSTADDR32 _IOW('a', ATMIOC_ITF+7, struct compat_atmif_sioc)
+#define ATM_ADDADDR32 _IOW('a', ATMIOC_ITF+8, struct compat_atmif_sioc)
+#define ATM_DELADDR32 _IOW('a', ATMIOC_ITF+9, struct compat_atmif_sioc)
+#define ATM_GETCIRANGE32 _IOW('a', ATMIOC_ITF+10, struct compat_atmif_sioc)
+#define ATM_SETCIRANGE32 _IOW('a', ATMIOC_ITF+11, struct compat_atmif_sioc)
+#define ATM_SETESI32 _IOW('a', ATMIOC_ITF+12, struct compat_atmif_sioc)
+#define ATM_SETESIF32 _IOW('a', ATMIOC_ITF+13, struct compat_atmif_sioc)
+#define ATM_GETSTAT32 _IOW('a', ATMIOC_SARCOM+0, struct compat_atmif_sioc)
+#define ATM_GETSTATZ32 _IOW('a', ATMIOC_SARCOM+1, struct compat_atmif_sioc)
+#define ATM_GETLOOP32 _IOW('a', ATMIOC_SARCOM+2, struct compat_atmif_sioc)
+#define ATM_SETLOOP32 _IOW('a', ATMIOC_SARCOM+3, struct compat_atmif_sioc)
+#define ATM_QUERYLOOP32 _IOW('a', ATMIOC_SARCOM+4, struct compat_atmif_sioc)
+
+static struct {
+ unsigned int cmd32;
+ unsigned int cmd;
+} atm_ioctl_map[] = {
+ { ATM_GETLINKRATE32, ATM_GETLINKRATE },
+ { ATM_GETNAMES32, ATM_GETNAMES },
+ { ATM_GETTYPE32, ATM_GETTYPE },
+ { ATM_GETESI32, ATM_GETESI },
+ { ATM_GETADDR32, ATM_GETADDR },
+ { ATM_RSTADDR32, ATM_RSTADDR },
+ { ATM_ADDADDR32, ATM_ADDADDR },
+ { ATM_DELADDR32, ATM_DELADDR },
+ { ATM_GETCIRANGE32, ATM_GETCIRANGE },
+ { ATM_SETCIRANGE32, ATM_SETCIRANGE },
+ { ATM_SETESI32, ATM_SETESI },
+ { ATM_SETESIF32, ATM_SETESIF },
+ { ATM_GETSTAT32, ATM_GETSTAT },
+ { ATM_GETSTATZ32, ATM_GETSTATZ },
+ { ATM_GETLOOP32, ATM_GETLOOP },
+ { ATM_SETLOOP32, ATM_SETLOOP },
+ { ATM_QUERYLOOP32, ATM_QUERYLOOP },
+};
+
+#define NR_ATM_IOCTL ARRAY_SIZE(atm_ioctl_map)
+
+static int do_atm_iobuf(struct socket *sock, unsigned int cmd,
+ unsigned long arg)
+{
+ struct atm_iobuf __user *iobuf;
+ struct compat_atm_iobuf __user *iobuf32;
+ u32 data;
+ void __user *datap;
+ int len, err;
+
+ iobuf = compat_alloc_user_space(sizeof(*iobuf));
+ iobuf32 = compat_ptr(arg);
+
+ if (get_user(len, &iobuf32->length) ||
+ get_user(data, &iobuf32->buffer))
+ return -EFAULT;
+ datap = compat_ptr(data);
+ if (put_user(len, &iobuf->length) ||
+ put_user(datap, &iobuf->buffer))
+ return -EFAULT;
+
+ err = do_vcc_ioctl(sock, cmd, (unsigned long) iobuf, 0);
+
+ if (!err) {
+ if (copy_in_user(&iobuf32->length, &iobuf->length,
+ sizeof(int)))
+ err = -EFAULT;
+ }
+
+ return err;
+}
+
+static int do_atmif_sioc(struct socket *sock, unsigned int cmd,
+ unsigned long arg)
+{
+ struct atmif_sioc __user *sioc;
+ struct compat_atmif_sioc __user *sioc32;
+ u32 data;
+ void __user *datap;
+ int err;
+
+ sioc = compat_alloc_user_space(sizeof(*sioc));
+ sioc32 = compat_ptr(arg);
+
+ if (copy_in_user(&sioc->number, &sioc32->number, 2 * sizeof(int))
+ || get_user(data, &sioc32->arg))
+ return -EFAULT;
+ datap = compat_ptr(data);
+ if (put_user(datap, &sioc->arg))
+ return -EFAULT;
+
+ err = do_vcc_ioctl(sock, cmd, (unsigned long) sioc, 0);
+
+ if (!err) {
+ if (copy_in_user(&sioc32->length, &sioc->length,
+ sizeof(int)))
+ err = -EFAULT;
+ }
+ return err;
+}
+
+static int do_atm_ioctl(struct socket *sock, unsigned int cmd32,
+ unsigned long arg)
+{
+ int i;
+ unsigned int cmd = 0;
+
+ switch (cmd32) {
+ case SONET_GETSTAT:
+ case SONET_GETSTATZ:
+ case SONET_GETDIAG:
+ case SONET_SETDIAG:
+ case SONET_CLRDIAG:
+ case SONET_SETFRAMING:
+ case SONET_GETFRAMING:
+ case SONET_GETFRSENSE:
+ return do_atmif_sioc(sock, cmd32, arg);
+ }
+
+ for (i = 0; i < NR_ATM_IOCTL; i++) {
+ if (cmd32 == atm_ioctl_map[i].cmd32) {
+ cmd = atm_ioctl_map[i].cmd;
+ break;
+ }
+ }
+ if (i == NR_ATM_IOCTL)
+ return -EINVAL;
+
+ switch (cmd) {
+ case ATM_GETNAMES:
+ return do_atm_iobuf(sock, cmd, arg);
+
+ case ATM_GETLINKRATE:
+ case ATM_GETTYPE:
+ case ATM_GETESI:
+ case ATM_GETADDR:
+ case ATM_RSTADDR:
+ case ATM_ADDADDR:
+ case ATM_DELADDR:
+ case ATM_GETCIRANGE:
+ case ATM_SETCIRANGE:
+ case ATM_SETESI:
+ case ATM_SETESIF:
+ case ATM_GETSTAT:
+ case ATM_GETSTATZ:
+ case ATM_GETLOOP:
+ case ATM_SETLOOP:
+ case ATM_QUERYLOOP:
+ return do_atmif_sioc(sock, cmd, arg);
+ }
+
+ return -EINVAL;
+}
+
+int vcc_compat_ioctl(struct socket *sock, unsigned int cmd,
+ unsigned long arg)
{
- return do_vcc_ioctl(sock, cmd, arg, 1);
+ int ret;
+
+ ret = do_vcc_ioctl(sock, cmd, arg, 1);
+ if (ret != -ENOIOCTLCMD)
+ return ret;
+
+ return do_atm_ioctl(sock, cmd, arg);
}
#endif
diff --git a/net/socket.c b/net/socket.c
index 05c4828..402abb3 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -100,14 +100,6 @@
#include <linux/if_tun.h>
#include <linux/ipv6_route.h>
#include <linux/route.h>
-#include <linux/atmdev.h>
-#include <linux/atmarp.h>
-#include <linux/atmsvc.h>
-#include <linux/atmlec.h>
-#include <linux/atmclip.h>
-#include <linux/atmmpc.h>
-#include <linux/atm_tcp.h>
-#include <linux/sonet.h>
#include <linux/sockios.h>
#include <linux/atalk.h>
@@ -2917,173 +2909,6 @@ static int old_bridge_ioctl(compat_ulong_t __user *argp)
return -EINVAL;
}
-struct atmif_sioc32 {
- compat_int_t number;
- compat_int_t length;
- compat_caddr_t arg;
-};
-
-struct atm_iobuf32 {
- compat_int_t length;
- compat_caddr_t buffer;
-};
-
-#define ATM_GETLINKRATE32 _IOW('a', ATMIOC_ITF+1, struct atmif_sioc32)
-#define ATM_GETNAMES32 _IOW('a', ATMIOC_ITF+3, struct atm_iobuf32)
-#define ATM_GETTYPE32 _IOW('a', ATMIOC_ITF+4, struct atmif_sioc32)
-#define ATM_GETESI32 _IOW('a', ATMIOC_ITF+5, struct atmif_sioc32)
-#define ATM_GETADDR32 _IOW('a', ATMIOC_ITF+6, struct atmif_sioc32)
-#define ATM_RSTADDR32 _IOW('a', ATMIOC_ITF+7, struct atmif_sioc32)
-#define ATM_ADDADDR32 _IOW('a', ATMIOC_ITF+8, struct atmif_sioc32)
-#define ATM_DELADDR32 _IOW('a', ATMIOC_ITF+9, struct atmif_sioc32)
-#define ATM_GETCIRANGE32 _IOW('a', ATMIOC_ITF+10, struct atmif_sioc32)
-#define ATM_SETCIRANGE32 _IOW('a', ATMIOC_ITF+11, struct atmif_sioc32)
-#define ATM_SETESI32 _IOW('a', ATMIOC_ITF+12, struct atmif_sioc32)
-#define ATM_SETESIF32 _IOW('a', ATMIOC_ITF+13, struct atmif_sioc32)
-#define ATM_GETSTAT32 _IOW('a', ATMIOC_SARCOM+0, struct atmif_sioc32)
-#define ATM_GETSTATZ32 _IOW('a', ATMIOC_SARCOM+1, struct atmif_sioc32)
-#define ATM_GETLOOP32 _IOW('a', ATMIOC_SARCOM+2, struct atmif_sioc32)
-#define ATM_SETLOOP32 _IOW('a', ATMIOC_SARCOM+3, struct atmif_sioc32)
-#define ATM_QUERYLOOP32 _IOW('a', ATMIOC_SARCOM+4, struct atmif_sioc32)
-
-static struct {
- unsigned int cmd32;
- unsigned int cmd;
-} atm_ioctl_map[] = {
- { ATM_GETLINKRATE32, ATM_GETLINKRATE },
- { ATM_GETNAMES32, ATM_GETNAMES },
- { ATM_GETTYPE32, ATM_GETTYPE },
- { ATM_GETESI32, ATM_GETESI },
- { ATM_GETADDR32, ATM_GETADDR },
- { ATM_RSTADDR32, ATM_RSTADDR },
- { ATM_ADDADDR32, ATM_ADDADDR },
- { ATM_DELADDR32, ATM_DELADDR },
- { ATM_GETCIRANGE32, ATM_GETCIRANGE },
- { ATM_SETCIRANGE32, ATM_SETCIRANGE },
- { ATM_SETESI32, ATM_SETESI },
- { ATM_SETESIF32, ATM_SETESIF },
- { ATM_GETSTAT32, ATM_GETSTAT },
- { ATM_GETSTATZ32, ATM_GETSTATZ },
- { ATM_GETLOOP32, ATM_GETLOOP },
- { ATM_SETLOOP32, ATM_SETLOOP },
- { ATM_QUERYLOOP32, ATM_QUERYLOOP }
-};
-
-#define NR_ATM_IOCTL ARRAY_SIZE(atm_ioctl_map)
-
-static int do_atm_iobuf(struct net *net, struct socket *sock,
- unsigned int cmd, unsigned long arg)
-{
- struct atm_iobuf __user *iobuf;
- struct atm_iobuf32 __user *iobuf32;
- u32 data;
- void __user *datap;
- int len, err;
-
- iobuf = compat_alloc_user_space(sizeof(*iobuf));
- iobuf32 = compat_ptr(arg);
-
- if (get_user(len, &iobuf32->length) ||
- get_user(data, &iobuf32->buffer))
- return -EFAULT;
- datap = compat_ptr(data);
- if (put_user(len, &iobuf->length) ||
- put_user(datap, &iobuf->buffer))
- return -EFAULT;
-
- err = sock_do_ioctl(net, sock, cmd, (unsigned long)iobuf);
-
- if (!err) {
- if (copy_in_user(&iobuf32->length, &iobuf->length,
- sizeof(int)))
- err = -EFAULT;
- }
-
- return err;
-}
-
-static int do_atmif_sioc(struct net *net, struct socket *sock,
- unsigned int cmd, unsigned long arg)
-{
- struct atmif_sioc __user *sioc;
- struct atmif_sioc32 __user *sioc32;
- u32 data;
- void __user *datap;
- int err;
-
- sioc = compat_alloc_user_space(sizeof(*sioc));
- sioc32 = compat_ptr(arg);
-
- if (copy_in_user(&sioc->number, &sioc32->number, 2 * sizeof(int)) ||
- get_user(data, &sioc32->arg))
- return -EFAULT;
- datap = compat_ptr(data);
- if (put_user(datap, &sioc->arg))
- return -EFAULT;
-
- err = sock_do_ioctl(net, sock, cmd, (unsigned long) sioc);
-
- if (!err) {
- if (copy_in_user(&sioc32->length, &sioc->length,
- sizeof(int)))
- err = -EFAULT;
- }
- return err;
-}
-
-static int do_atm_ioctl(struct net *net, struct socket *sock,
- unsigned int cmd32, unsigned long arg)
-{
- int i;
- unsigned int cmd = 0;
-
- switch (cmd32) {
- case SONET_GETSTAT:
- case SONET_GETSTATZ:
- case SONET_GETDIAG:
- case SONET_SETDIAG:
- case SONET_CLRDIAG:
- case SONET_SETFRAMING:
- case SONET_GETFRAMING:
- case SONET_GETFRSENSE:
- return do_atmif_sioc(net, sock, cmd32, arg);
- }
-
- for (i = 0; i < NR_ATM_IOCTL; i++) {
- if (cmd32 == atm_ioctl_map[i].cmd32) {
- cmd = atm_ioctl_map[i].cmd;
- break;
- }
- }
- if (i == NR_ATM_IOCTL)
- return -EINVAL;
-
- switch (cmd) {
- case ATM_GETNAMES:
- return do_atm_iobuf(net, sock, cmd, arg);
-
- case ATM_GETLINKRATE:
- case ATM_GETTYPE:
- case ATM_GETESI:
- case ATM_GETADDR:
- case ATM_RSTADDR:
- case ATM_ADDADDR:
- case ATM_DELADDR:
- case ATM_GETCIRANGE:
- case ATM_SETCIRANGE:
- case ATM_SETESI:
- case ATM_SETESIF:
- case ATM_GETSTAT:
- case ATM_GETSTATZ:
- case ATM_GETLOOP:
- case ATM_SETLOOP:
- case ATM_QUERYLOOP:
- return do_atmif_sioc(net, sock, cmd, arg);
- }
-
- return -EINVAL;
-}
-
static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
unsigned int cmd, unsigned long arg)
{
@@ -3173,49 +2998,6 @@ static int compat_sock_ioctl_trans(struct file *file, struct socket *sock,
case SIOCSMIIREG:
return dev_ifsioc(net, sock, cmd, argp);
- case ATM_GETLINKRATE32:
- case ATM_GETNAMES32:
- case ATM_GETTYPE32:
- case ATM_GETESI32:
- case ATM_GETADDR32:
- case ATM_RSTADDR32:
- case ATM_ADDADDR32:
- case ATM_DELADDR32:
- case ATM_GETCIRANGE32:
- case ATM_SETCIRANGE32:
- case ATM_SETESI32:
- case ATM_SETESIF32:
- case ATM_GETSTAT32:
- case ATM_GETSTATZ32:
- case ATM_GETLOOP32:
- case ATM_SETLOOP32:
- case ATM_QUERYLOOP32:
- case SONET_GETSTAT:
- case SONET_GETSTATZ:
- case SONET_GETDIAG:
- case SONET_SETDIAG:
- case SONET_CLRDIAG:
- case SONET_SETFRAMING:
- case SONET_GETFRAMING:
- case SONET_GETFRSENSE:
- return do_atm_ioctl(net, sock, cmd, arg);
-
- case ATMSIGD_CTRL:
- case ATMARPD_CTRL:
- case ATMLEC_CTRL:
- case ATMLEC_MCAST:
- case ATMLEC_DATA:
- case ATM_SETSC:
- case SIOCSIFATMTCP:
- case SIOCMKCLIP:
- case ATMARP_MKIP:
- case ATMARP_SETENTRY:
- case ATMARP_ENCAP:
- case ATMTCP_CREATE:
- case ATMTCP_REMOVE:
- case ATMMPC_CTRL:
- case ATMMPC_DATA:
-
case SIOCSARP:
case SIOCGARP:
case SIOCDARP:
--
1.6.3.3
^ permalink raw reply related
* Re: [PATCH 04/10] AOE: use rcu to find network device
From: Ed Cashin @ 2009-11-11 14:22 UTC (permalink / raw)
To: shemminger, ecashin, davem, harvey.harrison, bzolnier, netdev
In-Reply-To: <20091110150617.0e6920f0@nehalam>
On Tue Nov 10 18:06:41 EST 2009, shemminger@vyatta.com wrote:
...
> Hmm, looks like AOE actually is not ref counting the network device.
> So my patch is incorrect.
>
> As it stands (before my patch), it is UNSAFE. It can decide to queue
> packets to a device that is removed out from underneath it causing
> reference to freed memory.
Yes, that's right. I will look at the patch you sent in the follow
up. Thanks.
--
Ed
^ permalink raw reply
* [PATCH] ARM: fix bug of checking on signed return value using unsigned statement in w90p910 platform
From: Wan ZongShun @ 2009-11-11 14:35 UTC (permalink / raw)
To: David S. Miller, roel.kluin; +Cc: linux-arm-kernel, linux-netdev
Dear sir,
To fix the bug of checking on signed return value using unsigned statement.
Thanks Roel Kluin for digging out it.
Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
Signed-off-by: Wan ZongShun <mcuos.com@gmail.com>
---
drivers/net/arm/w90p910_ether.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/arm/w90p910_ether.c b/drivers/net/arm/w90p910_ether.c
index 25e2627..b7f3866 100644
--- a/drivers/net/arm/w90p910_ether.c
+++ b/drivers/net/arm/w90p910_ether.c
@@ -160,8 +160,8 @@ struct w90p910_ether {
struct mii_if_info mii;
struct timer_list check_timer;
void __iomem *reg;
- unsigned int rxirq;
- unsigned int txirq;
+ int rxirq;
+ int txirq;
unsigned int cur_tx;
unsigned int cur_rx;
unsigned int finish_tx;
--
1.5.6.3
^ permalink raw reply related
* Re: linux-next: manual merge of the net/wireless trees with the wireless-current tree
From: John W. Linville @ 2009-11-11 14:54 UTC (permalink / raw)
To: Stephen Rothwell
Cc: David Miller, netdev, linux-next, linux-kernel, Wey-Yi Guy
In-Reply-To: <20091111130119.ace8da65.sfr@canb.auug.org.au>
On Wed, Nov 11, 2009 at 01:01:19PM +1100, Stephen Rothwell wrote:
> Hi all,
>
> Today's linux-next merge of the net tree got conflicts in
> drivers/net/wireless/iwlwifi/iwl-1000.c,
> drivers/net/wireless/iwlwifi/iwl-6000.c and
> drivers/net/wireless/iwlwifi/iwl-core.h between commits in the
> wireless-current tree and commits in the net (wireless) tree.
>
> I used the versions from the net tree except where obvious additions
> had been made in the wireless-current tree. The fixes may not be
> correct - someone should merge the wireless-current tree into the
> net tree.
Yeah, these conflicts should all be resolved by taking the bigger hunk.
The smaller hunk is duplicative because a patch that has already
been sent to net-next-2.6 is going to be sent for net-2.6 as well
(to support a regression fix).
I'll probably send the wireless-2.6 pull request today. Perhaps after
Dave pulls that (and Linus pulls from him), Dave can pull net-2.6
into net-next-2.6 to resolve the issue.
John
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
^ permalink raw reply
* Re: [PATCH 0/6] gianfar: Some fixes
From: Kumar Gala @ 2009-11-11 15:16 UTC (permalink / raw)
To: avorontsov
Cc: Jon Loeliger, Kumar Gopalpet-B05799, netdev, linuxppc-dev,
Andy Fleming, Stephen Hemminger, David Miller, Lennert Buytenhek
In-Reply-To: <20091111001036.GA28576@oksana.dev.rtsoft.ru>
On Nov 10, 2009, at 6:10 PM, Anton Vorontsov wrote:
> Hi all,
>
> Here are some fixes for the gianfar driver, patches on the way.
>
> Thanks,
Acked-by: Kumar Gala <galak@kernel.crashing.org>
- k
^ permalink raw reply
* Re: [PATCH 2/4] macvlan: allow in-kernel modules to create and manage macvlan devices
From: Patrick McHardy @ 2009-11-11 15:29 UTC (permalink / raw)
To: Patrick Mullaney
Cc: alacrityvm-devel, linux-kernel, arnd, bridge, evb, netdev
In-Reply-To: <20091110222757.24100.16046.stgit@mimic.site>
Patrick Mullaney wrote:
> The macvlan driver didn't allow for creation/deletion of devices
> by other in-kernel modules. This patch provides common routines
> for both in-kernel and netlink based management. This patch
> also enables macvlan device support for gro for lower level
> devices that support gro.
> -static void macvlan_transfer_operstate(struct net_device *dev)
> +void macvlan_transfer_operstate(struct net_device *dev)
> {
> struct macvlan_dev *vlan = netdev_priv(dev);
> const struct net_device *lowerdev = vlan->lowerdev;
> @@ -458,6 +458,7 @@ static void macvlan_transfer_operstate(struct net_device *dev)
> netif_carrier_off(dev);
> }
> }
> +EXPORT_SYMBOL_GPL(macvlan_transfer_operstate);
I think this function could be moved to net/core/dev.c or
net/core/link_watch.c. The VLAN code has an identical copy.
> -int macvlan_newlink(struct net_device *dev,
> - struct nlattr *tb[], struct nlattr *data[])
> +int macvlan_link_lowerdev(struct net_device *dev,
> + struct net_device *lowerdev)
Please indent this more cleanly.
> {
> struct macvlan_dev *vlan = netdev_priv(dev);
> struct macvlan_port *port;
> + int err = 0;
> +
> + if (lowerdev->macvlan_port == NULL) {
> + err = macvlan_port_create(lowerdev);
> + if (err < 0)
> + return err;
> + }
> + port = lowerdev->macvlan_port;
> +
> + vlan->lowerdev = lowerdev;
> + vlan->dev = dev;
> + vlan->port = port;
> + vlan->receive = netif_rx;
> +
> + macvlan_init(dev);
> +
> + list_add_tail(&vlan->list, &port->vlans);
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(macvlan_link_lowerdev);
> @@ -502,23 +539,14 @@ int macvlan_newlink(struct net_device *dev,
> if (!tb[IFLA_ADDRESS])
> random_ether_addr(dev->dev_addr);
>
> - if (lowerdev->macvlan_port == NULL) {
> - err = macvlan_port_create(lowerdev);
> - if (err < 0)
> - return err;
> - }
> - port = lowerdev->macvlan_port;
> -
> - vlan->lowerdev = lowerdev;
> - vlan->dev = dev;
> - vlan->port = port;
> - vlan->receive = netif_rx;
> + err = macvlan_link_lowerdev(dev, lowerdev);
> + if (err < 0)
> + return err;
>
> err = register_netdevice(dev);
> if (err < 0)
> return err;
You've already added the device to the port->vlans list, so you
need to remove it again when register_netdevice() fails.
> - list_add_tail(&vlan->list, &port->vlans);
> macvlan_transfer_operstate(dev);
> return 0;
> }
> @@ -526,14 +554,8 @@ EXPORT_SYMBOL_GPL(macvlan_newlink);
^ permalink raw reply
* Re: [PATCH 4/4] venet-macvlan: add new driver to connect a venet to a macvlan netdevice
From: Patrick McHardy @ 2009-11-11 15:36 UTC (permalink / raw)
To: Patrick Mullaney
Cc: alacrityvm-devel, linux-kernel, arnd, bridge, evb, netdev
In-Reply-To: <20091110222812.24100.42756.stgit@mimic.site>
Patrick Mullaney wrote:
> This driver implements a macvlan device as a venet device that can
> be connected to vbus. Since it is a macvlan device, it provides
> a more direct path to the underlying adapter by avoiding the
> bridge.
> --- /dev/null
> +++ b/kernel/vbus/devices/venet/macvlan.c
> ...
> +struct venetmacv {
> + struct macvlan_dev mdev;
> + unsigned char ll_ifname[IFNAMSIZ];
> + struct venetdev dev;
> + const struct net_device_ops *macvlan_netdev_ops;
> +};
macvlan might destroy the device below you when the underlying
device is unregistered. You need to handle this by releasing
the venetmacv device. Check out the NETDEV_UNREGISTER case in
macvlan_device_event().
^ permalink raw reply
* Re: [Bugme-new] [Bug 14546] New: Off-by-two stack buffer overflow in function rpc_uaddr2sockaddr() of net/sunrpc/addr.c
From: Chuck Lever @ 2009-11-11 15:53 UTC (permalink / raw)
To: Fabio Olive Leite
Cc: argp-YZAGAMbGdGKGw+nKnLezzg,
bugzilla-daemon-590EEB7GvNiWaY/ihj7yzEB+6BGkLq7r,
bugme-daemon-590EEB7GvNiWaY/ihj7yzEB+6BGkLq7r,
Linux Network Developers, J. Bruce Fields, Trond Myklebust,
Neil Brown, Andrew Morton, Linux NFS Mailing list
In-Reply-To: <967DC2CE-588D-4207-BF2D-59727454DC2E-QHcLZuEGTsvQT0dZR+AlfA@public.gmane.org>
On 2009-11-11 Fabio Olive Leite wrote:
> On 2009-11-11 Patroklos Argyroudis wrote:
>> There is no need to increase the size of the buffer since the new
>> check (if (uaddr_len > sizeof(buf) - 2)) will terminate the function
>> in case the valid universal address is RPCBIND_MAXUADDRLEN bytes.
> On a second note, why is '\n' needed there? You should only need
> '\0', as a '\n'
> at the end is not required by any of the string functions used to
> convert the
> address. I believe you could go with buf[RPCBIND_MAXUADDRLEN+1] for
> the extra NUL only.
AFAICT, strict_strtoul() requires the '\n\0' termination.
--
Chuck Lever
chuck[dot]lever[at]oracle[dot]com
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] ifb: add multi-queue support
From: Patrick McHardy @ 2009-11-11 15:59 UTC (permalink / raw)
To: xiaosuo
Cc: David S. Miller, Stephen Hemminger, Eric Dumazet, Tom Herbert,
netdev
In-Reply-To: <4AFA8911.7050204@gmail.com>
Changli Gao wrote:
> diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
> index 69c2566..ac04e85 100644
> --- a/drivers/net/ifb.c
> +++ b/drivers/net/ifb.c
> ...
> +/* Number of ifb devices to be set up by this module. */
> static int numifbs = 2;
> +module_param(numifbs, int, 0444);
> +MODULE_PARM_DESC(numifbs, "Number of ifb devices");
>
> -static void ri_tasklet(unsigned long dev);
> -static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev);
> -static int ifb_open(struct net_device *dev);
> -static int ifb_close(struct net_device *dev);
> +/* Number of TX queues per ifb */
> +static int numtxqs = 1;
> +module_param(numtxqs, int, 0444);
> +MODULE_PARM_DESC(numtxqs, "Number of TX queues per ifb");
unsigned?
> + while ((skb = skb_dequeue(&pq->tq)) != NULL) {
> + u32 from = G_TC_FROM(skb->tc_verd);
> +
> + skb->tc_verd = 0;
> + skb->tc_verd = SET_TC_NCLS(skb->tc_verd);
> + txq->tx_packets++;
> + txq->tx_bytes +=skb->len;
> +
> + rcu_read_lock();
> + skb->dev = dev_get_by_index_rcu(&init_net, skb->iif);
> + if (!skb->dev) {
> + rcu_read_unlock();
> + dev_kfree_skb(skb);
> + txq->tx_dropped++;
> + break;
> + }
> + rcu_read_unlock();
> + skb->iif = dev->ifindex;
What protects the device from disappearing here and below during
dev_queue_xmit() and netif_rx_ni()?
> +
> + if (from & AT_EGRESS) {
> + dev_queue_xmit(skb);
> + } else if (from & AT_INGRESS) {
> + skb_pull(skb, skb->dev->hard_header_len);
> + netif_rx_ni(skb);
> + } else
> + BUG();
> }
> +static u32 simple_tx_hashrnd;
> +
> +static u16 ifb_select_queue(struct net_device *dev, struct sk_buff *skb)
> +{
> + u32 addr1, addr2;
> + u32 hash, ihl;
> + union {
> + u16 in16[2];
> + u32 in32;
> + } ports;
> + u8 ip_proto;
> +
> + if ((hash = skb_rx_queue_recorded(skb))) {
> + while (hash >= dev->real_num_tx_queues)
> + hash -= dev->real_num_tx_queues;
> + return hash;
> + }
> +
> + switch (skb->protocol) {
> + case __constant_htons(ETH_P_IP):
> + if (!(ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)))
> + ip_proto = ip_hdr(skb)->protocol;
> + else
> + ip_proto = 0;
So fragments will get reordered?
> + addr1 = ip_hdr(skb)->saddr;
> + addr2 = ip_hdr(skb)->daddr;
> + ihl = ip_hdr(skb)->ihl << 2;
ip_hdrlen()?
> + break;
> + case __constant_htons(ETH_P_IPV6):
> + ip_proto = ipv6_hdr(skb)->nexthdr;
> + addr1 = ipv6_hdr(skb)->saddr.s6_addr32[3];
> + addr2 = ipv6_hdr(skb)->daddr.s6_addr32[3];
> + ihl = 10;
Where does 10 come from?
> + break;
> + default:
> + return 0;
Perhaps hash on skb->protocol here.
> + }
> + if (addr1 > addr2)
> + swap(addr1, addr2);
> +
> + switch (ip_proto) {
> + case IPPROTO_TCP:
> + case IPPROTO_UDP:
> + case IPPROTO_DCCP:
> + case IPPROTO_ESP:
> + case IPPROTO_AH:
> + case IPPROTO_SCTP:
> + case IPPROTO_UDPLITE:
> + ports.in32 = *((u32 *) (skb_network_header(skb) + ihl));
> + if (ports.in16[0] > ports.in16[1])
> + swap(ports.in16[0], ports.in16[1]);
> + break;
> +
> + default:
> + ports.in32 = 0;
> + break;
> + }
> +
> + hash = jhash_3words(addr1, addr2, ports.in32,
> + simple_tx_hashrnd ^ ip_proto);
> +
> + return (u16) (((u64) hash * dev->real_num_tx_queues) >> 32);
> +}
> +
> +static int ifb_init(struct net_device *dev)
> +{
> + struct ifb_private *dp = netdev_priv(dev);
> + struct ifb_private_q *pq = dp->pq;
> + int i;
> +
> + pq = kmalloc(sizeof(*pq) * dev->real_num_tx_queues, GFP_KERNEL);
kcalloc()?
> + if (pq == NULL)
> + return -ENOMEM;
> + dp->pq = pq;
> +
> + for (i = 0; i < dev->real_num_tx_queues; i++) {
> + pq[i].dev = dev;
> + skb_queue_head_init(&pq[i].rq);
> + skb_queue_head_init(&pq[i].tq);
> + init_waitqueue_head(&pq[i].wq);
> + pq[i].rx_packets = 0;
> + pq[i].rx_bytes = 0;
> + pq[i].rx_dropped = 0;
> + }
> +
> + return 0;
> +}
> +static int ifb_get_tx_queues(struct net *net, struct nlattr *tb[],
> + unsigned int *num_tx_queues,
> + unsigned int *real_num_tx_queues)
> +{
> + if (tb[IFLA_NTXQ]) {
> + *num_tx_queues = nla_get_u16(tb[IFLA_NTXQ]);
We currently use unsigned ints for the queue number, so please
use an u32 for the attribute as well.
> + *real_num_tx_queues = *num_tx_queues;
> + } else {
> + *num_tx_queues = numtxqs;
> + *real_num_tx_queues = numtxqs;
> + }
> +
> + return 0;
> +}
> +
^ permalink raw reply
* Re: [PATCH 1/2] rps: core implementation
From: Tom Herbert @ 2009-11-11 16:28 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, netdev
In-Reply-To: <4AFA73DA.30308@gmail.com>
> I must say this is really exciting :)
>
Thanks!
>> +/* Maximum size of RPS map (for allocation) */
>> +#define RPS_MAP_SIZE (sizeof(struct rps_map) + \
>> + (num_possible_cpus() * sizeof(u16)))
>> +
>
> Problem of possible cpus is the number can be very large on some arches,
> but yet few cpus online....
>
> In this kind of situation, get_rps_cpu() will return -1 most of the time,
> defeating goal of RPS ?
>
I suppose it would make sense to either use num_online_cpus or simply
put a reasonable limit on it (like HW RSS hash tables are 128 entries
I believe).
>> + hash = jhash_3words(addr1, addr2, ports, simple_hashrnd);
>
> I wonder if you tried to exchange addr1/addr2 port1/port2 so that conntracking/routing
> is also speedup ...
>
> ie make sure hash will be the same regardless of the direction of packet.
>
> union {
> u32 port;
> u16 ports[2];
> } p;
>
> if (addr1 < addr2)
> swap(addr1, addr2);
>
> if (p.ports[0] < p.ports[1]);
> swap(p.ports[0], p.ports[1]);
>
I have not considered that. How much of a win would this be?
> hash = jhash_3words(addr1, addr2, ports, simple_hashrnd);
>
Another possibility we considered was to call inet_hashfn and
inet6_ehashfn directly to get the hash, and store that value in
skb->rxhash and use it later on connection lookup in tcp_v4_rcv to
eliminate to another jhash. This has some benefit, but it doesn't
help if we get different type of hash from HW (using that is a much
bigger win), and also we needed to pull in more IP header files into
dev.c.
>
> I think I'll try to extend your patches with TX completion recycling too.
>
> Ie record in skb the cpu number of original sender, and queue skb to
> remote queue for destruction (sock_wfree() call and expensive scheduler calls...)
>
We also have implemented a form of that if you are interested. In
dev_kfree_skb put the skb on the completion list the origin CPU of the
skb (where it was allocated) and use the remote softirq to schedule
processing.
Tom
^ permalink raw reply
* Re: [PATCH 1/2] rps: core implementation
From: Randy Dunlap @ 2009-11-11 16:49 UTC (permalink / raw)
To: Tom Herbert; +Cc: David Miller, netdev
In-Reply-To: <65634d660911102253o2b4f7a19kfed5849e5c88bfe1@mail.gmail.com>
On Tue, 10 Nov 2009 22:53:17 -0800 Tom Herbert wrote:
> Third version of RPS.
>
> Signed-off-by: Tom Herbert <therbert@google.com>
> ---
> include/linux/interrupt.h | 1 +
> include/linux/netdevice.h | 18 ++++
> include/linux/skbuff.h | 2 +
> net/core/dev.c | 227 ++++++++++++++++++++++++++++++++++++++-------
> net/core/net-sysfs.c | 135 +++++++++++++++++++++++++++
> 5 files changed, 348 insertions(+), 35 deletions(-)
>
> diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
> index 0c68fbd..95feac7 100644
> --- a/include/linux/skbuff.h
> +++ b/include/linux/skbuff.h
> @@ -396,6 +396,8 @@ struct sk_buff {
>
> __u16 vlan_tci;
>
> + __u32 rxhash;
> +
@rxhash needs to be added to the kernel-doc for struct sk_buff.
> sk_buff_data_t transport_header;
> sk_buff_data_t network_header;
> sk_buff_data_t mac_header;
> diff --git a/net/core/dev.c b/net/core/dev.c
> index 28b0b9e..735e7e3 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -1976,6 +1976,162 @@ int weight_p __read_mostly = 64; /*
> old backlog weight */
>
> DEFINE_PER_CPU(struct netif_rx_stats, netdev_rx_stat) = { 0, };
>
> +static u32 simple_hashrnd;
> +
> +/**
> + * get_rps_cpu is called from netif_receive_skb and returns the target
> + * CPU from the RPS map of the receiving NAPI instance for a given skb.
> + */
"/**" in kernel source code means "begin kernel-doc notation", but that
is not kernel-doc notation, so please make it be kernel-doc, or don't
use "/**" to begin comment blocks.
(in several functions here...)
> +static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb)
> +{
> + u32 addr1, addr2, ports;
> + struct ipv6hdr *ip6;
> + struct iphdr *ip;
> + u32 hash, ihl;
> + u8 ip_proto;
> + int cpu;
> + struct rps_map *map = NULL;
> +
> + if (dev->rps_num_maps) {
> + /*
> + * Locate the map corresponding to the NAPI queue that
> + * the packet was received on.
> + */
> + int index = skb_get_rx_queue(skb);
> + if (index < 0 || index >= dev->rps_num_maps)
> + index = 0;
> +
> + map = (struct rps_map *)
> + (dev->rps_maps + (RPS_MAP_SIZE * index));
> + if (!map->len)
> + map = NULL;
> + }
> +
> + if (!map)
> + return -1;
> +
> + hash = skb->rxhash;
> + if (hash)
> + goto got_hash; /* Skip hash computation on packet header */
> +
> + switch (skb->protocol) {
> + case __constant_htons(ETH_P_IP):
> + if (!pskb_may_pull(skb, sizeof(*ip)))
> + return -1;
> +
> + ip = (struct iphdr *) skb->data;
> + ip_proto = ip->protocol;
> + addr1 = ip->saddr;
> + addr2 = ip->daddr;
> + ihl = ip->ihl;
> + break;
> + case __constant_htons(ETH_P_IPV6):
> + if (!pskb_may_pull(skb, sizeof(*ip6)))
> + return -1;
> +
> + ip6 = (struct ipv6hdr *) skb->data;
> + ip_proto = ip6->nexthdr;
> + addr1 = ip6->saddr.s6_addr32[3];
> + addr2 = ip6->daddr.s6_addr32[3];
> + ihl = (40 >> 2);
> + break;
> + default:
> + return -1;
> + }
> + ports = 0;
> + switch (ip_proto) {
> + case IPPROTO_TCP:
> + case IPPROTO_UDP:
> + case IPPROTO_DCCP:
> + case IPPROTO_ESP:
> + case IPPROTO_AH:
> + case IPPROTO_SCTP:
> + case IPPROTO_UDPLITE:
> + if (pskb_may_pull(skb, (ihl * 4) + 4))
> + ports = *((u32 *) (skb->data + (ihl * 4)));
> + break;
> +
> + default:
> + break;
> + }
> +
> + hash = jhash_3words(addr1, addr2, ports, simple_hashrnd);
> +
> +got_hash:
> + cpu = map->map[((u64) hash * map->len) >> 32];
> +
> + return cpu_online(cpu) ? cpu : -1;
> +}
> +/**
> + * net_rps_action is called from NET_RPS_SOFTIRQ to do IPIs to schedule RX
> + * softirq on remote CPUs. Called in a separate softirq to allow for
> + * coalescing.
> + */
> +static void net_rps_action(struct softirq_action *h)
> +{
> + int cpu;
> +
> + local_irq_disable();
> +
> + for_each_cpu_mask_nr(cpu, __get_cpu_var(rps_remote_softirq_cpus)) {
> + struct softnet_data *queue = &per_cpu(softnet_data, cpu);
> + __smp_call_function_single(cpu, &queue->csd, 0);
> + }
> + cpus_clear(__get_cpu_var(rps_remote_softirq_cpus));
> +
> + local_irq_enable();
> +}
> +
> +/**
> + * enqueue_to_backlog is called to queue an skb to a per CPU backlog
> + * queue (may be a remote CPU queue).
> + */
> +static int enqueue_to_backlog(struct sk_buff *skb, int cpu)
> +{
> diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
> index 753c420..ca250f6 100644
> --- a/net/core/net-sysfs.c
> +++ b/net/core/net-sysfs.c
> @@ -18,6 +18,9 @@
> #include <linux/wireless.h>
> #include <net/wext.h>
>
> +#include <linux/string.h>
> +#include <linux/ctype.h>
> +
> #include "net-sysfs.h"
>
> #ifdef CONFIG_SYSFS
> @@ -249,6 +252,137 @@ static ssize_t store_tx_queue_len(struct device *dev,
> return netdev_store(dev, attr, buf, len, change_tx_queue_len);
> }
>
> +static char *
> +get_token(const char **cp, size_t *len)
> +{
nit: not kernel style.
---
~Randy
^ permalink raw reply
* Re: [PATCH resent] Documentation: rw_lock lessons learned
From: William Allen Simpson @ 2009-11-11 17:08 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Paul E. McKenney, Linus Torvalds, Linux Kernel Developers,
Linux Kernel Network Developers, Eric Dumazet
In-Reply-To: <20091110180646.2e5859a8@nehalam>
Stephen Hemminger wrote:
> I would rather see the text in Documentation/spinlocks give an explaination
> as to why reader/writer locks are normally not desirable.
>
> The whole document needs work to make it a developer document, rather than
> a historical mail thread.. A good document says what should be done today,
> and does not have old junk or ask the reader to overly new context
> on old information.
>
You wish me to merge our patches?
Or this is a second patch in a proposed series?
^ permalink raw reply
* pull request: wireless-2.6 2009-11-11
From: John W. Linville @ 2009-11-11 17:22 UTC (permalink / raw)
To: davem; +Cc: linux-wireless, netdev, linux-kernel
Dave,
Here is another batch of small fixes intended for 2.6.32. Along with a
number of simple fixes, there is also a MAINTAINERS update, some LED
handling quirks for ath5k, a libertas beautification that is a prereq
for a libertas fix, and an iwlwifi fix that was already sent for
net-next-2.6 but which is needed to support an iwlwifi regression fix.
My personal favorite is the ath5k mcast filtering fix. The problem
only revealed itself when using IP autoconf w/ multicast DNS... :-)
Please let me know if there are problems!
Thanks,
John
P.S. Due to the aformentioned iwlwifi fix, this will cause -next
conflicts for sfr. You may want to pull net-2.6 into net-next-2.6 after
pulling this. The iwlwifi conflicts can be resolved by taking the bigger
hunks...
---
Individual patches are available here:
http://www.kernel.org/pub/linux/kernel/people/linville/wireless-2.6/
---
The following changes since commit 2606289779cb297320a185db5997729d29b6700b:
Sebastian Siewior (1):
net/fsl_pq_mdio: add module license GPL
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6.git master
Bing Zhao (2):
Libertas: coding style cleanup in ethtool.c
Libertas: fix issues while configuring host sleep using ethtool wol
Bob Copeland (3):
ath5k: don't reset mcast filter when configuring the mode
ath5k: add LED support for HP Compaq CQ60
ath5k: add LED definition for BenQ Joybook R55v
Felix Fietkau (1):
b43: work around a locking issue in ->set_tim()
Ivo van Doorn (1):
rt2x00: update MAINTAINERS
Larry Finger (1):
rtl8187: Fix sparse warnings
Martin Fuzzey (1):
ssb-pcmcia: Fix 32bit register access in early bus scanning
Wey-Yi Guy (2):
iwlwifi: Use RTS/CTS as the preferred protection mechanism for 6000 series
iwlwifi: Fix issue on file transfer stalled in HT mode
MAINTAINERS | 1 +
drivers/net/wireless/ath/ath5k/base.c | 1 -
drivers/net/wireless/ath/ath5k/led.c | 4 ++++
drivers/net/wireless/b43/main.c | 3 +--
drivers/net/wireless/iwlwifi/iwl-1000.c | 1 +
drivers/net/wireless/iwlwifi/iwl-6000.c | 5 +++++
drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 9 +++++++++
drivers/net/wireless/iwlwifi/iwl-agn.c | 10 +++++++---
drivers/net/wireless/iwlwifi/iwl-core.h | 2 ++
drivers/net/wireless/libertas/ethtool.c | 17 ++++++++++-------
drivers/net/wireless/rtl818x/rtl8187_rfkill.c | 1 +
drivers/ssb/scan.c | 6 +++++-
12 files changed, 46 insertions(+), 14 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index c856aee..b37e0cd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4280,6 +4280,7 @@ F: drivers/video/aty/aty128fb.c
RALINK RT2X00 WIRELESS LAN DRIVER
P: rt2x00 project
+M: Ivo van Doorn <IvDoorn@gmail.com>
L: linux-wireless@vger.kernel.org
L: users@rt2x00.serialmonkey.com (moderated for non-subscribers)
W: http://rt2x00.serialmonkey.com/
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 9c6ab53..95a8e23 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -1125,7 +1125,6 @@ ath5k_mode_setup(struct ath5k_softc *sc)
/* configure operational mode */
ath5k_hw_set_opmode(ah);
- ath5k_hw_set_mcast_filter(ah, 0, 0);
ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt);
}
diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c
index b767c3b..b548c8e 100644
--- a/drivers/net/wireless/ath/ath5k/led.c
+++ b/drivers/net/wireless/ath/ath5k/led.c
@@ -63,12 +63,16 @@ static const struct pci_device_id ath5k_led_devices[] = {
{ ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0422), ATH_LED(1, 1) },
/* E-machines E510 (tuliom@gmail.com) */
{ ATH_SDEVICE(PCI_VENDOR_ID_AMBIT, 0x0428), ATH_LED(3, 0) },
+ /* BenQ Joybook R55v (nowymarluk@wp.pl) */
+ { ATH_SDEVICE(PCI_VENDOR_ID_QMI, 0x0100), ATH_LED(1, 0) },
/* Acer Extensa 5620z (nekoreeve@gmail.com) */
{ ATH_SDEVICE(PCI_VENDOR_ID_QMI, 0x0105), ATH_LED(3, 0) },
/* Fukato Datacask Jupiter 1014a (mrb74@gmx.at) */
{ ATH_SDEVICE(PCI_VENDOR_ID_AZWAVE, 0x1026), ATH_LED(3, 0) },
/* IBM ThinkPad AR5BXB6 (legovini@spiro.fisica.unipd.it) */
{ ATH_SDEVICE(PCI_VENDOR_ID_IBM, 0x058a), ATH_LED(1, 0) },
+ /* HP Compaq CQ60-206US (ddreggors@jumptv.com) */
+ { ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137a), ATH_LED(3, 1) },
/* HP Compaq C700 (nitrousnrg@gmail.com) */
{ ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137b), ATH_LED(3, 1) },
/* IBM-specific AR5212 (all others) */
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 86f3582..098dda1 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -4521,9 +4521,8 @@ static int b43_op_beacon_set_tim(struct ieee80211_hw *hw,
{
struct b43_wl *wl = hw_to_b43_wl(hw);
- mutex_lock(&wl->mutex);
+ /* FIXME: add locking */
b43_update_templates(wl);
- mutex_unlock(&wl->mutex);
return 0;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 2716b91..950267a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -161,5 +161,6 @@ struct iwl_cfg iwl1000_bgn_cfg = {
.max_ll_items = OTP_MAX_LL_ITEMS_1000,
.shadow_ram_support = false,
.ht_greenfield_support = true,
+ .use_rts_for_ht = true, /* use rts/cts protection */
};
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index c295b8e..1473452 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -175,6 +175,7 @@ struct iwl_cfg iwl6000h_2agn_cfg = {
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
.shadow_ram_support = true,
.ht_greenfield_support = true,
+ .use_rts_for_ht = true, /* use rts/cts protection */
};
/*
@@ -198,6 +199,7 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
.shadow_ram_support = true,
.ht_greenfield_support = true,
+ .use_rts_for_ht = true, /* use rts/cts protection */
};
struct iwl_cfg iwl6050_2agn_cfg = {
@@ -218,6 +220,7 @@ struct iwl_cfg iwl6050_2agn_cfg = {
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
.shadow_ram_support = true,
.ht_greenfield_support = true,
+ .use_rts_for_ht = true, /* use rts/cts protection */
};
struct iwl_cfg iwl6000_3agn_cfg = {
@@ -238,6 +241,7 @@ struct iwl_cfg iwl6000_3agn_cfg = {
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
.shadow_ram_support = true,
.ht_greenfield_support = true,
+ .use_rts_for_ht = true, /* use rts/cts protection */
};
struct iwl_cfg iwl6050_3agn_cfg = {
@@ -258,6 +262,7 @@ struct iwl_cfg iwl6050_3agn_cfg = {
.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
.shadow_ram_support = true,
.ht_greenfield_support = true,
+ .use_rts_for_ht = true, /* use rts/cts protection */
};
MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 346dc06..81726ee 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -418,6 +418,15 @@ static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid,
else if (tid == IWL_AGG_ALL_TID)
for (tid = 0; tid < TID_MAX_LOAD_COUNT; tid++)
rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta);
+ if (priv->cfg->use_rts_for_ht) {
+ /*
+ * switch to RTS/CTS if it is the prefer protection method
+ * for HT traffic
+ */
+ IWL_DEBUG_HT(priv, "use RTS/CTS protection for HT\n");
+ priv->staging_rxon.flags &= ~RXON_FLG_SELF_CTS_EN;
+ iwlcore_commit_rxon(priv);
+ }
}
static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 9b5ea8b..877af44 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -115,9 +115,6 @@ int iwl_commit_rxon(struct iwl_priv *priv)
/* always get timestamp with Rx frame */
priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK;
- /* allow CTS-to-self if possible. this is relevant only for
- * 5000, but will not damage 4965 */
- priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN;
ret = iwl_check_rxon_cmd(priv);
if (ret) {
@@ -217,6 +214,13 @@ int iwl_commit_rxon(struct iwl_priv *priv)
"Could not send WEP static key.\n");
}
+ /*
+ * allow CTS-to-self if possible for new association.
+ * this is relevant only for 5000 series and up,
+ * but will not damage 4965
+ */
+ priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN;
+
/* Apply the new configuration
* RXON assoc doesn't clear the station table in uCode,
*/
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index e50103a..7754538 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -213,6 +213,7 @@ struct iwl_mod_params {
* @pa_type: used by 6000 series only to identify the type of Power Amplifier
* @max_ll_items: max number of OTP blocks
* @shadow_ram_support: shadow support for OTP memory
+ * @use_rts_for_ht: use rts/cts protection for HT traffic
*
* We enable the driver to be backward compatible wrt API version. The
* driver specifies which APIs it supports (with @ucode_api_max being the
@@ -255,6 +256,7 @@ struct iwl_cfg {
const bool shadow_ram_support;
const bool ht_greenfield_support;
const bool broken_powersave;
+ bool use_rts_for_ht;
};
/***************************
diff --git a/drivers/net/wireless/libertas/ethtool.c b/drivers/net/wireless/libertas/ethtool.c
index 039b555..53d56ab 100644
--- a/drivers/net/wireless/libertas/ethtool.c
+++ b/drivers/net/wireless/libertas/ethtool.c
@@ -169,16 +169,19 @@ static int lbs_ethtool_set_wol(struct net_device *dev,
struct lbs_private *priv = dev->ml_priv;
uint32_t criteria = 0;
- if (priv->wol_criteria == 0xffffffff && wol->wolopts)
- return -EOPNOTSUPP;
-
if (wol->wolopts & ~(WAKE_UCAST|WAKE_MCAST|WAKE_BCAST|WAKE_PHY))
return -EOPNOTSUPP;
- if (wol->wolopts & WAKE_UCAST) criteria |= EHS_WAKE_ON_UNICAST_DATA;
- if (wol->wolopts & WAKE_MCAST) criteria |= EHS_WAKE_ON_MULTICAST_DATA;
- if (wol->wolopts & WAKE_BCAST) criteria |= EHS_WAKE_ON_BROADCAST_DATA;
- if (wol->wolopts & WAKE_PHY) criteria |= EHS_WAKE_ON_MAC_EVENT;
+ if (wol->wolopts & WAKE_UCAST)
+ criteria |= EHS_WAKE_ON_UNICAST_DATA;
+ if (wol->wolopts & WAKE_MCAST)
+ criteria |= EHS_WAKE_ON_MULTICAST_DATA;
+ if (wol->wolopts & WAKE_BCAST)
+ criteria |= EHS_WAKE_ON_BROADCAST_DATA;
+ if (wol->wolopts & WAKE_PHY)
+ criteria |= EHS_WAKE_ON_MAC_EVENT;
+ if (wol->wolopts == 0)
+ criteria |= EHS_REMOVE_WAKEUP;
return lbs_host_sleep_cfg(priv, criteria, (struct wol_config *)NULL);
}
diff --git a/drivers/net/wireless/rtl818x/rtl8187_rfkill.c b/drivers/net/wireless/rtl818x/rtl8187_rfkill.c
index 9fab13e..cad8037 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_rfkill.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_rfkill.c
@@ -18,6 +18,7 @@
#include <net/mac80211.h>
#include "rtl8187.h"
+#include "rtl8187_rfkill.h"
static bool rtl8187_is_radio_enabled(struct rtl8187_priv *priv)
{
diff --git a/drivers/ssb/scan.c b/drivers/ssb/scan.c
index b74212d..e8b89e8 100644
--- a/drivers/ssb/scan.c
+++ b/drivers/ssb/scan.c
@@ -162,6 +162,8 @@ static u8 chipid_to_nrcores(u16 chipid)
static u32 scan_read32(struct ssb_bus *bus, u8 current_coreidx,
u16 offset)
{
+ u32 lo, hi;
+
switch (bus->bustype) {
case SSB_BUSTYPE_SSB:
offset += current_coreidx * SSB_CORE_SIZE;
@@ -174,7 +176,9 @@ static u32 scan_read32(struct ssb_bus *bus, u8 current_coreidx,
offset -= 0x800;
} else
ssb_pcmcia_switch_segment(bus, 0);
- break;
+ lo = readw(bus->mmio + offset);
+ hi = readw(bus->mmio + offset + 2);
+ return lo | (hi << 16);
case SSB_BUSTYPE_SDIO:
offset += current_coreidx * SSB_CORE_SIZE;
return ssb_sdio_scan_read32(bus, offset);
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
^ 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