[RFC PATCH 3/4] net: can: move shared data into net namespace

From: Andri Yngvason <hidden>
Date: 2015-09-27 18:22:56
Subsystem: can network layer, networking [general], the rest · Maintainers: Oliver Hartkopp, Marc Kleine-Budde, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds

---
 include/linux/can/core.h    |   4 +-
 include/net/af_can.h        |  27 ++--
 include/net/net_namespace.h |   4 +
 include/net/netns/can.h     |  20 +++
 net/can/af_can.c            | 141 ++++++++++++---------
 net/can/bcm.c               |  29 +++--
 net/can/gw.c                |  11 +-
 net/can/proc.c              | 295 ++++++++++++++++++++++++--------------------
 net/can/raw.c               |  31 +++--
 9 files changed, 330 insertions(+), 232 deletions(-)
 create mode 100644 include/net/netns/can.h
diff --git a/include/linux/can/core.h b/include/linux/can/core.h
index a087500..276d7b6 100644
--- a/include/linux/can/core.h
+++ b/include/linux/can/core.h
@@ -48,12 +48,12 @@ extern void can_proto_unregister(const struct can_proto *cp);
 extern int  can_rx_register(struct net_device *dev, canid_t can_id,
 			    canid_t mask,
 			    void (*func)(struct sk_buff *, void *),
-			    void *data, char *ident);
+			    void *data, char *ident, struct net *net);
 
 extern void can_rx_unregister(struct net_device *dev, canid_t can_id,
 			      canid_t mask,
 			      void (*func)(struct sk_buff *, void *),
-			      void *data);
+			      void *data, struct net *net);
 
 extern int can_send(struct sk_buff *skb, int loop);
 extern int can_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
diff --git a/include/net/af_can.h b/include/net/af_can.h
index d9e8952..b3e1ecc 100644
--- a/include/net/af_can.h
+++ b/include/net/af_can.h
@@ -41,7 +41,7 @@
 #define __LINUX_NET_AF_CAN_H__
 
 #include <linux/skbuff.h>
-#include <linux/netdevice.h>
+#include <net/net_namespace.h>
 #include <linux/list.h>
 #include <linux/rcupdate.h>
 #include <linux/can.h>
@@ -109,18 +109,23 @@ struct can_pstats {
 	unsigned long rcv_entries_max;
 };
 
-/* receive filters subscribed for 'all' CAN devices */
-extern struct can_dev_rcv_lists can_rx_alldev_list;
+struct can_proc {
+	struct proc_dir_entry *can_dir;
+	struct proc_dir_entry *version;
+	struct proc_dir_entry *stats;
+	struct proc_dir_entry *reset_stats;
+	struct proc_dir_entry *rcvlist_all;
+	struct proc_dir_entry *rcvlist_fil;
+	struct proc_dir_entry *rcvlist_inv;
+	struct proc_dir_entry *rcvlist_sff;
+	struct proc_dir_entry *rcvlist_eff;
+	struct proc_dir_entry *rcvlist_err;
+	int                    user_reset;
+};
 
 /* function prototypes for the CAN networklayer procfs (proc.c) */
-void can_init_proc(void);
-void can_remove_proc(void);
+void can_init_proc(struct net* net);
+void can_remove_proc(struct net* net);
 void can_stat_update(unsigned long data);
 
-/* structures and variables from af_can.c needed in proc.c for reading */
-extern struct timer_list can_stattimer;    /* timer for statistics update */
-extern struct can_stats  can_stats;        /* packet statistics */
-extern struct can_pstats can_pstats;       /* receive list statistics */
-extern struct hlist_head can_rx_dev_list;  /* rx dispatcher structures */
-
 #endif /* __LINUX_NET_AF_CAN_H__ */
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index 2dcea63..2218eec 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -27,6 +27,7 @@
 #include <net/netns/nftables.h>
 #include <net/netns/xfrm.h>
 #include <net/netns/mpls.h>
+#include <net/netns/can.h>
 #include <linux/ns_common.h>
 #include <linux/idr.h>
 #include <linux/skbuff.h>
@@ -137,6 +138,9 @@ struct net {
 #if IS_ENABLED(CONFIG_MPLS)
 	struct netns_mpls	mpls;
 #endif
+#if IS_ENABLED(CONFIG_CAN)
+	struct netns_can        can;
+#endif
 	struct sock		*diag_nlsk;
 	atomic_t		fnhe_genid;
 };
diff --git a/include/net/netns/can.h b/include/net/netns/can.h
new file mode 100644
index 0000000..2037f2b
--- /dev/null
+++ b/include/net/netns/can.h
@@ -0,0 +1,20 @@
+/*
+ * CAN network namespace
+ */
+#ifndef __NETNS_CAN_H__
+#define __NETNS_CAN_H__
+
+#include <linux/timer.h>
+#include <net/af_can.h>
+#include <linux/proc_fs.h>
+
+struct netns_can {
+	struct timer_list        can_stattimer;
+	struct can_stats         can_stats;
+	struct can_pstats        can_pstats;
+	struct hlist_head        can_rx_dev_list;
+	struct can_proc          can_proc;
+	struct can_dev_rcv_lists can_rx_alldev_list;
+};
+
+#endif /* __NETNS_CAN_H__ */
diff --git a/net/can/af_can.c b/net/can/af_can.c
index 73f1cb8..aaeb93a 100644
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -76,7 +76,6 @@ module_param(stats_timer, int, S_IRUGO);
 MODULE_PARM_DESC(stats_timer, "enable timer for statistics (default:on)");
 
 /* receive filters subscribed for 'all' CAN devices */
-struct can_dev_rcv_lists can_rx_alldev_list;
 static DEFINE_SPINLOCK(can_rcvlists_lock);
 
 static struct kmem_cache *rcv_cache __read_mostly;
@@ -85,10 +84,6 @@ static struct kmem_cache *rcv_cache __read_mostly;
 static const struct can_proto *proto_tab[CAN_NPROTO] __read_mostly;
 static DEFINE_MUTEX(proto_tab_lock);
 
-struct timer_list can_stattimer;   /* timer for statistics update */
-struct can_stats  can_stats;       /* packet statistics */
-struct can_pstats can_pstats;      /* receive list statistics */
-
 static atomic_t skbcounter = ATOMIC_INIT(0);
 
 /*
@@ -226,6 +221,7 @@ static int can_create(struct net *net, struct socket *sock, int protocol,
  */
 int can_send(struct sk_buff *skb, int loop)
 {
+	struct net* net = sock_net(skb->sk);
 	struct sk_buff *newskb = NULL;
 	struct canfd_frame *cfd = (struct canfd_frame *)skb->data;
 	int err = -EINVAL;
@@ -316,8 +312,8 @@ int can_send(struct sk_buff *skb, int loop)
 		netif_rx_ni(newskb);
 
 	/* update statistics */
-	can_stats.tx_frames++;
-	can_stats.tx_frames_delta++;
+	net->can.can_stats.tx_frames++;
+	net->can.can_stats.tx_frames_delta++;
 
 	return 0;
 
@@ -331,10 +327,11 @@ EXPORT_SYMBOL(can_send);
  * af_can rx path
  */
 
-static struct can_dev_rcv_lists *find_dev_rcv_lists(struct net_device *dev)
+static struct can_dev_rcv_lists *find_dev_rcv_lists(struct net_device *dev,
+						    struct net* net)
 {
 	if (!dev)
-		return &can_rx_alldev_list;
+		return &net->can.can_rx_alldev_list;
 	else
 		return (struct can_dev_rcv_lists *)dev->ml_priv;
 }
@@ -468,7 +465,7 @@ static struct hlist_head *find_rcv_list(canid_t *can_id, canid_t *mask,
  */
 int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask,
 		    void (*func)(struct sk_buff *, void *), void *data,
-		    char *ident)
+		    char *ident, struct net *net)
 {
 	struct can_receiver *r;
 	struct hlist_head *rl;
@@ -486,7 +483,7 @@ int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask,
 
 	spin_lock(&can_rcvlists_lock);
 
-	d = find_dev_rcv_lists(dev);
+	d = find_dev_rcv_lists(dev, net);
 	if (d) {
 		rl = find_rcv_list(&can_id, &mask, d);
 
@@ -500,9 +497,9 @@ int can_rx_register(struct net_device *dev, canid_t can_id, canid_t mask,
 		hlist_add_head_rcu(&r->list, rl);
 		d->entries++;
 
-		can_pstats.rcv_entries++;
-		if (can_pstats.rcv_entries_max < can_pstats.rcv_entries)
-			can_pstats.rcv_entries_max = can_pstats.rcv_entries;
+		net->can.can_pstats.rcv_entries++;
+		if (net->can.can_pstats.rcv_entries_max < net->can.can_pstats.rcv_entries)
+			net->can.can_pstats.rcv_entries_max = net->can.can_pstats.rcv_entries;
 	} else {
 		kmem_cache_free(rcv_cache, r);
 		err = -ENODEV;
@@ -536,7 +533,8 @@ static void can_rx_delete_receiver(struct rcu_head *rp)
  *  Removes subscription entry depending on given (subscription) values.
  */
 void can_rx_unregister(struct net_device *dev, canid_t can_id, canid_t mask,
-		       void (*func)(struct sk_buff *, void *), void *data)
+		       void (*func)(struct sk_buff *, void *), void *data,
+		       struct net *net)
 {
 	struct can_receiver *r = NULL;
 	struct hlist_head *rl;
@@ -547,7 +545,7 @@ void can_rx_unregister(struct net_device *dev, canid_t can_id, canid_t mask,
 
 	spin_lock(&can_rcvlists_lock);
 
-	d = find_dev_rcv_lists(dev);
+	d = find_dev_rcv_lists(dev, net);
 	if (!d) {
 		pr_err("BUG: receive list not found for "
 		       "dev %s, id %03X, mask %03X\n",
@@ -583,8 +581,8 @@ void can_rx_unregister(struct net_device *dev, canid_t can_id, canid_t mask,
 	hlist_del_rcu(&r->list);
 	d->entries--;
 
-	if (can_pstats.rcv_entries > 0)
-		can_pstats.rcv_entries--;
+	if (net->can.can_pstats.rcv_entries > 0)
+		net->can.can_pstats.rcv_entries--;
 
 	/* remove device structure requested by NETDEV_UNREGISTER */
 	if (d->remove_on_zero_entries && !d->entries) {
@@ -674,12 +672,13 @@ static int can_rcv_filter(struct can_dev_rcv_lists *d, struct sk_buff *skb)
 
 static void can_receive(struct sk_buff *skb, struct net_device *dev)
 {
+	struct net *net = dev_net(dev);
 	struct can_dev_rcv_lists *d;
 	int matches;
 
 	/* update statistics */
-	can_stats.rx_frames++;
-	can_stats.rx_frames_delta++;
+	net->can.can_stats.rx_frames++;
+	net->can.can_stats.rx_frames_delta++;
 
 	/* create non-zero unique skb identifier together with *skb */
 	while (!(can_skb_prv(skb)->skbcnt))
@@ -688,10 +687,10 @@ static void can_receive(struct sk_buff *skb, struct net_device *dev)
 	rcu_read_lock();
 
 	/* deliver the packet to sockets listening on all devices */
-	matches = can_rcv_filter(&can_rx_alldev_list, skb);
+	matches = can_rcv_filter(&net->can.can_rx_alldev_list, skb);
 
 	/* find receive list for this device */
-	d = find_dev_rcv_lists(dev);
+	d = find_dev_rcv_lists(dev, net);
 	if (d)
 		matches += can_rcv_filter(d, skb);
 
@@ -701,8 +700,8 @@ static void can_receive(struct sk_buff *skb, struct net_device *dev)
 	consume_skb(skb);
 
 	if (matches > 0) {
-		can_stats.matches++;
-		can_stats.matches_delta++;
+		net->can.can_stats.matches++;
+		net->can.can_stats.matches_delta++;
 	}
 }
 
@@ -894,8 +893,58 @@ static struct notifier_block can_netdev_notifier __read_mostly = {
 	.notifier_call = can_notifier,
 };
 
-static __init int can_init(void)
+static __net_init int can_init_net(struct net *net)
+{
+	memset(&net->can.can_rx_alldev_list, 0,
+	       sizeof(net->can.can_rx_alldev_list));
+
+	if (stats_timer) {
+		/* the statistics are updated every second (timer triggered) */
+		setup_timer(&net->can.can_stattimer, can_stat_update,
+			    (unsigned long)net);
+		mod_timer(&net->can.can_stattimer, round_jiffies(jiffies + HZ));
+	} else
+		net->can.can_stattimer.function = NULL;
+
+	can_init_proc(net);
+
+	return 0;
+}
+
+static __net_exit void can_exit_net(struct net *net)
 {
+	struct net_device *dev;
+
+	can_remove_proc(net);
+
+	if (stats_timer)
+		del_timer_sync(&net->can.can_stattimer);
+
+	/* remove created dev_rcv_lists from still registered CAN devices */
+	rcu_read_lock();
+	for_each_netdev_rcu(net, dev) {
+		if (dev->type == ARPHRD_CAN && dev->ml_priv) {
+			struct can_dev_rcv_lists *d = dev->ml_priv;
+
+			BUG_ON(d->entries);
+			kfree(d);
+			dev->ml_priv = NULL;
+		}
+	}
+	rcu_read_unlock();
+
+	rcu_barrier(); /* Wait for completion of call_rcu()'s */
+}
+
+static __net_initdata struct pernet_operations can_ops = {
+	.init = can_init_net,
+	.exit = can_exit_net
+};
+
+static int __init can_init(void)
+{
+	int rc;
+
 	/* check for correct padding to be able to use the structs similarly */
 	BUILD_BUG_ON(offsetof(struct can_frame, can_dlc) !=
 		     offsetof(struct canfd_frame, len) ||
@@ -904,21 +953,14 @@ static __init int can_init(void)
 
 	pr_info("can: controller area network core (" CAN_VERSION_STRING ")\n");
 
-	memset(&can_rx_alldev_list, 0, sizeof(can_rx_alldev_list));
-
 	rcv_cache = kmem_cache_create("can_receiver",
 				      sizeof(struct can_receiver), 0, 0, NULL);
 	if (!rcv_cache)
 		return -ENOMEM;
 
-	if (stats_timer) {
-		/* the statistics are updated every second (timer triggered) */
-		setup_timer(&can_stattimer, can_stat_update, 0);
-		mod_timer(&can_stattimer, round_jiffies(jiffies + HZ));
-	} else
-		can_stattimer.function = NULL;
-
-	can_init_proc();
+	rc = register_pernet_subsys(&can_ops);
+	if (rc < 0)
+		goto failure;
 
 	/* protocol register */
 	sock_register(&can_family_ops);
@@ -927,38 +969,21 @@ static __init int can_init(void)
 	dev_add_pack(&canfd_packet);
 
 	return 0;
+
+failure:
+	kmem_cache_destroy(rcv_cache);
+	return rc;
 }
 
-static __exit void can_exit(void)
+static void __exit can_exit(void)
 {
-	struct net_device *dev;
-
-	if (stats_timer)
-		del_timer_sync(&can_stattimer);
-
-	can_remove_proc();
-
 	/* protocol unregister */
 	dev_remove_pack(&canfd_packet);
 	dev_remove_pack(&can_packet);
 	unregister_netdevice_notifier(&can_netdev_notifier);
 	sock_unregister(PF_CAN);
 
-	/* remove created dev_rcv_lists from still registered CAN devices */
-	rcu_read_lock();
-	for_each_netdev_rcu(&init_net, dev) {
-		if (dev->type == ARPHRD_CAN && dev->ml_priv) {
-
-			struct can_dev_rcv_lists *d = dev->ml_priv;
-
-			BUG_ON(d->entries);
-			kfree(d);
-			dev->ml_priv = NULL;
-		}
-	}
-	rcu_read_unlock();
-
-	rcu_barrier(); /* Wait for completion of call_rcu()'s */
+	unregister_pernet_subsys(&can_ops);
 
 	kmem_cache_destroy(rcv_cache);
 }
diff --git a/net/can/bcm.c b/net/can/bcm.c
index a1ba687..2b70715 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -723,11 +723,12 @@ static void bcm_remove_op(struct bcm_op *op)
 	kfree(op);
 }
 
-static void bcm_rx_unreg(struct net_device *dev, struct bcm_op *op)
+static void bcm_rx_unreg(struct net_device *dev, struct bcm_op *op,
+			 struct net* net)
 {
 	if (op->rx_reg_dev == dev) {
 		can_rx_unregister(dev, op->can_id, REGMASK(op->can_id),
-				  bcm_rx_handler, op);
+				  bcm_rx_handler, op, net);
 
 		/* mark as removed subscription */
 		op->rx_reg_dev = NULL;
@@ -739,7 +740,8 @@ static void bcm_rx_unreg(struct net_device *dev, struct bcm_op *op)
 /*
  * bcm_delete_rx_op - find and remove a rx op (returns number of removed ops)
  */
-static int bcm_delete_rx_op(struct list_head *ops, canid_t can_id, int ifindex)
+static int bcm_delete_rx_op(struct list_head *ops, canid_t can_id, int ifindex,
+			    struct net* net)
 {
 	struct bcm_op *op, *n;
 
@@ -763,14 +765,14 @@ static int bcm_delete_rx_op(struct list_head *ops, canid_t can_id, int ifindex)
 					dev = dev_get_by_index(&init_net,
 							       op->ifindex);
 					if (dev) {
-						bcm_rx_unreg(dev, op);
+						bcm_rx_unreg(dev, op, net);
 						dev_put(dev);
 					}
 				}
 			} else
 				can_rx_unregister(NULL, op->can_id,
 						  REGMASK(op->can_id),
-						  bcm_rx_handler, op);
+						  bcm_rx_handler, op, net);
 
 			list_del(&op->list);
 			bcm_remove_op(op);
@@ -986,6 +988,7 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 			int ifindex, struct sock *sk)
 {
 	struct bcm_sock *bo = bcm_sk(sk);
+	struct net *net = sock_net(sk);
 	struct bcm_op *op;
 	int do_rx_register;
 	int err = 0;
@@ -1165,7 +1168,7 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 				err = can_rx_register(dev, op->can_id,
 						      REGMASK(op->can_id),
 						      bcm_rx_handler, op,
-						      "bcm");
+						      "bcm", net);
 
 				op->rx_reg_dev = dev;
 				dev_put(dev);
@@ -1174,7 +1177,7 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 		} else
 			err = can_rx_register(NULL, op->can_id,
 					      REGMASK(op->can_id),
-					      bcm_rx_handler, op, "bcm");
+					      bcm_rx_handler, op, "bcm", net);
 		if (err) {
 			/* this bcm rx op is broken -> remove it */
 			list_del(&op->list);
@@ -1236,6 +1239,7 @@ static int bcm_tx_send(struct msghdr *msg, int ifindex, struct sock *sk)
 static int bcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
 {
 	struct sock *sk = sock->sk;
+	struct net *net = sock_net(sk);
 	struct bcm_sock *bo = bcm_sk(sk);
 	int ifindex = bo->ifindex; /* default ifindex for this bcm_op */
 	struct bcm_msg_head msg_head;
@@ -1305,7 +1309,8 @@ static int bcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
 		break;
 
 	case RX_DELETE:
-		if (bcm_delete_rx_op(&bo->rx_ops, msg_head.can_id, ifindex))
+		if (bcm_delete_rx_op(&bo->rx_ops, msg_head.can_id, ifindex,
+				     net))
 			ret = MHSIZ;
 		else
 			ret = -EINVAL;
@@ -1350,6 +1355,7 @@ static int bcm_notifier(struct notifier_block *nb, unsigned long msg,
 	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
 	struct bcm_sock *bo = container_of(nb, struct bcm_sock, notifier);
 	struct sock *sk = &bo->sk;
+	struct net *net = sock_net(sk);
 	struct bcm_op *op;
 	int notify_enodev = 0;
 
@@ -1367,7 +1373,7 @@ static int bcm_notifier(struct notifier_block *nb, unsigned long msg,
 		/* remove device specific receive entries */
 		list_for_each_entry(op, &bo->rx_ops, list)
 			if (op->rx_reg_dev == dev)
-				bcm_rx_unreg(dev, op);
+				bcm_rx_unreg(dev, op, net);
 
 		/* remove device reference, if this is our bound device */
 		if (bo->bound && bo->ifindex == dev->ifindex) {
@@ -1425,6 +1431,7 @@ static int bcm_init(struct sock *sk)
 static int bcm_release(struct socket *sock)
 {
 	struct sock *sk = sock->sk;
+	struct net *net = sock_net(sk);
 	struct bcm_sock *bo;
 	struct bcm_op *op, *next;
 
@@ -1458,14 +1465,14 @@ static int bcm_release(struct socket *sock)
 
 				dev = dev_get_by_index(&init_net, op->ifindex);
 				if (dev) {
-					bcm_rx_unreg(dev, op);
+					bcm_rx_unreg(dev, op, net);
 					dev_put(dev);
 				}
 			}
 		} else
 			can_rx_unregister(NULL, op->can_id,
 					  REGMASK(op->can_id),
-					  bcm_rx_handler, op);
+					  bcm_rx_handler, op, net);
 
 		bcm_remove_op(op);
 	}
diff --git a/net/can/gw.c b/net/can/gw.c
index 4551687..082a144 100644
--- a/net/can/gw.c
+++ b/net/can/gw.c
@@ -149,6 +149,7 @@ struct cgw_job {
 	u8 gwtype;
 	u8 limit_hops;
 	u16 flags;
+	struct net* net;
 };
 
 /* modification functions that are invoked in the hot path in can_can_gw_rcv */
@@ -442,13 +443,14 @@ static inline int cgw_register_filter(struct cgw_job *gwj)
 {
 	return can_rx_register(gwj->src.dev, gwj->ccgw.filter.can_id,
 			       gwj->ccgw.filter.can_mask, can_can_gw_rcv,
-			       gwj, "gw");
+			       gwj, "gw", gwj->net);
 }
 
 static inline void cgw_unregister_filter(struct cgw_job *gwj)
 {
 	can_rx_unregister(gwj->src.dev, gwj->ccgw.filter.can_id,
-			  gwj->ccgw.filter.can_mask, can_can_gw_rcv, gwj);
+			  gwj->ccgw.filter.can_mask, can_can_gw_rcv, gwj,
+			  gwj->net);
 }
 
 static int cgw_notifier(struct notifier_block *nb,
@@ -872,6 +874,7 @@ static int cgw_create_job(struct sk_buff *skb,  struct nlmsghdr *nlh)
 	gwj->flags = r->flags;
 	gwj->gwtype = r->gwtype;
 	gwj->limit_hops = limhops;
+	gwj->net = sock_net(skb->sk);
 
 	/* insert already parsed information */
 	memcpy(&gwj->mod, &mod, sizeof(mod));
@@ -879,7 +882,7 @@ static int cgw_create_job(struct sk_buff *skb,  struct nlmsghdr *nlh)
 
 	err = -ENODEV;
 
-	gwj->src.dev = __dev_get_by_index(&init_net, gwj->ccgw.src_idx);
+	gwj->src.dev = __dev_get_by_index(gwj->net, gwj->ccgw.src_idx);
 
 	if (!gwj->src.dev)
 		goto out;
@@ -887,7 +890,7 @@ static int cgw_create_job(struct sk_buff *skb,  struct nlmsghdr *nlh)
 	if (gwj->src.dev->type != ARPHRD_CAN)
 		goto out;
 
-	gwj->dst.dev = __dev_get_by_index(&init_net, gwj->ccgw.dst_idx);
+	gwj->dst.dev = __dev_get_by_index(gwj->net, gwj->ccgw.dst_idx);
 
 	if (!gwj->dst.dev)
 		goto out;
diff --git a/net/can/proc.c b/net/can/proc.c
index 0f9f7dc..a80f5e5 100644
--- a/net/can/proc.c
+++ b/net/can/proc.c
@@ -45,6 +45,7 @@
 #include <linux/rcupdate.h>
 #include <linux/if_arp.h>
 #include <linux/can/core.h>
+#include <net/net_namespace.h>
 
 #include <net/af_can.h>
 
@@ -62,18 +63,6 @@
 #define CAN_PROC_RCVLIST_EFF "rcvlist_eff"
 #define CAN_PROC_RCVLIST_ERR "rcvlist_err"
 
-static struct proc_dir_entry *can_dir;
-static struct proc_dir_entry *pde_version;
-static struct proc_dir_entry *pde_stats;
-static struct proc_dir_entry *pde_reset_stats;
-static struct proc_dir_entry *pde_rcvlist_all;
-static struct proc_dir_entry *pde_rcvlist_fil;
-static struct proc_dir_entry *pde_rcvlist_inv;
-static struct proc_dir_entry *pde_rcvlist_sff;
-static struct proc_dir_entry *pde_rcvlist_eff;
-static struct proc_dir_entry *pde_rcvlist_err;
-
-static int user_reset;
 
 static const char rx_list_name[][8] = {
 	[RX_ERR] = "rx_err",
@@ -86,21 +75,21 @@ static const char rx_list_name[][8] = {
  * af_can statistics stuff
  */
 
-static void can_init_stats(void)
+static void can_init_stats(struct net *net)
 {
 	/*
 	 * This memset function is called from a timer context (when
 	 * can_stattimer is active which is the default) OR in a process
 	 * context (reading the proc_fs when can_stattimer is disabled).
 	 */
-	memset(&can_stats, 0, sizeof(can_stats));
-	can_stats.jiffies_init = jiffies;
+	memset(&net->can.can_stats, 0, sizeof(net->can.can_stats));
+	net->can.can_stats.jiffies_init = jiffies;
 
-	can_pstats.stats_reset++;
+	net->can.can_pstats.stats_reset++;
 
-	if (user_reset) {
-		user_reset = 0;
-		can_pstats.user_reset++;
+	if (net->can.can_proc.user_reset) {
+		net->can.can_proc.user_reset = 0;
+		net->can.can_pstats.user_reset++;
 	}
 }
 
@@ -126,64 +115,71 @@ static unsigned long calc_rate(unsigned long oldjif, unsigned long newjif,
 
 void can_stat_update(unsigned long data)
 {
+	struct net *net = (struct net *)data;
+
 	unsigned long j = jiffies; /* snapshot */
 
+	struct can_stats* can_stats = &net->can.can_stats;
+
 	/* restart counting in timer context on user request */
-	if (user_reset)
-		can_init_stats();
+	if (net->can.can_proc.user_reset)
+		can_init_stats(net);
 
 	/* restart counting on jiffies overflow */
-	if (j < can_stats.jiffies_init)
-		can_init_stats();
+	if (j < can_stats->jiffies_init)
+		can_init_stats(net);
 
 	/* prevent overflow in calc_rate() */
-	if (can_stats.rx_frames > (ULONG_MAX / HZ))
-		can_init_stats();
+	if (can_stats->rx_frames > (ULONG_MAX / HZ))
+		can_init_stats(net);
 
 	/* prevent overflow in calc_rate() */
-	if (can_stats.tx_frames > (ULONG_MAX / HZ))
-		can_init_stats();
+	if (can_stats->tx_frames > (ULONG_MAX / HZ))
+		can_init_stats(net);
 
 	/* matches overflow - very improbable */
-	if (can_stats.matches > (ULONG_MAX / 100))
-		can_init_stats();
+	if (can_stats->matches > (ULONG_MAX / 100))
+		can_init_stats(net);
 
 	/* calc total values */
-	if (can_stats.rx_frames)
-		can_stats.total_rx_match_ratio = (can_stats.matches * 100) /
-			can_stats.rx_frames;
+	if (can_stats->rx_frames)
+		can_stats->total_rx_match_ratio = (can_stats->matches * 100) /
+						  can_stats->rx_frames;
 
-	can_stats.total_tx_rate = calc_rate(can_stats.jiffies_init, j,
-					    can_stats.tx_frames);
-	can_stats.total_rx_rate = calc_rate(can_stats.jiffies_init, j,
-					    can_stats.rx_frames);
+	can_stats->total_tx_rate = calc_rate(can_stats->jiffies_init, j,
+					     can_stats->tx_frames);
+	can_stats->total_rx_rate = calc_rate(can_stats->jiffies_init, j,
+					     can_stats->rx_frames);
 
 	/* calc current values */
-	if (can_stats.rx_frames_delta)
-		can_stats.current_rx_match_ratio =
-			(can_stats.matches_delta * 100) /
-			can_stats.rx_frames_delta;
+	if (can_stats->rx_frames_delta)
+		can_stats->current_rx_match_ratio =
+			(can_stats->matches_delta * 100) /
+			can_stats->rx_frames_delta;
 
-	can_stats.current_tx_rate = calc_rate(0, HZ, can_stats.tx_frames_delta);
-	can_stats.current_rx_rate = calc_rate(0, HZ, can_stats.rx_frames_delta);
+	can_stats->current_tx_rate = calc_rate(0, HZ,
+					      can_stats->tx_frames_delta);
+	can_stats->current_rx_rate = calc_rate(0, HZ,
+					      can_stats->rx_frames_delta);
 
 	/* check / update maximum values */
-	if (can_stats.max_tx_rate < can_stats.current_tx_rate)
-		can_stats.max_tx_rate = can_stats.current_tx_rate;
+	if (can_stats->max_tx_rate < can_stats->current_tx_rate)
+		can_stats->max_tx_rate = can_stats->current_tx_rate;
 
-	if (can_stats.max_rx_rate < can_stats.current_rx_rate)
-		can_stats.max_rx_rate = can_stats.current_rx_rate;
+	if (can_stats->max_rx_rate < can_stats->current_rx_rate)
+		can_stats->max_rx_rate = can_stats->current_rx_rate;
 
-	if (can_stats.max_rx_match_ratio < can_stats.current_rx_match_ratio)
-		can_stats.max_rx_match_ratio = can_stats.current_rx_match_ratio;
+	if (can_stats->max_rx_match_ratio < can_stats->current_rx_match_ratio)
+		can_stats->max_rx_match_ratio =
+			can_stats->current_rx_match_ratio;
 
 	/* clear values for 'current rate' calculation */
-	can_stats.tx_frames_delta = 0;
-	can_stats.rx_frames_delta = 0;
-	can_stats.matches_delta   = 0;
+	can_stats->tx_frames_delta = 0;
+	can_stats->rx_frames_delta = 0;
+	can_stats->matches_delta   = 0;
 
 	/* restart timer (one second) */
-	mod_timer(&can_stattimer, round_jiffies(jiffies + HZ));
+	mod_timer(&net->can.can_stattimer, round_jiffies(jiffies + HZ));
 }
 
 /*
@@ -217,57 +213,61 @@ static void can_print_recv_banner(struct seq_file *m)
 
 static int can_stats_proc_show(struct seq_file *m, void *v)
 {
+	struct net *net = m->private;
+	struct can_stats *can_stats = &net->can.can_stats;
+	struct can_pstats *can_pstats = &net->can.can_pstats;
+
 	seq_putc(m, '\n');
-	seq_printf(m, " %8ld transmitted frames (TXF)\n", can_stats.tx_frames);
-	seq_printf(m, " %8ld received frames (RXF)\n", can_stats.rx_frames);
-	seq_printf(m, " %8ld matched frames (RXMF)\n", can_stats.matches);
+	seq_printf(m, " %8ld transmitted frames (TXF)\n", can_stats->tx_frames);
+	seq_printf(m, " %8ld received frames (RXF)\n", can_stats->rx_frames);
+	seq_printf(m, " %8ld matched frames (RXMF)\n", can_stats->matches);
 
 	seq_putc(m, '\n');
 
-	if (can_stattimer.function == can_stat_update) {
+	if (net->can.can_stattimer.function == can_stat_update) {
 		seq_printf(m, " %8ld %% total match ratio (RXMR)\n",
-				can_stats.total_rx_match_ratio);
+				can_stats->total_rx_match_ratio);
 
 		seq_printf(m, " %8ld frames/s total tx rate (TXR)\n",
-				can_stats.total_tx_rate);
+				can_stats->total_tx_rate);
 		seq_printf(m, " %8ld frames/s total rx rate (RXR)\n",
-				can_stats.total_rx_rate);
+				can_stats->total_rx_rate);
 
 		seq_putc(m, '\n');
 
 		seq_printf(m, " %8ld %% current match ratio (CRXMR)\n",
-				can_stats.current_rx_match_ratio);
+				can_stats->current_rx_match_ratio);
 
 		seq_printf(m, " %8ld frames/s current tx rate (CTXR)\n",
-				can_stats.current_tx_rate);
+				can_stats->current_tx_rate);
 		seq_printf(m, " %8ld frames/s current rx rate (CRXR)\n",
-				can_stats.current_rx_rate);
+				can_stats->current_rx_rate);
 
 		seq_putc(m, '\n');
 
 		seq_printf(m, " %8ld %% max match ratio (MRXMR)\n",
-				can_stats.max_rx_match_ratio);
+				can_stats->max_rx_match_ratio);
 
 		seq_printf(m, " %8ld frames/s max tx rate (MTXR)\n",
-				can_stats.max_tx_rate);
+				can_stats->max_tx_rate);
 		seq_printf(m, " %8ld frames/s max rx rate (MRXR)\n",
-				can_stats.max_rx_rate);
+				can_stats->max_rx_rate);
 
 		seq_putc(m, '\n');
 	}
 
 	seq_printf(m, " %8ld current receive list entries (CRCV)\n",
-			can_pstats.rcv_entries);
+			can_pstats->rcv_entries);
 	seq_printf(m, " %8ld maximum receive list entries (MRCV)\n",
-			can_pstats.rcv_entries_max);
+			can_pstats->rcv_entries_max);
 
-	if (can_pstats.stats_reset)
+	if (can_pstats->stats_reset)
 		seq_printf(m, "\n %8ld statistic resets (STR)\n",
-				can_pstats.stats_reset);
+				can_pstats->stats_reset);
 
-	if (can_pstats.user_reset)
+	if (can_pstats->user_reset)
 		seq_printf(m, " %8ld user statistic resets (USTR)\n",
-				can_pstats.user_reset);
+				can_pstats->user_reset);
 
 	seq_putc(m, '\n');
 	return 0;
@@ -275,7 +275,8 @@ static int can_stats_proc_show(struct seq_file *m, void *v)
 
 static int can_stats_proc_open(struct inode *inode, struct file *file)
 {
-	return single_open(file, can_stats_proc_show, NULL);
+	return single_open(file, can_stats_proc_show,
+			   proc_get_parent_data(inode));
 }
 
 static const struct file_operations can_stats_proc_fops = {
@@ -288,25 +289,29 @@ static const struct file_operations can_stats_proc_fops = {
 
 static int can_reset_stats_proc_show(struct seq_file *m, void *v)
 {
-	user_reset = 1;
+	struct net *net = m->private;
+	struct can_stats *can_stats = &net->can.can_stats;
+	struct can_pstats *can_pstats = &net->can.can_pstats;
+	net->can.can_proc.user_reset = 1;
 
-	if (can_stattimer.function == can_stat_update) {
+	if (net->can.can_stattimer.function == can_stat_update) {
 		seq_printf(m, "Scheduled statistic reset #%ld.\n",
-				can_pstats.stats_reset + 1);
+				can_pstats->stats_reset + 1);
 
 	} else {
-		if (can_stats.jiffies_init != jiffies)
-			can_init_stats();
+		if (can_stats->jiffies_init != jiffies)
+			can_init_stats(net);
 
 		seq_printf(m, "Performed statistic reset #%ld.\n",
-				can_pstats.stats_reset);
+				can_pstats->stats_reset);
 	}
 	return 0;
 }
 
 static int can_reset_stats_proc_open(struct inode *inode, struct file *file)
 {
-	return single_open(file, can_reset_stats_proc_show, NULL);
+	return single_open(file, can_reset_stats_proc_show,
+			   proc_get_parent_data(inode));
 }
 
 static const struct file_operations can_reset_stats_proc_fops = {
@@ -325,7 +330,8 @@ static int can_version_proc_show(struct seq_file *m, void *v)
 
 static int can_version_proc_open(struct inode *inode, struct file *file)
 {
-	return single_open(file, can_version_proc_show, NULL);
+	return single_open(file, can_version_proc_show,
+			   proc_get_parent_data(inode));
 }
 
 static const struct file_operations can_version_proc_fops = {
@@ -348,23 +354,25 @@ static inline void can_rcvlist_proc_show_one(struct seq_file *m, int idx,
 
 }
 
-static int can_rcvlist_proc_show(struct seq_file *m, void *v)
+static int can_rcvlist_proc_show(struct seq_file *m, void* v)
 {
 	/* double cast to prevent GCC warning */
-	int idx = (int)(long)m->private;
+	struct inode *inode = m->private;
+	int idx = (int)(long)PDE_DATA(inode);
 	struct net_device *dev;
 	struct can_dev_rcv_lists *d;
+	struct net *net = proc_get_parent_data(inode);
 
 	seq_printf(m, "\nreceive list '%s':\n", rx_list_name[idx]);
 
 	rcu_read_lock();
 
 	/* receive list for 'all' CAN devices (dev == NULL) */
-	d = &can_rx_alldev_list;
+	d = &net->can.can_rx_alldev_list;
 	can_rcvlist_proc_show_one(m, idx, NULL, d);
 
 	/* receive list for registered CAN devices */
-	for_each_netdev_rcu(&init_net, dev) {
+	for_each_netdev_rcu(net, dev) {
 		if (dev->type == ARPHRD_CAN && dev->ml_priv)
 			can_rcvlist_proc_show_one(m, idx, dev, dev->ml_priv);
 	}
@@ -377,7 +385,7 @@ static int can_rcvlist_proc_show(struct seq_file *m, void *v)
 
 static int can_rcvlist_proc_open(struct inode *inode, struct file *file)
 {
-	return single_open(file, can_rcvlist_proc_show, PDE_DATA(inode));
+	return single_open(file, can_rcvlist_proc_show, inode);
 }
 
 static const struct file_operations can_rcvlist_proc_fops = {
@@ -417,6 +425,7 @@ static int can_rcvlist_sff_proc_show(struct seq_file *m, void *v)
 {
 	struct net_device *dev;
 	struct can_dev_rcv_lists *d;
+	struct net *net = m->private;
 
 	/* RX_SFF */
 	seq_puts(m, "\nreceive list 'rx_sff':\n");
@@ -424,11 +433,11 @@ static int can_rcvlist_sff_proc_show(struct seq_file *m, void *v)
 	rcu_read_lock();
 
 	/* sff receive list for 'all' CAN devices (dev == NULL) */
-	d = &can_rx_alldev_list;
+	d = &net->can.can_rx_alldev_list;
 	can_rcvlist_proc_show_array(m, NULL, d->rx_sff, ARRAY_SIZE(d->rx_sff));
 
 	/* sff receive list for registered CAN devices */
-	for_each_netdev_rcu(&init_net, dev) {
+	for_each_netdev_rcu(net, dev) {
 		if (dev->type == ARPHRD_CAN && dev->ml_priv) {
 			d = dev->ml_priv;
 			can_rcvlist_proc_show_array(m, dev, d->rx_sff,
@@ -444,7 +453,8 @@ static int can_rcvlist_sff_proc_show(struct seq_file *m, void *v)
 
 static int can_rcvlist_sff_proc_open(struct inode *inode, struct file *file)
 {
-	return single_open(file, can_rcvlist_sff_proc_show, NULL);
+	return single_open(file, can_rcvlist_sff_proc_show,
+			   proc_get_parent_data(inode));
 }
 
 static const struct file_operations can_rcvlist_sff_proc_fops = {
@@ -460,6 +470,7 @@ static int can_rcvlist_eff_proc_show(struct seq_file *m, void *v)
 {
 	struct net_device *dev;
 	struct can_dev_rcv_lists *d;
+	struct net *net = m->private;
 
 	/* RX_EFF */
 	seq_puts(m, "\nreceive list 'rx_eff':\n");
@@ -467,11 +478,11 @@ static int can_rcvlist_eff_proc_show(struct seq_file *m, void *v)
 	rcu_read_lock();
 
 	/* eff receive list for 'all' CAN devices (dev == NULL) */
-	d = &can_rx_alldev_list;
+	d = &net->can.can_rx_alldev_list;
 	can_rcvlist_proc_show_array(m, NULL, d->rx_eff, ARRAY_SIZE(d->rx_eff));
 
 	/* eff receive list for registered CAN devices */
-	for_each_netdev_rcu(&init_net, dev) {
+	for_each_netdev_rcu(net, dev) {
 		if (dev->type == ARPHRD_CAN && dev->ml_priv) {
 			d = dev->ml_priv;
 			can_rcvlist_proc_show_array(m, dev, d->rx_eff,
@@ -487,7 +498,8 @@ static int can_rcvlist_eff_proc_show(struct seq_file *m, void *v)
 
 static int can_rcvlist_eff_proc_open(struct inode *inode, struct file *file)
 {
-	return single_open(file, can_rcvlist_eff_proc_show, NULL);
+	return single_open(file, can_rcvlist_eff_proc_show,
+			   proc_get_parent_data(inode));
 }
 
 static const struct file_operations can_rcvlist_eff_proc_fops = {
@@ -502,19 +514,22 @@ static const struct file_operations can_rcvlist_eff_proc_fops = {
  * proc utility functions
  */
 
-static void can_remove_proc_readentry(const char *name)
+static void can_remove_proc_readentry(struct net* net, const char *name)
 {
-	if (can_dir)
-		remove_proc_entry(name, can_dir);
+	if (net->can.can_proc.can_dir)
+		remove_proc_entry(name, net->can.can_proc.can_dir);
 }
 
 /*
  * can_init_proc - create main CAN proc directory and procfs entries
  */
-void can_init_proc(void)
+void can_init_proc(struct net *net)
 {
 	/* create /proc/net/can directory */
-	can_dir = proc_mkdir("can", init_net.proc_net);
+	struct proc_dir_entry *can_dir;
+	struct can_proc *pde;
+
+	can_dir = proc_net_mkdir(net, "can", net->proc_net);
 
 	if (!can_dir) {
 		printk(KERN_INFO "can: failed to create /proc/net/can . "
@@ -522,59 +537,69 @@ void can_init_proc(void)
 		return;
 	}
 
+	net->can.can_proc.can_dir = can_dir;
+
+	pde = &net->can.can_proc;
+
 	/* own procfs entries from the AF_CAN core */
-	pde_version     = proc_create(CAN_PROC_VERSION, 0644, can_dir,
-				      &can_version_proc_fops);
-	pde_stats       = proc_create(CAN_PROC_STATS, 0644, can_dir,
-				      &can_stats_proc_fops);
-	pde_reset_stats = proc_create(CAN_PROC_RESET_STATS, 0644, can_dir,
-				      &can_reset_stats_proc_fops);
-	pde_rcvlist_err = proc_create_data(CAN_PROC_RCVLIST_ERR, 0644, can_dir,
-					   &can_rcvlist_proc_fops, (void *)RX_ERR);
-	pde_rcvlist_all = proc_create_data(CAN_PROC_RCVLIST_ALL, 0644, can_dir,
-					   &can_rcvlist_proc_fops, (void *)RX_ALL);
-	pde_rcvlist_fil = proc_create_data(CAN_PROC_RCVLIST_FIL, 0644, can_dir,
-					   &can_rcvlist_proc_fops, (void *)RX_FIL);
-	pde_rcvlist_inv = proc_create_data(CAN_PROC_RCVLIST_INV, 0644, can_dir,
-					   &can_rcvlist_proc_fops, (void *)RX_INV);
-	pde_rcvlist_eff = proc_create(CAN_PROC_RCVLIST_EFF, 0644, can_dir,
-				      &can_rcvlist_eff_proc_fops);
-	pde_rcvlist_sff = proc_create(CAN_PROC_RCVLIST_SFF, 0644, can_dir,
-				      &can_rcvlist_sff_proc_fops);
+	pde->version     = proc_create(CAN_PROC_VERSION, 0644, can_dir,
+				       &can_version_proc_fops);
+	pde->stats       = proc_create(CAN_PROC_STATS, 0644, can_dir,
+				       &can_stats_proc_fops);
+	pde->reset_stats = proc_create(CAN_PROC_RESET_STATS, 0644, can_dir,
+				       &can_reset_stats_proc_fops);
+	pde->rcvlist_err = proc_create_data(CAN_PROC_RCVLIST_ERR, 0644, can_dir,
+					    &can_rcvlist_proc_fops,
+					    (void *)RX_ERR);
+	pde->rcvlist_all = proc_create_data(CAN_PROC_RCVLIST_ALL, 0644, can_dir,
+					    &can_rcvlist_proc_fops,
+					    (void *)RX_ALL);
+	pde->rcvlist_fil = proc_create_data(CAN_PROC_RCVLIST_FIL, 0644, can_dir,
+					    &can_rcvlist_proc_fops,
+					    (void *)RX_FIL);
+	pde->rcvlist_inv = proc_create_data(CAN_PROC_RCVLIST_INV, 0644, can_dir,
+					    &can_rcvlist_proc_fops,
+					    (void *)RX_INV);
+	pde->rcvlist_eff = proc_create(CAN_PROC_RCVLIST_EFF, 0644, can_dir,
+				       &can_rcvlist_eff_proc_fops);
+	pde->rcvlist_sff = proc_create(CAN_PROC_RCVLIST_SFF, 0644, can_dir,
+				       &can_rcvlist_sff_proc_fops);
 }
 
 /*
  * can_remove_proc - remove procfs entries and main CAN proc directory
  */
-void can_remove_proc(void)
+void can_remove_proc(struct net *net)
 {
-	if (pde_version)
-		can_remove_proc_readentry(CAN_PROC_VERSION);
+	struct can_proc *pde = &net->can.can_proc;
+
+	if (pde->version)
+		can_remove_proc_readentry(net, CAN_PROC_VERSION);
 
-	if (pde_stats)
-		can_remove_proc_readentry(CAN_PROC_STATS);
+	if (pde->stats)
+		can_remove_proc_readentry(net, CAN_PROC_STATS);
 
-	if (pde_reset_stats)
-		can_remove_proc_readentry(CAN_PROC_RESET_STATS);
+	if (pde->reset_stats)
+		can_remove_proc_readentry(net, CAN_PROC_RESET_STATS);
 
-	if (pde_rcvlist_err)
-		can_remove_proc_readentry(CAN_PROC_RCVLIST_ERR);
+	if (pde->rcvlist_err)
+		can_remove_proc_readentry(net, CAN_PROC_RCVLIST_ERR);
 
-	if (pde_rcvlist_all)
-		can_remove_proc_readentry(CAN_PROC_RCVLIST_ALL);
+	if (pde->rcvlist_all)
+		can_remove_proc_readentry(net, CAN_PROC_RCVLIST_ALL);
 
-	if (pde_rcvlist_fil)
-		can_remove_proc_readentry(CAN_PROC_RCVLIST_FIL);
+	if (pde->rcvlist_fil)
+		can_remove_proc_readentry(net, CAN_PROC_RCVLIST_FIL);
 
-	if (pde_rcvlist_inv)
-		can_remove_proc_readentry(CAN_PROC_RCVLIST_INV);
+	if (pde->rcvlist_inv)
+		can_remove_proc_readentry(net, CAN_PROC_RCVLIST_INV);
 
-	if (pde_rcvlist_eff)
-		can_remove_proc_readentry(CAN_PROC_RCVLIST_EFF);
+	if (pde->rcvlist_eff)
+		can_remove_proc_readentry(net, CAN_PROC_RCVLIST_EFF);
 
-	if (pde_rcvlist_sff)
-		can_remove_proc_readentry(CAN_PROC_RCVLIST_SFF);
+	if (pde->rcvlist_sff)
+		can_remove_proc_readentry(net, CAN_PROC_RCVLIST_SFF);
 
-	if (can_dir)
-		remove_proc_entry("can", init_net.proc_net);
+	if (pde->can_dir)
+		remove_proc_entry("can", net->proc_net);
 }
diff --git a/net/can/raw.c b/net/can/raw.c
index 2e67b14..c5c0cb9 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -184,19 +184,20 @@ static void raw_rcv(struct sk_buff *oskb, void *data)
 static int raw_enable_filters(struct net_device *dev, struct sock *sk,
 			      struct can_filter *filter, int count)
 {
+	struct net *net = sock_net(sk);
 	int err = 0;
 	int i;
 
 	for (i = 0; i < count; i++) {
 		err = can_rx_register(dev, filter[i].can_id,
 				      filter[i].can_mask,
-				      raw_rcv, sk, "raw");
+				      raw_rcv, sk, "raw", net);
 		if (err) {
 			/* clean up successfully registered filters */
 			while (--i >= 0)
 				can_rx_unregister(dev, filter[i].can_id,
 						  filter[i].can_mask,
-						  raw_rcv, sk);
+						  raw_rcv, sk, net);
 			break;
 		}
 	}
@@ -207,11 +208,12 @@ static int raw_enable_filters(struct net_device *dev, struct sock *sk,
 static int raw_enable_errfilter(struct net_device *dev, struct sock *sk,
 				can_err_mask_t err_mask)
 {
+	struct net *net = sock_net(sk);
 	int err = 0;
 
 	if (err_mask)
 		err = can_rx_register(dev, 0, err_mask | CAN_ERR_FLAG,
-				      raw_rcv, sk, "raw");
+				      raw_rcv, sk, "raw", net);
 
 	return err;
 }
@@ -219,11 +221,12 @@ static int raw_enable_errfilter(struct net_device *dev, struct sock *sk,
 static void raw_disable_filters(struct net_device *dev, struct sock *sk,
 			      struct can_filter *filter, int count)
 {
+	struct net *net = sock_net(sk);
 	int i;
 
 	for (i = 0; i < count; i++)
 		can_rx_unregister(dev, filter[i].can_id, filter[i].can_mask,
-				  raw_rcv, sk);
+				  raw_rcv, sk, net);
 }
 
 static inline void raw_disable_errfilter(struct net_device *dev,
@@ -231,9 +234,11 @@ static inline void raw_disable_errfilter(struct net_device *dev,
 					 can_err_mask_t err_mask)
 
 {
+	struct net *net = sock_net(sk);
+
 	if (err_mask)
 		can_rx_unregister(dev, 0, err_mask | CAN_ERR_FLAG,
-				  raw_rcv, sk);
+				  raw_rcv, sk, net);
 }
 
 static inline void raw_disable_allfilters(struct net_device *dev,
@@ -342,6 +347,7 @@ static int raw_init(struct sock *sk)
 static int raw_release(struct socket *sock)
 {
 	struct sock *sk = sock->sk;
+	struct net *net = sock_net(sk);
 	struct raw_sock *ro;
 
 	if (!sk)
@@ -358,7 +364,7 @@ static int raw_release(struct socket *sock)
 		if (ro->ifindex) {
 			struct net_device *dev;
 
-			dev = dev_get_by_index(&init_net, ro->ifindex);
+			dev = dev_get_by_index(net, ro->ifindex);
 			if (dev) {
 				raw_disable_allfilters(dev, sk);
 				dev_put(dev);
@@ -389,6 +395,7 @@ static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len)
 	struct sockaddr_can *addr = (struct sockaddr_can *)uaddr;
 	struct sock *sk = sock->sk;
 	struct raw_sock *ro = raw_sk(sk);
+	struct net *net = sock_net(sk);
 	int ifindex;
 	int err = 0;
 	int notify_enetdown = 0;
@@ -404,7 +411,7 @@ static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len)
 	if (addr->can_ifindex) {
 		struct net_device *dev;
 
-		dev = dev_get_by_index(&init_net, addr->can_ifindex);
+		dev = dev_get_by_index(net, addr->can_ifindex);
 		if (!dev) {
 			err = -ENODEV;
 			goto out;
@@ -435,7 +442,7 @@ static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len)
 			if (ro->ifindex) {
 				struct net_device *dev;
 
-				dev = dev_get_by_index(&init_net, ro->ifindex);
+				dev = dev_get_by_index(net, ro->ifindex);
 				if (dev) {
 					raw_disable_allfilters(dev, sk);
 					dev_put(dev);
@@ -483,6 +490,7 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
 {
 	struct sock *sk = sock->sk;
 	struct raw_sock *ro = raw_sk(sk);
+	struct net *net = sock_net(sk);
 	struct can_filter *filter = NULL;  /* dyn. alloc'ed filters */
 	struct can_filter sfilter;         /* single filter */
 	struct net_device *dev = NULL;
@@ -514,7 +522,7 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
 		lock_sock(sk);
 
 		if (ro->bound && ro->ifindex)
-			dev = dev_get_by_index(&init_net, ro->ifindex);
+			dev = dev_get_by_index(net, ro->ifindex);
 
 		if (ro->bound) {
 			/* (try to) register the new filters */
@@ -566,7 +574,7 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
 		lock_sock(sk);
 
 		if (ro->bound && ro->ifindex)
-			dev = dev_get_by_index(&init_net, ro->ifindex);
+			dev = dev_get_by_index(net, ro->ifindex);
 
 		/* remove current error mask */
 		if (ro->bound) {
@@ -711,6 +719,7 @@ static int raw_getsockopt(struct socket *sock, int level, int optname,
 static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
 {
 	struct sock *sk = sock->sk;
+	struct net *net = sock_net(sk);
 	struct raw_sock *ro = raw_sk(sk);
 	struct sk_buff *skb;
 	struct net_device *dev;
@@ -738,7 +747,7 @@ static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
 			return -EINVAL;
 	}
 
-	dev = dev_get_by_index(&init_net, ifindex);
+	dev = dev_get_by_index(net, ifindex);
 	if (!dev)
 		return -ENXIO;
 
-- 
2.5.3
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help