alistair23-linux/net/ipv6
David S. Miller f11e6659ce [IPV6]: Fix routing round-robin locking.
As per RFC2461, section 6.3.6, item #2, when no routers on the
matching list are known to be reachable or probably reachable we
do round robin on those available routes so that we make sure
to probe as many of them as possible to detect when one becomes
reachable faster.

Each routing table has a rwlock protecting the tree and the linked
list of routes at each leaf.  The round robin code executes during
lookup and thus with the rwlock taken as a reader.  A small local
spinlock tries to provide protection but this does not work at all
for two reasons:

1) The round-robin list manipulation, as coded, goes like this (with
   read lock held):

	walk routes finding head and tail

	spin_lock();
	rotate list using head and tail
	spin_unlock();

   While one thread is rotating the list, another thread can
   end up with stale values of head and tail and then proceed
   to corrupt the list when it gets the lock.  This ends up causing
   the OOPS in fib6_add() later onthat many people have been hitting.

2) All the other code paths that run with the rwlock held as
   a reader do not expect the list to change on them, they
   expect it to remain completely fixed while they hold the
   lock in that way.

So, simply stated, it is impossible to implement this correctly using
a manipulation of the list without violating the rwlock locking
semantics.

Reimplement using a per-fib6_node round-robin pointer.  This way we
don't need to manipulate the list at all, and since the round-robin
pointer can only ever point to real existing entries we don't need
to perform any locking on the changing of the round-robin pointer
itself.  We only need to reset the round-robin pointer to NULL when
the entry it is pointing to is removed.

The idea is from Thomas Graf and it is very similar to how this
was implemented before the advanced router selection code when in.

Signed-off-by: David S. Miller <davem@davemloft.net>
2007-03-25 18:48:05 -07:00
..
netfilter [NETFILTER]: nf_conntrack_ipv6: fix incorrect classification of IPv6 fragments as ESTABLISHED 2007-03-07 16:08:01 -08:00
addrconf.c [NET]: fix up misplaced inlines. 2007-03-22 12:27:49 -07:00
addrconf_core.c [IPV6]: Fix __ipv6_addr_type() export in correct place. 2007-02-26 11:42:57 -08:00
af_inet6.c [IPV6]: Adjust inet6_exit() cleanup sequence against inet6_init() 2007-02-26 11:42:44 -08:00
ah6.c [NET] IPV6: Fix whitespace errors. 2007-02-10 23:19:42 -08:00
anycast.c [IPV6]: /proc/net/anycast6 unbalanced inet6_dev refcnt 2007-02-28 09:42:10 -08:00
datagram.c [PATCH] remove many unneeded #includes of sched.h 2007-02-14 08:09:54 -08:00
esp6.c [NET] IPV6: Fix whitespace errors. 2007-02-10 23:19:42 -08:00
exthdrs.c [PATCH] remove many unneeded #includes of sched.h 2007-02-14 08:09:54 -08:00
exthdrs_core.c [NET] IPV6: Fix whitespace errors. 2007-02-10 23:19:42 -08:00
fib6_rules.c [NET]: Fix fib_rules compatibility breakage 2007-03-25 18:48:00 -07:00
icmp.c [PATCH] remove many unneeded #includes of sched.h 2007-02-14 08:09:54 -08:00
inet6_connection_sock.c [TCP]: Restore SKB socket owner setting in tcp_transmit_skb(). 2007-01-26 01:04:55 -08:00
inet6_hashtables.c [IPV6] HASHTABLES: Use appropriate seed for caluculating ehash index. 2007-02-12 20:26:39 -08:00
ip6_fib.c [IPV6]: Fix routing round-robin locking. 2007-03-25 18:48:05 -07:00
ip6_flowlabel.c [PATCH] mark struct file_operations const 7 2007-02-12 09:48:46 -08:00
ip6_input.c [PATCH] remove many unneeded #includes of sched.h 2007-02-14 08:09:54 -08:00
ip6_output.c [NET] IPV6: Fix whitespace errors. 2007-02-10 23:19:42 -08:00
ip6_tunnel.c [IPV6] IP6TUNNEL: Use update_pmtu() of dst on xmit. 2007-02-26 11:42:53 -08:00
ipcomp6.c [NET] IPV6: Fix whitespace errors. 2007-02-10 23:19:42 -08:00
ipv6_sockglue.c [IPV6] fix ipv6_getsockopt_sticky copy_to_user leak 2007-03-09 16:19:17 -08:00
ipv6_syms.c [IPV6]: Fix __ipv6_addr_type() export in correct place. 2007-02-26 11:42:57 -08:00
Kconfig [IPSEC]: make sit use the xfrm4_tunnel_register 2007-02-13 12:55:25 -08:00
Makefile [IPV6] ADDRCONF: Statically link __ipv6_addr_type() for sunrpc subsystem. 2007-02-26 11:42:52 -08:00
mcast.c [PATCH] mark struct file_operations const 7 2007-02-12 09:48:46 -08:00
mip6.c [NET] IPV6: Fix whitespace errors. 2007-02-10 23:19:42 -08:00
ndisc.c [NET] IPV6: Fix whitespace errors. 2007-02-10 23:19:42 -08:00
netfilter.c [NETFILTER]: ip6_route_me_harder should take into account mark 2007-03-05 13:25:27 -08:00
proc.c [PATCH] remove many unneeded #includes of sched.h 2007-02-14 08:09:54 -08:00
protocol.c [PATCH] remove many unneeded #includes of sched.h 2007-02-14 08:09:54 -08:00
raw.c [PATCH] remove many unneeded #includes of sched.h 2007-02-14 08:09:54 -08:00
reassembly.c [NET] IPV6: Fix whitespace errors. 2007-02-10 23:19:42 -08:00
route.c [IPV6]: Fix routing round-robin locking. 2007-03-25 18:48:05 -07:00
sit.c [PATCH] remove many unneeded #includes of sched.h 2007-02-14 08:09:54 -08:00
sysctl_net_ipv6.c [PATCH] sysctl: remove insert_at_head from register_sysctl 2007-02-14 08:09:59 -08:00
tcp_ipv6.c [IPV6]: ipv6_fl_socklist is inadvertently shared. 2007-03-16 16:14:03 -07:00
tunnel6.c [IPSEC]: changing API of xfrm6_tunnel_register 2007-02-13 12:55:55 -08:00
udp.c [PATCH] remove many unneeded #includes of sched.h 2007-02-14 08:09:54 -08:00
udp_impl.h [NET] IPV6: Fix whitespace errors. 2007-02-10 23:19:42 -08:00
udplite.c [NET]: Possible cleanups. 2006-12-02 21:31:51 -08:00
xfrm6_input.c [IPSEC]: changing API of xfrm6_tunnel_register 2007-02-13 12:55:55 -08:00
xfrm6_mode_beet.c [XFRM]: BEET mode 2006-10-04 00:31:09 -07:00
xfrm6_mode_ro.c [IPSEC]: output mode to take an xfrm state as input param 2006-09-22 15:18:48 -07:00
xfrm6_mode_transport.c [IPSEC]: output mode to take an xfrm state as input param 2006-09-22 15:18:48 -07:00
xfrm6_mode_tunnel.c [IPSEC]: IPv4 over IPv6 IPsec tunnel 2007-02-08 12:39:02 -08:00
xfrm6_output.c [NET] IPV6: Fix whitespace errors. 2007-02-10 23:19:42 -08:00
xfrm6_policy.c [IPSEC]: More fix is needed for __xfrm6_bundle_create(). 2007-02-26 11:42:43 -08:00
xfrm6_state.c [NET] IPV6: Fix whitespace errors. 2007-02-10 23:19:42 -08:00
xfrm6_tunnel.c [NET]: fix up misplaced inlines. 2007-03-22 12:27:49 -07:00