Re: [PATCH net-next v2] ipv6: Do not iterate over all interfaces when finding source address on specific interface.

2015-07-13 Thread Erik Kline
On 13 July 2015 at 15:32, YOSHIFUJI Hideaki
hideaki.yoshif...@miraclelinux.com wrote:
 Hi,

 Erik Kline wrote:
 Hmm, when I run a UML linux with this patch (which, I'm ashamed to
 say, I failed to do before) I get these kinds of errors:

 unregister_netdevice: waiting for TAPdevice to become free.
 Usage count = 1
 unregister_netdevice: waiting for TAPdevice to become free.
 Usage count = 1

 Perhaps they're unrelated... I'm still investigating.

 Would you test attached patch please?

That does look logically correct, so +1 to it regardless, but it does
not seem to have fixed the issue I'm seeing.

I still haven't produced the smallest possible demo test program.
--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH net-next v2] ipv6: Do not iterate over all interfaces when finding source address on specific interface.

2015-07-13 Thread Hajime Tazaki

Yoshifuji-san,

At Mon, 13 Jul 2015 17:38:48 +0900,
Erik Kline wrote:
 
 On 13 July 2015 at 15:32, YOSHIFUJI Hideaki
 hideaki.yoshif...@miraclelinux.com wrote:
  Hi,
 
  Erik Kline wrote:
  Hmm, when I run a UML linux with this patch (which, I'm ashamed to
  say, I failed to do before) I get these kinds of errors:
 
  unregister_netdevice: waiting for TAPdevice to become free.
  Usage count = 1
  unregister_netdevice: waiting for TAPdevice to become free.
  Usage count = 1
 
  Perhaps they're unrelated... I'm still investigating.
 
  Would you test attached patch please?
 
 That does look logically correct, so +1 to it regardless, but it does
 not seem to have fixed the issue I'm seeing.
 
 I still haven't produced the smallest possible demo test program.

sorry to jump-in, but there is a side-effect with this
patch, which my tcp and dccp tests (ipv6) are failed.

because newly added function (__ipv6_dev_get_saddr) won't
update a variable 'hiscore' (it swaps with 'score' in some
case), the caller (ipv6_dev_get_saddr) can't fill an
appropriate saddr in the end.

I don't know if this is a good patch but the following diff
makes my test happy.

-- Hajime

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 4ab74d5..c4e9416 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1363,7 +1363,8 @@ static void __ipv6_dev_get_saddr(struct net *net,
 unsigned int prefs,
 const struct in6_addr *saddr,
 struct inet6_dev *idev,
-struct ipv6_saddr_score *scores)
+struct ipv6_saddr_score *scores,
+struct ipv6_saddr_score **in_hiscore)
 {
struct ipv6_saddr_score *score = scores[0], *hiscore = scores[1];
 
@@ -1424,6 +1425,7 @@ static void __ipv6_dev_get_saddr(struct net *net,
in6_ifa_hold(score-ifa);
 
swap(hiscore, score);
+   *in_hiscore = hiscore;
 
/* restore our iterator */
score-ifa = hiscore-ifa;
@@ -1480,13 +1482,15 @@ int ipv6_dev_get_saddr(struct net *net, const struct 
net_device *dst_dev,
}
 
if (use_oif_addr) {
-   __ipv6_dev_get_saddr(net, dst, prefs, saddr, idev, scores);
+   __ipv6_dev_get_saddr(net, dst, prefs, saddr, idev,
+scores, hiscore);
} else {
for_each_netdev_rcu(net, dev) {
idev = __in6_dev_get(dev);
if (!idev)
continue;
-   __ipv6_dev_get_saddr(net, dst, prefs, saddr, idev, 
scores);
+   __ipv6_dev_get_saddr(net, dst, prefs, saddr, idev,
+scores, hiscore);
}
}
rcu_read_unlock();
--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH net-next v2] ipv6: Do not iterate over all interfaces when finding source address on specific interface.

2015-07-13 Thread YOSHIFUJI Hideaki
Hi,

Hajime Tazaki wrote:
 
 Yoshifuji-san,
 
 At Mon, 13 Jul 2015 17:38:48 +0900,
 Erik Kline wrote:

 On 13 July 2015 at 15:32, YOSHIFUJI Hideaki
 hideaki.yoshif...@miraclelinux.com wrote:
 Hi,

 Erik Kline wrote:
 Hmm, when I run a UML linux with this patch (which, I'm ashamed to
 say, I failed to do before) I get these kinds of errors:

 unregister_netdevice: waiting for TAPdevice to become free.
 Usage count = 1
 unregister_netdevice: waiting for TAPdevice to become free.
 Usage count = 1

 Perhaps they're unrelated... I'm still investigating.

 Would you test attached patch please?

 That does look logically correct, so +1 to it regardless, but it does
 not seem to have fixed the issue I'm seeing.

 I still haven't produced the smallest possible demo test program.
 
 sorry to jump-in, but there is a side-effect with this
 patch, which my tcp and dccp tests (ipv6) are failed.
 
 because newly added function (__ipv6_dev_get_saddr) won't
 update a variable 'hiscore' (it swaps with 'score' in some
 case), the caller (ipv6_dev_get_saddr) can't fill an
 appropriate saddr in the end.
 
 I don't know if this is a good patch but the following diff
 makes my test happy.

We should update score as well...

 
 -- Hajime
 
 diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
 index 4ab74d5..c4e9416 100644
 --- a/net/ipv6/addrconf.c
 +++ b/net/ipv6/addrconf.c
 @@ -1363,7 +1363,8 @@ static void __ipv6_dev_get_saddr(struct net *net,
unsigned int prefs,
const struct in6_addr *saddr,
struct inet6_dev *idev,
 -  struct ipv6_saddr_score *scores)
 +  struct ipv6_saddr_score *scores,
 +  struct ipv6_saddr_score **in_hiscore)
  {
   struct ipv6_saddr_score *score = scores[0], *hiscore = scores[1];
  
 @@ -1424,6 +1425,7 @@ static void __ipv6_dev_get_saddr(struct net *net,
   in6_ifa_hold(score-ifa);
  
   swap(hiscore, score);
 + *in_hiscore = hiscore;
  
   /* restore our iterator */
   score-ifa = hiscore-ifa;
 @@ -1480,13 +1482,15 @@ int ipv6_dev_get_saddr(struct net *net, const struct 
 net_device *dst_dev,
   }
  
   if (use_oif_addr) {
 - __ipv6_dev_get_saddr(net, dst, prefs, saddr, idev, scores);
 + __ipv6_dev_get_saddr(net, dst, prefs, saddr, idev,
 +  scores, hiscore);
   } else {
   for_each_netdev_rcu(net, dev) {
   idev = __in6_dev_get(dev);
   if (!idev)
   continue;
 - __ipv6_dev_get_saddr(net, dst, prefs, saddr, idev, 
 scores);
 + __ipv6_dev_get_saddr(net, dst, prefs, saddr, idev,
 +  scores, hiscore);
   }
   }
   rcu_read_unlock();
 

-- 
Hideaki Yoshifuji hideaki.yoshif...@miraclelinux.com
Technical Division, MIRACLE LINUX CORPORATION
--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH net-next v2] ipv6: Do not iterate over all interfaces when finding source address on specific interface.

2015-07-13 Thread YOSHIFUJI Hideaki
Hi,

Erik Kline wrote:
 Hmm, when I run a UML linux with this patch (which, I'm ashamed to
 say, I failed to do before) I get these kinds of errors:
 
 unregister_netdevice: waiting for TAPdevice to become free.
 Usage count = 1
 unregister_netdevice: waiting for TAPdevice to become free.
 Usage count = 1
 
 Perhaps they're unrelated... I'm still investigating.

Would you test attached patch please?

--yoshfuji

 
 On 11 July 2015 at 15:19, David Miller da...@davemloft.net wrote:
 From: YOSHIFUJI Hideaki/吉藤英明 hideaki.yoshif...@miraclelinux.com
 Date: Fri, 10 Jul 2015 16:58:31 +0900

 If outgoing interface is specified and the candidate address is
 restricted to the outgoing interface, it is enough to iterate
 over that given interface only.

 Signed-off-by: YOSHIFUJI Hideaki hideaki.yoshif...@miraclelinux.com
 Acked-by: Erik Kline e...@google.com

 Applied, thanks!

-- 
Hideaki Yoshifuji hideaki.yoshif...@miraclelinux.com
Technical Division, MIRACLE LINUX CORPORATION
From 38c5a10a5876ea47766ffc05b5a131a210d6e1aa Mon Sep 17 00:00:00 2001
From: YOSHIFUJI Hideaki hideaki.yoshif...@miraclelinux.com
Date: Mon, 13 Jul 2015 15:23:02 +0900
Subject: [PATCH] ipv6: Avoid NULL pointer dereference in
 __ipv6_dev_get_saddr().

Commit 9131f3de2 (ipv6: Do not iterate over all interfaces when
finding source address on specific interface.) introduced
possible NULL pointer dereference if outgoing device is
specified.

Fixes: 9131f3de24db4dc12199aede7d931e6703e97f3b (ipv6: Do not
	iterate over all interfaces when finding source address
	on specific interface.)
Signed-off-by: YOSHIFUJI Hideaki hideaki.yoshif...@miraclelinux.com
---
 net/ipv6/addrconf.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 4ab74d5..50ad476 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1480,7 +1480,8 @@ int ipv6_dev_get_saddr(struct net *net, const struct net_device *dst_dev,
 	}
 
 	if (use_oif_addr) {
-		__ipv6_dev_get_saddr(net, dst, prefs, saddr, idev, scores);
+		if (idev)
+			__ipv6_dev_get_saddr(net, dst, prefs, saddr, idev, scores);
 	} else {
 		for_each_netdev_rcu(net, dev) {
 			idev = __in6_dev_get(dev);
-- 
1.9.1



Re: [PATCH net-next v2] ipv6: Do not iterate over all interfaces when finding source address on specific interface.

2015-07-11 Thread David Miller
From: YOSHIFUJI Hideaki/吉藤英明 hideaki.yoshif...@miraclelinux.com
Date: Fri, 10 Jul 2015 16:58:31 +0900

 If outgoing interface is specified and the candidate address is
 restricted to the outgoing interface, it is enough to iterate
 over that given interface only.
 
 Signed-off-by: YOSHIFUJI Hideaki hideaki.yoshif...@miraclelinux.com
 Acked-by: Erik Kline e...@google.com

Applied, thanks!
--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH net-next v2] ipv6: Do not iterate over all interfaces when finding source address on specific interface.

2015-07-11 Thread Erik Kline
Hmm, when I run a UML linux with this patch (which, I'm ashamed to
say, I failed to do before) I get these kinds of errors:

unregister_netdevice: waiting for TAPdevice to become free.
Usage count = 1
unregister_netdevice: waiting for TAPdevice to become free.
Usage count = 1

Perhaps they're unrelated... I'm still investigating.

On 11 July 2015 at 15:19, David Miller da...@davemloft.net wrote:
 From: YOSHIFUJI Hideaki/吉藤英明 hideaki.yoshif...@miraclelinux.com
 Date: Fri, 10 Jul 2015 16:58:31 +0900

 If outgoing interface is specified and the candidate address is
 restricted to the outgoing interface, it is enough to iterate
 over that given interface only.

 Signed-off-by: YOSHIFUJI Hideaki hideaki.yoshif...@miraclelinux.com
 Acked-by: Erik Kline e...@google.com

 Applied, thanks!
--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-next v2] ipv6: Do not iterate over all interfaces when finding source address on specific interface.

2015-07-10 Thread YOSHIFUJI Hideaki/吉藤英明
If outgoing interface is specified and the candidate address is
restricted to the outgoing interface, it is enough to iterate
over that given interface only.

Signed-off-by: YOSHIFUJI Hideaki hideaki.yoshif...@miraclelinux.com
Acked-by: Erik Kline e...@google.com
---
 net/ipv6/addrconf.c | 197 
 1 file changed, 107 insertions(+), 90 deletions(-)

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 21c2c81..4ab74d5 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1358,15 +1358,94 @@ out:
return ret;
 }
 
+static void __ipv6_dev_get_saddr(struct net *net,
+struct ipv6_saddr_dst *dst,
+unsigned int prefs,
+const struct in6_addr *saddr,
+struct inet6_dev *idev,
+struct ipv6_saddr_score *scores)
+{
+   struct ipv6_saddr_score *score = scores[0], *hiscore = scores[1];
+
+   read_lock_bh(idev-lock);
+   list_for_each_entry(score-ifa, idev-addr_list, if_list) {
+   int i;
+
+   /*
+* - Tentative Address (RFC2462 section 5.4)
+*  - A tentative address is not considered
+*assigned to an interface in the traditional
+*sense, unless it is also flagged as optimistic.
+* - Candidate Source Address (section 4)
+*  - In any case, anycast addresses, multicast
+*addresses, and the unspecified address MUST
+*NOT be included in a candidate set.
+*/
+   if ((score-ifa-flags  IFA_F_TENTATIVE) 
+   (!(score-ifa-flags  IFA_F_OPTIMISTIC)))
+   continue;
+
+   score-addr_type = __ipv6_addr_type(score-ifa-addr);
+
+   if (unlikely(score-addr_type == IPV6_ADDR_ANY ||
+score-addr_type  IPV6_ADDR_MULTICAST)) {
+   net_dbg_ratelimited(ADDRCONF: unspecified / multicast 
address assigned as unicast address on %s,
+   idev-dev-name);
+   continue;
+   }
+
+   score-rule = -1;
+   bitmap_zero(score-scorebits, IPV6_SADDR_RULE_MAX);
+
+   for (i = 0; i  IPV6_SADDR_RULE_MAX; i++) {
+   int minihiscore, miniscore;
+
+   minihiscore = ipv6_get_saddr_eval(net, hiscore, dst, i);
+   miniscore = ipv6_get_saddr_eval(net, score, dst, i);
+
+   if (minihiscore  miniscore) {
+   if (i == IPV6_SADDR_RULE_SCOPE 
+   score-scopedist  0) {
+   /*
+* special case:
+* each remaining entry
+* has too small (not enough)
+* scope, because ifa entries
+* are sorted by their scope
+* values.
+*/
+   goto out;
+   }
+   break;
+   } else if (minihiscore  miniscore) {
+   if (hiscore-ifa)
+   in6_ifa_put(hiscore-ifa);
+
+   in6_ifa_hold(score-ifa);
+
+   swap(hiscore, score);
+
+   /* restore our iterator */
+   score-ifa = hiscore-ifa;
+
+   break;
+   }
+   }
+   }
+out:
+   read_unlock_bh(idev-lock);
+}
+
 int ipv6_dev_get_saddr(struct net *net, const struct net_device *dst_dev,
   const struct in6_addr *daddr, unsigned int prefs,
   struct in6_addr *saddr)
 {
-   struct ipv6_saddr_score scores[2],
-   *score = scores[0], *hiscore = scores[1];
+   struct ipv6_saddr_score scores[2], *hiscore = scores[1];
struct ipv6_saddr_dst dst;
+   struct inet6_dev *idev;
struct net_device *dev;
int dst_type;
+   bool use_oif_addr = false;
 
dst_type = __ipv6_addr_type(daddr);
dst.addr = daddr;
@@ -1380,97 +1459,35 @@ int ipv6_dev_get_saddr(struct net *net, const struct 
net_device *dst_dev,
 
rcu_read_lock();
 
-   for_each_netdev_rcu(net, dev) {
-   struct inet6_dev *idev;
-
-   /* Candidate Source Address (section 4)
-*  - multicast and link-local destination address,
-*the set of candidate source address MUST only
-