diff options
author | YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> | 2006-08-23 20:21:12 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-09-22 17:55:48 -0400 |
commit | 3fc5e0440be7fab3abae4e801b0ef17e9b3b58c4 (patch) | |
tree | 3512287b6942518c10c122d213334629e2266fd2 /net/ipv6/ip6_fib.c | |
parent | 2285adc1e6c9f964f9625e7edcd233fccd7a7c92 (diff) |
[IPV6] ROUTE: Fix looking up a route on subtree.
Even on RTN_ROOT node, we need to process its subtree first.
Fix NULL pointer dereference in fib6_locate().
Based on MIPL2 kernel patch.
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: Ville Nuorvala <vnuorval@tcs.hut.fi>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/ip6_fib.c')
-rw-r--r-- | net/ipv6/ip6_fib.c | 39 |
1 files changed, 15 insertions, 24 deletions
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 35b91ff95db2..5408b64f3b5f 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
@@ -850,33 +850,26 @@ static struct fib6_node * fib6_lookup_1(struct fib6_node *root, | |||
850 | break; | 850 | break; |
851 | } | 851 | } |
852 | 852 | ||
853 | while ((fn->fn_flags & RTN_ROOT) == 0) { | 853 | while(fn) { |
854 | #ifdef CONFIG_IPV6_SUBTREES | 854 | if (SUBTREE(fn) || fn->fn_flags & RTN_RTINFO) { |
855 | if (fn->subtree) { | ||
856 | struct fib6_node *st; | ||
857 | struct lookup_args *narg; | ||
858 | |||
859 | narg = args + 1; | ||
860 | |||
861 | if (narg->addr) { | ||
862 | st = fib6_lookup_1(fn->subtree, narg); | ||
863 | |||
864 | if (st && !(st->fn_flags & RTN_ROOT)) | ||
865 | return st; | ||
866 | } | ||
867 | } | ||
868 | #endif | ||
869 | |||
870 | if (fn->fn_flags & RTN_RTINFO) { | ||
871 | struct rt6key *key; | 855 | struct rt6key *key; |
872 | 856 | ||
873 | key = (struct rt6key *) ((u8 *) fn->leaf + | 857 | key = (struct rt6key *) ((u8 *) fn->leaf + |
874 | args->offset); | 858 | args->offset); |
875 | 859 | ||
876 | if (ipv6_prefix_equal(&key->addr, args->addr, key->plen)) | 860 | if (ipv6_prefix_equal(&key->addr, args->addr, key->plen)) { |
877 | return fn; | 861 | #ifdef CONFIG_IPV6_SUBTREES |
862 | if (fn->subtree) | ||
863 | fn = fib6_lookup_1(fn->subtree, args + 1); | ||
864 | #endif | ||
865 | if (!fn || fn->fn_flags & RTN_RTINFO) | ||
866 | return fn; | ||
867 | } | ||
878 | } | 868 | } |
879 | 869 | ||
870 | if (fn->fn_flags & RTN_ROOT) | ||
871 | break; | ||
872 | |||
880 | fn = fn->parent; | 873 | fn = fn->parent; |
881 | } | 874 | } |
882 | 875 | ||
@@ -953,10 +946,8 @@ struct fib6_node * fib6_locate(struct fib6_node *root, | |||
953 | #ifdef CONFIG_IPV6_SUBTREES | 946 | #ifdef CONFIG_IPV6_SUBTREES |
954 | if (src_len) { | 947 | if (src_len) { |
955 | BUG_TRAP(saddr!=NULL); | 948 | BUG_TRAP(saddr!=NULL); |
956 | if (fn == NULL) | 949 | if (fn && fn->subtree) |
957 | fn = fn->subtree; | 950 | fn = fib6_locate_1(fn->subtree, saddr, src_len, |
958 | if (fn) | ||
959 | fn = fib6_locate_1(fn, saddr, src_len, | ||
960 | offsetof(struct rt6_info, rt6i_src)); | 951 | offsetof(struct rt6_info, rt6i_src)); |
961 | } | 952 | } |
962 | #endif | 953 | #endif |