Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2774c7ab authored by Eric W. Biederman's avatar Eric W. Biederman Committed by David S. Miller
Browse files

[NET]: Make the loopback device per network namespace.



This patch makes loopback_dev per network namespace.  Adding
code to create a different loopback device for each network
namespace and adding the code to free a loopback device
when a network namespace exits.

This patch modifies all users the loopback_dev so they
access it as init_net.loopback_dev, keeping all of the
code compiling and working.  A later pass will be needed to
update the users to use something other than the initial network
namespace.

Signed-off-by: default avatarEric W. Biederman <ebiederm@xmission.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 0cc217e1
Loading
Loading
Loading
Loading
+21 −5
Original line number Diff line number Diff line
@@ -57,6 +57,7 @@
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/percpu.h>
#include <net/net_namespace.h>

struct pcpu_lstats {
	unsigned long packets;
@@ -252,7 +253,7 @@ static void loopback_setup(struct net_device *dev)
}

/* Setup and register the loopback device. */
static int __init loopback_init(void)
static int loopback_net_init(struct net *net)
{
	struct net_device *dev;
	int err;
@@ -262,12 +263,13 @@ static int __init loopback_init(void)
	if (!dev)
		goto out;

	dev->nd_net = net;
	err = register_netdev(dev);
	if (err)
		goto out_free_netdev;

	err = 0;
	loopback_dev = dev;
	net->loopback_dev = dev;

out:
	if (err)
@@ -279,7 +281,21 @@ out_free_netdev:
	goto out;
}

fs_initcall(loopback_init);
static void loopback_net_exit(struct net *net)
{
	struct net_device *dev = net->loopback_dev;

	unregister_netdev(dev);
}

static struct pernet_operations loopback_net_ops = {
       .init = loopback_net_init,
       .exit = loopback_net_exit,
};

static int __init loopback_init(void)
{
	return register_pernet_device(&loopback_net_ops);
}

struct net_device *loopback_dev;
EXPORT_SYMBOL(loopback_dev);
fs_initcall(loopback_init);
+0 −1
Original line number Diff line number Diff line
@@ -742,7 +742,6 @@ struct packet_type {
#include <linux/interrupt.h>
#include <linux/notifier.h>

extern struct net_device		*loopback_dev;		/* The loopback */
extern rwlock_t				dev_base_lock;		/* Device list lock */


+3 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
#include <linux/list.h>

struct proc_dir_entry;
struct net_device;
struct net {
	atomic_t		count;		/* To decided when the network
						 *  namespace should be freed.
@@ -23,6 +24,8 @@ struct net {
	struct proc_dir_entry 	*proc_net_stat;
	struct proc_dir_entry 	*proc_net_root;

	struct net_device       *loopback_dev;          /* The loopback */

	struct list_head 	dev_base_head;
	struct hlist_head 	*dev_name_head;
	struct hlist_head	*dev_index_head;
+3 −2
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include <linux/types.h>
#include <net/net_namespace.h>

#include <net/net_namespace.h>
#include <net/dst.h>

/*
@@ -278,11 +279,11 @@ static inline void dst_ifdown(struct dst_entry *dst, struct net_device *dev,
	if (!unregister) {
		dst->input = dst->output = dst_discard;
	} else {
		dst->dev = loopback_dev;
		dst->dev = init_net.loopback_dev;
		dev_hold(dst->dev);
		dev_put(dev);
		if (dst->neighbour && dst->neighbour->dev == dev) {
			dst->neighbour->dev = loopback_dev;
			dst->neighbour->dev = init_net.loopback_dev;
			dev_put(dev);
			dev_hold(dst->neighbour->dev);
		}
+2 −2
Original line number Diff line number Diff line
@@ -869,10 +869,10 @@ last_chance:
		rv = dn_dev_get_first(dev, addr);
		read_unlock(&dev_base_lock);
		dev_put(dev);
		if (rv == 0 || dev == loopback_dev)
		if (rv == 0 || dev == init_net.loopback_dev)
			return rv;
	}
	dev = loopback_dev;
	dev = init_net.loopback_dev;
	dev_hold(dev);
	goto last_chance;
}
Loading