aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ip6_fib.c
diff options
context:
space:
mode:
authorYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>2006-08-23 20:21:12 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-09-22 17:55:48 -0400
commit3fc5e0440be7fab3abae4e801b0ef17e9b3b58c4 (patch)
tree3512287b6942518c10c122d213334629e2266fd2 /net/ipv6/ip6_fib.c
parent2285adc1e6c9f964f9625e7edcd233fccd7a7c92 (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.c39
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