From 937cf01895144dee548ed7c6a4bf25bb5c1970d6 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Wed, 2 Jul 2008 18:30:18 +0900 Subject: [PATCH] --- yaml --- r: 103211 b: refs/heads/master c: dd3abc4ef52597ec8268274222574b2700ba3ded h: refs/heads/master i: 103209: bf18b4dddf1dd77065ab72da6b99132c16b26628 103207: 08bac391f38aea4138a23f00b11263d8c4d4ba65 v: v3 --- [refs] | 2 +- trunk/net/ipv6/route.c | 20 ++++++++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/[refs] b/[refs] index 90559dd047a5..fd903b69acfc 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 1b34be74cbf18f5d58cc85c7c4afcd9f7d74accd +refs/heads/master: dd3abc4ef52597ec8268274222574b2700ba3ded diff --git a/trunk/net/ipv6/route.c b/trunk/net/ipv6/route.c index dbad96c58baa..5d6c166dfbb6 100644 --- a/trunk/net/ipv6/route.c +++ b/trunk/net/ipv6/route.c @@ -237,15 +237,20 @@ static inline int rt6_need_strict(struct in6_addr *daddr) static inline struct rt6_info *rt6_device_match(struct net *net, struct rt6_info *rt, + struct in6_addr *saddr, int oif, int flags) { struct rt6_info *local = NULL; struct rt6_info *sprt; - if (oif) { - for (sprt = rt; sprt; sprt = sprt->u.dst.rt6_next) { - struct net_device *dev = sprt->rt6i_dev; + if (!oif && ipv6_addr_any(saddr)) + goto out; + + for (sprt = rt; sprt; sprt = sprt->u.dst.rt6_next) { + struct net_device *dev = sprt->rt6i_dev; + + if (oif) { if (dev->ifindex == oif) return sprt; if (dev->flags & IFF_LOOPBACK) { @@ -259,14 +264,21 @@ static inline struct rt6_info *rt6_device_match(struct net *net, } local = sprt; } + } else { + if (ipv6_chk_addr(net, saddr, dev, + flags & RT6_LOOKUP_F_IFACE)) + return sprt; } + } + if (oif) { if (local) return local; if (flags & RT6_LOOKUP_F_IFACE) return net->ipv6.ip6_null_entry; } +out: return rt; } @@ -539,7 +551,7 @@ static struct rt6_info *ip6_pol_route_lookup(struct net *net, fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src); restart: rt = fn->leaf; - rt = rt6_device_match(net, rt, fl->oif, flags); + rt = rt6_device_match(net, rt, &fl->fl6_src, fl->oif, flags); BACKTRACK(net, &fl->fl6_src); out: dst_use(&rt->u.dst, jiffies);