netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: dlezcano@fr.ibm.com
To: containers@lists.osdl.org
Cc: netdev@vger.kernel.org
Subject: [patch 07/12] net namespace: set source addresse
Date: Fri, 19 Jan 2007 16:47:21 +0100	[thread overview]
Message-ID: <20070119155358.002872544@localhost.localdomain> (raw)
In-Reply-To: 20070119154714.439706567@localhost.localdomain

[-- Attachment #1: net-namespace-l3-set-source-address.patch --]
[-- Type: text/plain, Size: 5056 bytes --]

From: Daniel Lezcano <dlezcano@fr.ibm.com>

When no source address is specified, search from the dev list the
ifaddr allowed to be used as source address.

Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>

---
 include/linux/net_namespace.h |   14 ++++++++
 net/core/net_namespace.c      |   68 ++++++++++++++++++++++++++++++++++++++++++
 net/ipv4/route.c              |   28 +++++++++++------
 3 files changed, 100 insertions(+), 10 deletions(-)

Index: 2.6.20-rc4-mm1/net/ipv4/route.c
===================================================================
--- 2.6.20-rc4-mm1.orig/net/ipv4/route.c
+++ 2.6.20-rc4-mm1/net/ipv4/route.c
@@ -2475,17 +2475,17 @@
 
 		if (LOCAL_MCAST(oldflp->fl4_dst) || oldflp->fl4_dst == htonl(0xFFFFFFFF)) {
 			if (!fl.fl4_src)
-				fl.fl4_src = inet_select_addr(dev_out, 0,
-							      RT_SCOPE_LINK);
+				fl.fl4_src = SELECT_SRC_ADDR(dev_out, 0,
+							     RT_SCOPE_LINK);
 			goto make_route;
 		}
 		if (!fl.fl4_src) {
 			if (MULTICAST(oldflp->fl4_dst))
-				fl.fl4_src = inet_select_addr(dev_out, 0,
-							      fl.fl4_scope);
+				fl.fl4_src = SELECT_SRC_ADDR(dev_out, 0,
+							     fl.fl4_scope);
 			else if (!oldflp->fl4_dst)
-				fl.fl4_src = inet_select_addr(dev_out, 0,
-							      RT_SCOPE_HOST);
+				fl.fl4_src = SELECT_SRC_ADDR(dev_out, 0,
+							     RT_SCOPE_HOST);
 		}
 	}
 
@@ -2525,8 +2525,8 @@
 			 */
 
 			if (fl.fl4_src == 0)
-				fl.fl4_src = inet_select_addr(dev_out, 0,
-							      RT_SCOPE_LINK);
+				fl.fl4_src = SELECT_SRC_ADDR(dev_out, 0,
+							     RT_SCOPE_LINK);
 			res.type = RTN_UNICAST;
 			goto make_route;
 		}
@@ -2539,7 +2539,13 @@
 
 	if (res.type == RTN_LOCAL) {
 		if (!fl.fl4_src)
+#ifdef CONFIG_NET_NS
+			fl.fl4_src = net_ns_select_source_address(dev_out,
+								  fl.fl4_dst,
+								  RT_SCOPE_LINK);
+#else
 			fl.fl4_src = fl.fl4_dst;
+#endif
 		if (dev_out)
 			dev_put(dev_out);
 		dev_out = &loopback_dev;
@@ -2561,8 +2567,10 @@
 		fib_select_default(&fl, &res);
 
 	if (!fl.fl4_src)
-		fl.fl4_src = FIB_RES_PREFSRC(res);
-
+		fl.fl4_src = res.fi->fib_prefsrc ? :
+			SELECT_SRC_ADDR(FIB_RES_DEV(res),
+					FIB_RES_GW(res),
+					res.scope);
 	if (dev_out)
 		dev_put(dev_out);
 	dev_out = FIB_RES_DEV(res);
Index: 2.6.20-rc4-mm1/include/linux/net_namespace.h
===================================================================
--- 2.6.20-rc4-mm1.orig/include/linux/net_namespace.h
+++ 2.6.20-rc4-mm1/include/linux/net_namespace.h
@@ -5,6 +5,7 @@
 #include <linux/kref.h>
 #include <linux/nsproxy.h>
 #include <linux/errno.h>
+#include <linux/types.h>
 
 struct net_namespace {
 	struct kref		kref;
@@ -95,6 +96,11 @@
 
 extern int net_ns_check_bind(int addr_type, u32 addr);
 
+extern __be32 net_ns_select_source_address(const struct net_device *dev,
+					   u32 dst, int scope);
+
+#define SELECT_SRC_ADDR net_ns_select_source_address
+
 #else /* CONFIG_NET_NS */
 
 #define INIT_NET_NS(net_ns)
@@ -155,6 +161,14 @@
 	return 0;
 }
 
+static inline __be32 net_ns_select_source_address(struct net_device *dev,
+						  u32 dst, int scope)
+{
+	return 0;
+}
+
+#define SELECT_SRC_ADDR inet_select_addr
+
 #endif /* !CONFIG_NET_NS */
 
 #endif /* _LINUX_NET_NAMESPACE_H */
Index: 2.6.20-rc4-mm1/net/core/net_namespace.c
===================================================================
--- 2.6.20-rc4-mm1.orig/net/core/net_namespace.c
+++ 2.6.20-rc4-mm1/net/core/net_namespace.c
@@ -317,4 +317,72 @@
 	return ret;
 }
 
+/*
+ * This function choose the source address from the network device,
+ * destination and the scope. The function will browse the ifaddr
+ * owned by network namespace and choose the most adapted for the
+ * dst address and dev.
+ * @dev : the network device where the traffic will go
+ * @dst : the destination address
+ * @scope : the scope of the dst address
+ * Returns: a source address
+ */
+__be32 net_ns_select_source_address(const struct net_device *dev,
+				    u32 dst, int scope)
+{
+	__be32 addr = 0;
+	struct in_device *in_dev;
+	struct net_namespace *net_ns = current_net_ns;
+
+	if (LOOPBACK(dst))
+	    return htonl(INADDR_LOOPBACK);
+
+	if (!dev)
+		goto no_dev;
+
+	rcu_read_lock();
+	in_dev = __in_dev_get_rcu(dev);
+	if (!in_dev)
+		goto no_in_dev;
+
+	for_ifa(in_dev) {
+		if (ifa->ifa_scope > scope)
+			continue;
+		if (ifa->ifa_net_ns != net_ns)
+			continue;
+		if (!dst || inet_ifa_match(dst, ifa)) {
+			addr = ifa->ifa_local;
+			break;
+		}
+		if (!addr)
+			addr = ifa->ifa_local;
+	} endfor_ifa(in_dev);
+no_in_dev:
+	rcu_read_unlock();
+
+	if (addr)
+		goto out;
+
+no_dev:
+	read_lock(&dev_base_lock);
+	rcu_read_lock();
+	for (dev = dev_base; dev; dev = dev->next) {
+		if ((in_dev = __in_dev_get_rcu(dev)) == NULL)
+			continue;
+
+		for_ifa(in_dev) {
+			if (ifa->ifa_scope != RT_SCOPE_LINK &&
+			    ifa->ifa_scope <= scope &&
+			    ifa->ifa_net_ns == net_ns) {
+				addr = ifa->ifa_local;
+				goto out_unlock_both;
+			}
+		} endfor_ifa(in_dev);
+	}
+out_unlock_both:
+	read_unlock(&dev_base_lock);
+	rcu_read_unlock();
+out:
+	return addr;
+}
 #endif /* CONFIG_NET_NS */

-- 

  parent reply	other threads:[~2007-01-19 16:40 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-01-19 15:47 [patch 00/12] net namespace : L3 namespace - introduction dlezcano
2007-01-19 15:47 ` [patch 01/12] net namespace : initialize init process to level 2 dlezcano
2007-01-19 15:47 ` [patch 02/12] net namespace : store L2 parent namespace dlezcano
2007-01-19 15:47 ` [patch 03/12] net namespace : share network ressources L2 with L3 dlezcano
2007-01-19 15:47 ` [patch 04/12] net namespace : isolate the inet device dlezcano
2007-01-19 15:47 ` [patch 05/12] net namespace : ioctl to push ifa to net namespace l3 dlezcano
2007-01-20  4:52   ` Herbert Poetzl
2007-01-20 11:48     ` Daniel Lezcano
2007-01-19 15:47 ` [patch 06/12] net namespace : check bind address dlezcano
2007-01-19 15:47 ` dlezcano [this message]
2007-01-19 15:47 ` [patch 08/12] net namespace : find namespace by addr dlezcano
2007-01-20  4:56   ` Herbert Poetzl
2007-01-19 15:47 ` [patch 09/12] net namespace : make loopback address always visible dlezcano
2007-01-19 15:47 ` [patch 10/12] net namespace : add the loopback isolation dlezcano
2007-01-19 15:47 ` [patch 11/12] net namespace : debugfs - add net_ns debugfs dlezcano
2007-01-19 15:47 ` [patch 12/12] net namespace : Add broadcasting dlezcano
2007-01-20  4:58   ` Herbert Poetzl
2007-01-20 11:54     ` Daniel Lezcano
2007-01-20  4:48 ` [patch 00/12] net namespace : L3 namespace - introduction Herbert Poetzl
2007-01-20 11:42   ` Daniel Lezcano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20070119155358.002872544@localhost.localdomain \
    --to=dlezcano@fr.ibm.com \
    --cc=containers@lists.osdl.org \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).