aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/route.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/route.c')
-rw-r--r--net/ipv6/route.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 7ca87b37c0ef..9ff0b78a9c15 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -83,6 +83,7 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
83 struct sk_buff *skb, u32 mtu); 83 struct sk_buff *skb, u32 mtu);
84static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, 84static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk,
85 struct sk_buff *skb); 85 struct sk_buff *skb);
86static int rt6_score_route(struct rt6_info *rt, int oif, int strict);
86 87
87#ifdef CONFIG_IPV6_ROUTE_INFO 88#ifdef CONFIG_IPV6_ROUTE_INFO
88static struct rt6_info *rt6_add_route_info(struct net *net, 89static struct rt6_info *rt6_add_route_info(struct net *net,
@@ -394,7 +395,8 @@ static int rt6_info_hash_nhsfn(unsigned int candidate_count,
394} 395}
395 396
396static struct rt6_info *rt6_multipath_select(struct rt6_info *match, 397static struct rt6_info *rt6_multipath_select(struct rt6_info *match,
397 struct flowi6 *fl6) 398 struct flowi6 *fl6, int oif,
399 int strict)
398{ 400{
399 struct rt6_info *sibling, *next_sibling; 401 struct rt6_info *sibling, *next_sibling;
400 int route_choosen; 402 int route_choosen;
@@ -408,6 +410,8 @@ static struct rt6_info *rt6_multipath_select(struct rt6_info *match,
408 &match->rt6i_siblings, rt6i_siblings) { 410 &match->rt6i_siblings, rt6i_siblings) {
409 route_choosen--; 411 route_choosen--;
410 if (route_choosen == 0) { 412 if (route_choosen == 0) {
413 if (rt6_score_route(sibling, oif, strict) < 0)
414 break;
411 match = sibling; 415 match = sibling;
412 break; 416 break;
413 } 417 }
@@ -743,7 +747,7 @@ restart:
743 rt = fn->leaf; 747 rt = fn->leaf;
744 rt = rt6_device_match(net, rt, &fl6->saddr, fl6->flowi6_oif, flags); 748 rt = rt6_device_match(net, rt, &fl6->saddr, fl6->flowi6_oif, flags);
745 if (rt->rt6i_nsiblings && fl6->flowi6_oif == 0) 749 if (rt->rt6i_nsiblings && fl6->flowi6_oif == 0)
746 rt = rt6_multipath_select(rt, fl6); 750 rt = rt6_multipath_select(rt, fl6, fl6->flowi6_oif, flags);
747 BACKTRACK(net, &fl6->saddr); 751 BACKTRACK(net, &fl6->saddr);
748out: 752out:
749 dst_use(&rt->dst, jiffies); 753 dst_use(&rt->dst, jiffies);
@@ -875,8 +879,8 @@ restart_2:
875 879
876restart: 880restart:
877 rt = rt6_select(fn, oif, strict | reachable); 881 rt = rt6_select(fn, oif, strict | reachable);
878 if (rt->rt6i_nsiblings && oif == 0) 882 if (rt->rt6i_nsiblings)
879 rt = rt6_multipath_select(rt, fl6); 883 rt = rt6_multipath_select(rt, fl6, oif, strict | reachable);
880 BACKTRACK(net, &fl6->saddr); 884 BACKTRACK(net, &fl6->saddr);
881 if (rt == net->ipv6.ip6_null_entry || 885 if (rt == net->ipv6.ip6_null_entry ||
882 rt->rt6i_flags & RTF_CACHE) 886 rt->rt6i_flags & RTF_CACHE)