lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20080628.041404.82719082.yoshfuji@linux-ipv6.org>
Date:	Sat, 28 Jun 2008 04:14:04 +0900 (JST)
From:	YOSHIFUJI Hideaki / 吉藤英明 
	<yoshfuji@...ux-ipv6.org>
To:	usagi-users@...linux-ipv6.org, nooiwa@...aclelinux.com
Cc:	netdev@...r.kernel.org, usagi-users@...ux-ipv6.org
Subject: Re: (usagi-users 04056) Re: ping6 is sent out from wrong interface

In article <4861ED72.6080100@...aclelinux.com> (at Wed, 25 Jun 2008 16:02:10 +0900), Naohiro Ooiwa <nooiwa@...aclelinux.com> says:

> Hi YOSHIFUJI-san
> 
> Thank you for your reply.
> 
> > -I does not specify interface strictly but source address.
> > Which means, if you just specify an address, interface is unspecified.
> > You can give "-I eth1", too.
> 
> I'm not convinced yet.
> I don't think it's correct that kernel or ping6 arbitrarily decides outgoing interface.
> 
> Is this really an expected behaviour?
> Could you explain to me the reason of it, too?

I have to agree it is rather strange (or not natural), but, I do not
agree with the solution.

In theory, outgoing interface must be selected by routing, if unspecified.
So, I'd propose something like this (not tested, not for real patch).

diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index d1f3e19..81ddf9a 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -239,17 +239,28 @@ 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 strict)
 {
 	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))
+		saddr = NULL;
+
+	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;
+		} else {
+			if (saddr && ipv6_chk_addr(net, saddr, dev, strict))
+				return sprt;
+		}
+
+		if (oif) {
 			if (dev->flags & IFF_LOOPBACK) {
 				if (sprt->rt6i_idev == NULL ||
 				    sprt->rt6i_idev->dev->ifindex != oif) {
@@ -261,13 +272,13 @@ static inline struct rt6_info *rt6_device_match(struct net *net,
 				}
 				local = sprt;
 			}
-		}
 
-		if (local)
-			return local;
+			if (local)
+				return local;
 
-		if (strict)
-			return net->ipv6.ip6_null_entry;
+			if (strict)
+				return net->ipv6.ip6_null_entry;
+		}
 	}
 	return rt;
 }
@@ -541,7 +552,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);

-- 
YOSHIFUJI Hideaki @ USAGI Project  <yoshfuji@...ux-ipv6.org>
GPG-FP  : 9022 65EB 1ECF 3AD1 0BDF  80D8 4807 F894 E062 0EEA
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ