Age | Commit message (Collapse) | Author |
|
Wrong ax25_cb refcounting in ax25_send_frame() and by its callers can
cause timer oopses (first reported with 2.6.29.6 kernel).
Fixes: http://bugzilla.kernel.org/show_bug.cgi?id=14905
Reported-by: Bernard Pidoux <bpidoux@free.fr>
Tested-by: Bernard Pidoux <bpidoux@free.fr>
Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Not including net/atm/
Compiled tested x86 allyesconfig only
Added a > 80 column line or two, which I ignored.
Existing checkpatch plaints willfully, cheerfully ignored.
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts:
drivers/net/usb/cdc_ether.c
All CDC ethernet devices of type USB_CLASS_COMM need to use
'&mbm_info'.
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
While hunting dev_put() for net-next-2.6, I found a device refcount
leak in ROSE, ioctl(SIOCADDRT) error path.
Fix is to not touch device refcount, as we hold RTNL
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Adds RCU management to the list of netdevices.
Convert some for_each_netdev() users to RCU version, if
it can avoid read_lock-ing dev_base_lock
Ie:
read_lock(&dev_base_loack);
for_each_netdev(net, dev)
some_action();
read_unlock(&dev_base_lock);
becomes :
rcu_read_lock();
for_each_netdev_rcu(net, dev)
some_action();
rcu_read_unlock();
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
The use of a static buffer in rose2asc() to return its result is not
threadproof and can result in corruption if multiple threads are trying
to use one of the procfs files based on rose2asc().
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
ROSE network is organized through nodes connected via hamradio or Internet.
AX25 packet radio frames sent to a remote ROSE address destination are routed
through these nodes.
Without the present patch, automatic routing mechanism did not work optimally
due to an improper parameter checking.
rose_get_neigh() function is called either by rose_connect() or by
rose_route_frame().
In the case of a call from rose_connect(), f0 timer is checked to find if a connection
is already pending. In that case it returns the address of the neighbour, or returns a NULL otherwise.
When called by rose_route_frame() the purpose was to route a packet AX25 frame
through an adjacent node given a destination rose address.
However, in that case, t0 timer checked does not indicate if the adjacent node
is actually connected even if the timer is not null. Thus, for each frame sent, the
function often tried to start a new connexion even if the adjacent node was already connected.
The patch adds a "new" parameter that is true when the function is called by
rose route_frame().
This instructs rose_get_neigh() to check node parameter "restarted".
If restarted is true it means that the route to the destination address is opened via a neighbour
node already connected.
If "restarted" is false the function returns a NULL.
In that case the calling function will initiate a new connection as before.
This results in a fast routing of frames, from nodes to nodes, until
destination is reached, as originaly specified by ROSE protocole.
Signed-off-by: Bernard Pidoux <f6bvp@amsat.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
In rose_node_start() as well as in rose_node_stop() __acquires() and
spin_lock_bh() were wrongly passing rose_neigh_list_lock instead of
rose_node_list_lock arguments.
Signed-off-by: Bernard Pidoux <f6bvp@amsat.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
[ INFO: possible recursive locking detected ]
2.6.25 #3
---------------------------------------------
ax25ipd/3811 is trying to acquire lock:
(rose_node_list_lock){-+..}, at: [<f8d31f1a>] rose_get_neigh+0x1a/0xa0
[rose]
but task is already holding lock:
(rose_node_list_lock){-+..}, at: [<f8d31fed>]
rose_route_frame+0x4d/0x620 [rose]
other info that might help us debug this:
6 locks held by ax25ipd/3811:
#0: (&tty->atomic_write_lock){--..}, at: [<c0259a1c>]
tty_write_lock+0x1c/0x50
#1: (rcu_read_lock){..--}, at: [<c02aea36>] net_rx_action+0x96/0x230
#2: (rcu_read_lock){..--}, at: [<c02ac5c0>] netif_receive_skb+0x100/0x2f0
#3: (rose_node_list_lock){-+..}, at: [<f8d31fed>]
rose_route_frame+0x4d/0x620 [rose]
#4: (rose_neigh_list_lock){-+..}, at: [<f8d31ff7>]
rose_route_frame+0x57/0x620 [rose]
#5: (rose_route_list_lock){-+..}, at: [<f8d32001>]
rose_route_frame+0x61/0x620 [rose]
stack backtrace:
Pid: 3811, comm: ax25ipd Not tainted 2.6.25 #3
[<c0147e27>] print_deadlock_bug+0xc7/0xd0
[<c0147eca>] check_deadlock+0x9a/0xb0
[<c0149cd2>] validate_chain+0x1e2/0x310
[<c0149b95>] ? validate_chain+0xa5/0x310
[<c010a7d8>] ? native_sched_clock+0x88/0xc0
[<c0149fa1>] __lock_acquire+0x1a1/0x750
[<c014a5d1>] lock_acquire+0x81/0xa0
[<f8d31f1a>] ? rose_get_neigh+0x1a/0xa0 [rose]
[<c03201a3>] _spin_lock_bh+0x33/0x60
[<f8d31f1a>] ? rose_get_neigh+0x1a/0xa0 [rose]
[<f8d31f1a>] rose_get_neigh+0x1a/0xa0 [rose]
[<f8d32404>] rose_route_frame+0x464/0x620 [rose]
[<c031ffdd>] ? _read_unlock+0x1d/0x20
[<f8d31fa0>] ? rose_route_frame+0x0/0x620 [rose]
[<f8d1c396>] ax25_rx_iframe+0x66/0x3b0 [ax25]
[<f8d1f42f>] ? ax25_start_t3timer+0x1f/0x40 [ax25]
[<f8d1e65b>] ax25_std_frame_in+0x7fb/0x890 [ax25]
[<c0320005>] ? _spin_unlock_bh+0x25/0x30
[<f8d1bdf6>] ax25_kiss_rcv+0x2c6/0x800 [ax25]
[<c02a4769>] ? sock_def_readable+0x59/0x80
[<c014a8a7>] ? __lock_release+0x47/0x70
[<c02a4769>] ? sock_def_readable+0x59/0x80
[<c031ffdd>] ? _read_unlock+0x1d/0x20
[<c02a4769>] ? sock_def_readable+0x59/0x80
[<c02a4d3a>] ? sock_queue_rcv_skb+0x13a/0x1d0
[<c02a4c45>] ? sock_queue_rcv_skb+0x45/0x1d0
[<f8d1bb30>] ? ax25_kiss_rcv+0x0/0x800 [ax25]
[<c02ac715>] netif_receive_skb+0x255/0x2f0
[<c02ac5c0>] ? netif_receive_skb+0x100/0x2f0
[<c02af05c>] process_backlog+0x7c/0xf0
[<c02aeb0c>] net_rx_action+0x16c/0x230
[<c02aea36>] ? net_rx_action+0x96/0x230
[<c012bd53>] __do_softirq+0x93/0x120
[<f8d2a68a>] ? mkiss_receive_buf+0x33a/0x3f0 [mkiss]
[<c012be37>] do_softirq+0x57/0x60
[<c012c265>] local_bh_enable_ip+0xa5/0xe0
[<c0320005>] _spin_unlock_bh+0x25/0x30
[<f8d2a68a>] mkiss_receive_buf+0x33a/0x3f0 [mkiss]
[<c025ea37>] pty_write+0x47/0x60
[<c025c620>] write_chan+0x1b0/0x220
[<c0259a1c>] ? tty_write_lock+0x1c/0x50
[<c011fec0>] ? default_wake_function+0x0/0x10
[<c0259bea>] tty_write+0x12a/0x1c0
[<c025c470>] ? write_chan+0x0/0x220
[<c018bbc6>] vfs_write+0x96/0x130
[<c0259ac0>] ? tty_write+0x0/0x1c0
[<c018c24d>] sys_write+0x3d/0x70
[<c0104d1e>] sysenter_past_esp+0x5f/0xa5
=======================
BUG: soft lockup - CPU#0 stuck for 61s! [ax25ipd:3811]
Pid: 3811, comm: ax25ipd Not tainted (2.6.25 #3)
EIP: 0060:[<c010a9db>] EFLAGS: 00000246 CPU: 0
EIP is at native_read_tsc+0xb/0x20
EAX: b404aa2c EBX: b404a9c9 ECX: 017f1000 EDX: 0000076b
ESI: 00000001 EDI: 00000000 EBP: ecc83afc ESP: ecc83afc
DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
CR0: 8005003b CR2: b7f5f000 CR3: 2cd8e000 CR4: 000006f0
DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
DR6: ffff0ff0 DR7: 00000400
[<c0204937>] delay_tsc+0x17/0x30
[<c02048e9>] __delay+0x9/0x10
[<c02127f6>] __spin_lock_debug+0x76/0xf0
[<c0212618>] ? spin_bug+0x18/0x100
[<c0147923>] ? __lock_contended+0xa3/0x110
[<c0212998>] _raw_spin_lock+0x68/0x90
[<c03201bf>] _spin_lock_bh+0x4f/0x60
[<f8d31f1a>] ? rose_get_neigh+0x1a/0xa0 [rose]
[<f8d31f1a>] rose_get_neigh+0x1a/0xa0 [rose]
[<f8d32404>] rose_route_frame+0x464/0x620 [rose]
[<c031ffdd>] ? _read_unlock+0x1d/0x20
[<f8d31fa0>] ? rose_route_frame+0x0/0x620 [rose]
[<f8d1c396>] ax25_rx_iframe+0x66/0x3b0 [ax25]
[<f8d1f42f>] ? ax25_start_t3timer+0x1f/0x40 [ax25]
[<f8d1e65b>] ax25_std_frame_in+0x7fb/0x890 [ax25]
[<c0320005>] ? _spin_unlock_bh+0x25/0x30
[<f8d1bdf6>] ax25_kiss_rcv+0x2c6/0x800 [ax25]
[<c02a4769>] ? sock_def_readable+0x59/0x80
[<c014a8a7>] ? __lock_release+0x47/0x70
[<c02a4769>] ? sock_def_readable+0x59/0x80
[<c031ffdd>] ? _read_unlock+0x1d/0x20
[<c02a4769>] ? sock_def_readable+0x59/0x80
[<c02a4d3a>] ? sock_queue_rcv_skb+0x13a/0x1d0
[<c02a4c45>] ? sock_queue_rcv_skb+0x45/0x1d0
[<f8d1bb30>] ? ax25_kiss_rcv+0x0/0x800 [ax25]
[<c02ac715>] netif_receive_skb+0x255/0x2f0
[<c02ac5c0>] ? netif_receive_skb+0x100/0x2f0
[<c02af05c>] process_backlog+0x7c/0xf0
[<c02aeb0c>] net_rx_action+0x16c/0x230
[<c02aea36>] ? net_rx_action+0x96/0x230
[<c012bd53>] __do_softirq+0x93/0x120
[<f8d2a68a>] ? mkiss_receive_buf+0x33a/0x3f0 [mkiss]
[<c012be37>] do_softirq+0x57/0x60
[<c012c265>] local_bh_enable_ip+0xa5/0xe0
[<c0320005>] _spin_unlock_bh+0x25/0x30
[<f8d2a68a>] mkiss_receive_buf+0x33a/0x3f0 [mkiss]
[<c025ea37>] pty_write+0x47/0x60
[<c025c620>] write_chan+0x1b0/0x220
[<c0259a1c>] ? tty_write_lock+0x1c/0x50
[<c011fec0>] ? default_wake_function+0x0/0x10
[<c0259bea>] tty_write+0x12a/0x1c0
[<c025c470>] ? write_chan+0x0/0x220
[<c018bbc6>] vfs_write+0x96/0x130
[<c0259ac0>] ? tty_write+0x0/0x1c0
[<c018c24d>] sys_write+0x3d/0x70
[<c0104d1e>] sysenter_past_esp+0x5f/0xa5
=======================
Since rose_route_frame() does not use rose_node_list we can safely
remove rose_node_list_lock spin lock here and let it be free for
rose_get_neigh().
Signed-off-by: Bernard Pidoux <f6bvp@amsat.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
CHECK net/rose/af_rose.c
net/rose/af_rose.c:125:11: warning: expensive signed divide
net/rose/af_rose.c:976:46: warning: expensive signed divide
net/rose/af_rose.c:1379:13: warning: context imbalance in 'rose_info_start' - wrong count at exit
net/rose/af_rose.c:1406:13: warning: context imbalance in 'rose_info_stop' - unexpected unlock
CHECK net/rose/rose_in.c
net/rose/rose_in.c:185:25: warning: expensive signed divide
CHECK net/rose/rose_route.c
net/rose/rose_route.c:997:46: warning: expensive signed divide
net/rose/rose_route.c:1070:13: warning: context imbalance in 'rose_node_start' - wrong count at exit
net/rose/rose_route.c:1093:13: warning: context imbalance in 'rose_node_stop' - unexpected unlock
net/rose/rose_route.c:1146:13: warning: context imbalance in 'rose_neigh_start' - wrong count at exit
net/rose/rose_route.c:1169:13: warning: context imbalance in 'rose_neigh_stop' - unexpected unlock
net/rose/rose_route.c:1229:13: warning: context imbalance in 'rose_route_start' - wrong count at exit
net/rose/rose_route.c:1252:13: warning: context imbalance in 'rose_route_stop' - unexpected unlock
Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
This patch makes most of the generic device layer network
namespace safe. This patch makes dev_base_head a
network namespace variable, and then it picks up
a few associated variables. The functions:
dev_getbyhwaddr
dev_getfirsthwbytype
dev_get_by_flags
dev_get_by_name
__dev_get_by_name
dev_get_by_index
__dev_get_by_index
dev_ioctl
dev_ethtool
dev_load
wireless_process_ioctl
were modified to take a network namespace argument, and
deal with it.
vlan_ioctl_set and brioctl_set were modified so their
hooks will receive a network namespace argument.
So basically anthing in the core of the network stack that was
affected to by the change of dev_base was modified to handle
multiple network namespaces. The rest of the network stack was
simply modified to explicitly use &init_net the initial network
namespace. This can be fixed when those components of the network
stack are modified to handle multiple network namespaces.
For now the ifindex generator is left global.
Fundametally ifindex numbers are per namespace, or else
we will have corner case problems with migration when
we get that far.
At the same time there are assumptions in the network stack
that the ifindex of a network device won't change. Making
the ifindex number global seems a good compromise until
the network stack can cope with ifindex changes when
you change namespaces, and the like.
Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Commit a3d384029aa304f8f3f5355d35f0ae274454f7cd aka
"[AX.25]: Fix unchecked rose_add_loopback_neigh uses"
transformed rose_loopback_neigh var into statically allocated one.
However, on unload it will be kfree's which can't work.
Steps to reproduce:
modprobe rose
rmmod rose
BUG: unable to handle kernel NULL pointer dereference at virtual address 00000008
printing eip:
c014c664
*pde = 00000000
Oops: 0000 [#1]
PREEMPT DEBUG_PAGEALLOC
Modules linked in: rose ax25 fan ufs loop usbhid rtc snd_intel8x0 snd_ac97_codec ehci_hcd ac97_bus uhci_hcd thermal usbcore button processor evdev sr_mod cdrom
CPU: 0
EIP: 0060:[<c014c664>] Not tainted VLI
EFLAGS: 00210086 (2.6.23-rc9 #3)
EIP is at kfree+0x48/0xa1
eax: 00000556 ebx: c1734aa0 ecx: f6a5e000 edx: f7082000
esi: 00000000 edi: f9a55d20 ebp: 00200287 esp: f6a5ef28
ds: 007b es: 007b fs: 0000 gs: 0033 ss: 0068
Process rmmod (pid: 1823, ti=f6a5e000 task=f7082000 task.ti=f6a5e000)
Stack: f9a55d20 f9a5200c 00000000 00000000 00000000 f6a5e000 f9a5200c f9a55a00
00000000 bf818cf0 f9a51f3f f9a55a00 00000000 c0132c60 65736f72 00000000
f69f9630 f69f9528 c014244a f6a4e900 00200246 f7082000 c01025e6 00000000
Call Trace:
[<f9a5200c>] rose_rt_free+0x1d/0x49 [rose]
[<f9a5200c>] rose_rt_free+0x1d/0x49 [rose]
[<f9a51f3f>] rose_exit+0x4c/0xd5 [rose]
[<c0132c60>] sys_delete_module+0x15e/0x186
[<c014244a>] remove_vma+0x40/0x45
[<c01025e6>] sysenter_past_esp+0x8f/0x99
[<c012bacf>] trace_hardirqs_on+0x118/0x13b
[<c01025b6>] sysenter_past_esp+0x5f/0x99
=======================
Code: 05 03 1d 80 db 5b c0 8b 03 25 00 40 02 00 3d 00 40 02 00 75 03 8b 5b 0c 8b 73 10 8b 44 24 18 89 44 24 04 9c 5d fa e8 77 df fd ff <8b> 56 08 89 f8 e8 84 f4 fd ff e8 bd 32 06 00 3b 5c 86 60 75 0f
EIP: [<c014c664>] kfree+0x48/0xa1 SS:ESP 0068:f6a5ef28
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Make all initialized struct seq_operations in net/ const
Signed-off-by: Philippe De Muyter <phdm@macqel.be>
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Cleanup of dev_base list use, with the aim to simplify making device
list per-namespace. In almost every occasion, use of dev_base variable
and dev->next pointer could be easily replaced by for_each_netdev
loop. A few most complicated places were converted to using
first_netdev()/next_netdev().
Signed-off-by: Pavel Emelianov <xemul@openvz.org>
Acked-by: Kirill Korotaev <dev@openvz.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
For the common, open coded 'skb->h.raw = skb->data' operation, so that we can
later turn skb->h.raw into a offset, reducing the size of struct sk_buff in
64bit land while possibly keeping it as a pointer on 32bit.
This one touches just the most simple cases:
skb->h.raw = skb->data;
skb->h.raw = {skb_push|[__]skb_pull}()
The next ones will handle the slightly more "complex" cases.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
After Al Viro (finally) succeeded in removing the sched.h #include in module.h
recently, it makes sense again to remove other superfluous sched.h includes.
There are quite a lot of files which include it but don't actually need
anything defined in there. Presumably these includes were once needed for
macros that used to live in sched.h, but moved to other header files in the
course of cleaning it up.
To ease the pain, this time I did not fiddle with any header files and only
removed #includes from .c-files, which tend to cause less trouble.
Compile tested against 2.6.20-rc2 and 2.6.20-rc2-mm2 (with offsets) on alpha,
arm, i386, ia64, mips, powerpc, and x86_64 with allnoconfig, defconfig,
allmodconfig, and allyesconfig as well as a few randconfigs on x86_64 and all
configs in arch/arm/configs on arm. I also checked that no new warnings were
introduced by the patch (actually, some warnings are removed that were emitted
by unnecessarily included header files).
Signed-off-by: Tim Schmielau <tim@physik3.uni-rostock.de>
Acked-by: Russell King <rmk+kernel@arm.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
|
Many struct file_operations in the kernel can be "const". Marking them const
moves these to the .rodata section, which avoids false sharing with potential
dirty data. In addition it'll catch accidental writes at compile time to
these shared resources.
Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
|
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
rose_add_loopback_neigh uses kmalloc and the callers were ignoring the
error value. Rewrite to let the caller deal with the allocation. This
allows the use of static allocation of kmalloc use entirely.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
The recent fix 0506d4068bad834aab1141b5dc5e748eb175c6b3 made obvious that
error values were not being propagated through the AX.25 stack. To help
with that this patch marks all kmalloc users in the AX.25, NETROM and
ROSE stacks as __must_check.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
David Binderman's icc logs:
net/rose/rose_route.c(399): remark #593: variable "err" was set but never used
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
The locking rule for rose_remove_neigh() are that the caller needs to
hold rose_neigh_list_lock, so we better don't take it yet again in
rose_neigh_list_lock.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
From: Jesper Juhl <jesper.juhl@gmail.com>
This is the net/ part of the big kfree cleanup patch.
Remove pointless checks for NULL prior to calling kfree() in net/.
Signed-off-by: Jesper Juhl <jesper.juhl@gmail.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Acked-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
|
|
Signed-off-by: Ralf Baechle DL5RB <ralf@linux-mips.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
|
|
Ax2asc was still using a static buffer for all invocations which isn't
exactly SMP-safe. Change ax2asc to take an additional result buffer as
the argument. Change all callers to provide such a buffer.
Signed-off-by: Ralf Baechle DL5RB <ralf@linux-mips.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Lots of places just needs the states, not even linux/tcp.h, where this
enum was, needs it.
This speeds up development of the refactorings as less sources are
rebuilt when things get moved from net/tcp.h.
Signed-off-by: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Noticed by Coverity checker.
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
|