diff options
Diffstat (limited to 'net/ipv6/route.c')
-rw-r--r-- | net/ipv6/route.c | 12 |
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); |
84 | static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, | 84 | static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, |
85 | struct sk_buff *skb); | 85 | struct sk_buff *skb); |
86 | static 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 |
88 | static struct rt6_info *rt6_add_route_info(struct net *net, | 89 | static 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 | ||
396 | static struct rt6_info *rt6_multipath_select(struct rt6_info *match, | 397 | static 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); |
748 | out: | 752 | out: |
749 | dst_use(&rt->dst, jiffies); | 753 | dst_use(&rt->dst, jiffies); |
@@ -875,8 +879,8 @@ restart_2: | |||
875 | 879 | ||
876 | restart: | 880 | restart: |
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) |