aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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