mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	can: network namespace support for CAN_BCM protocol
The CAN_BCM protocol and its procfs entries were not implemented as per-net
in the initial network namespace support by Mario Kicherer (8e8cda6d73).
This patch adds the missing per-net functionality for the CAN BCM.
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
			
			
This commit is contained in:
		
							parent
							
								
									cb5635a367
								
							
						
					
					
						commit
						384317ef41
					
				
					 2 changed files with 58 additions and 33 deletions
				
			
		| 
						 | 
					@ -23,6 +23,7 @@ struct netns_can {
 | 
				
			||||||
	struct proc_dir_entry *pde_rcvlist_sff;
 | 
						struct proc_dir_entry *pde_rcvlist_sff;
 | 
				
			||||||
	struct proc_dir_entry *pde_rcvlist_eff;
 | 
						struct proc_dir_entry *pde_rcvlist_eff;
 | 
				
			||||||
	struct proc_dir_entry *pde_rcvlist_err;
 | 
						struct proc_dir_entry *pde_rcvlist_err;
 | 
				
			||||||
 | 
						struct proc_dir_entry *bcmproc_dir;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* receive filters subscribed for 'all' CAN devices */
 | 
						/* receive filters subscribed for 'all' CAN devices */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * bcm.c - Broadcast Manager to filter/send (cyclic) CAN content
 | 
					 * bcm.c - Broadcast Manager to filter/send (cyclic) CAN content
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Copyright (c) 2002-2016 Volkswagen Group Electronic Research
 | 
					 * Copyright (c) 2002-2017 Volkswagen Group Electronic Research
 | 
				
			||||||
 * All rights reserved.
 | 
					 * All rights reserved.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Redistribution and use in source and binary forms, with or without
 | 
					 * Redistribution and use in source and binary forms, with or without
 | 
				
			||||||
| 
						 | 
					@ -77,7 +77,7 @@
 | 
				
			||||||
		     (CAN_EFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG) : \
 | 
							     (CAN_EFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG) : \
 | 
				
			||||||
		     (CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG))
 | 
							     (CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define CAN_BCM_VERSION "20161123"
 | 
					#define CAN_BCM_VERSION "20170425"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MODULE_DESCRIPTION("PF_CAN broadcast manager protocol");
 | 
					MODULE_DESCRIPTION("PF_CAN broadcast manager protocol");
 | 
				
			||||||
MODULE_LICENSE("Dual BSD/GPL");
 | 
					MODULE_LICENSE("Dual BSD/GPL");
 | 
				
			||||||
| 
						 | 
					@ -118,8 +118,6 @@ struct bcm_op {
 | 
				
			||||||
	struct net_device *rx_reg_dev;
 | 
						struct net_device *rx_reg_dev;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct proc_dir_entry *proc_dir;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct bcm_sock {
 | 
					struct bcm_sock {
 | 
				
			||||||
	struct sock sk;
 | 
						struct sock sk;
 | 
				
			||||||
	int bound;
 | 
						int bound;
 | 
				
			||||||
| 
						 | 
					@ -149,7 +147,7 @@ static inline ktime_t bcm_timeval_to_ktime(struct bcm_timeval tv)
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * procfs functions
 | 
					 * procfs functions
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static char *bcm_proc_getifname(char *result, int ifindex)
 | 
					static char *bcm_proc_getifname(struct net *net, char *result, int ifindex)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct net_device *dev;
 | 
						struct net_device *dev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -157,7 +155,7 @@ static char *bcm_proc_getifname(char *result, int ifindex)
 | 
				
			||||||
		return "any";
 | 
							return "any";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rcu_read_lock();
 | 
						rcu_read_lock();
 | 
				
			||||||
	dev = dev_get_by_index_rcu(&init_net, ifindex);
 | 
						dev = dev_get_by_index_rcu(net, ifindex);
 | 
				
			||||||
	if (dev)
 | 
						if (dev)
 | 
				
			||||||
		strcpy(result, dev->name);
 | 
							strcpy(result, dev->name);
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
| 
						 | 
					@ -170,7 +168,8 @@ static char *bcm_proc_getifname(char *result, int ifindex)
 | 
				
			||||||
static int bcm_proc_show(struct seq_file *m, void *v)
 | 
					static int bcm_proc_show(struct seq_file *m, void *v)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char ifname[IFNAMSIZ];
 | 
						char ifname[IFNAMSIZ];
 | 
				
			||||||
	struct sock *sk = (struct sock *)m->private;
 | 
						struct net *net = m->private;
 | 
				
			||||||
 | 
						struct sock *sk = (struct sock *)PDE_DATA(m->file->f_inode);
 | 
				
			||||||
	struct bcm_sock *bo = bcm_sk(sk);
 | 
						struct bcm_sock *bo = bcm_sk(sk);
 | 
				
			||||||
	struct bcm_op *op;
 | 
						struct bcm_op *op;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -178,7 +177,7 @@ static int bcm_proc_show(struct seq_file *m, void *v)
 | 
				
			||||||
	seq_printf(m, " / sk %pK", sk);
 | 
						seq_printf(m, " / sk %pK", sk);
 | 
				
			||||||
	seq_printf(m, " / bo %pK", bo);
 | 
						seq_printf(m, " / bo %pK", bo);
 | 
				
			||||||
	seq_printf(m, " / dropped %lu", bo->dropped_usr_msgs);
 | 
						seq_printf(m, " / dropped %lu", bo->dropped_usr_msgs);
 | 
				
			||||||
	seq_printf(m, " / bound %s", bcm_proc_getifname(ifname, bo->ifindex));
 | 
						seq_printf(m, " / bound %s", bcm_proc_getifname(net, ifname, bo->ifindex));
 | 
				
			||||||
	seq_printf(m, " <<<\n");
 | 
						seq_printf(m, " <<<\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	list_for_each_entry(op, &bo->rx_ops, list) {
 | 
						list_for_each_entry(op, &bo->rx_ops, list) {
 | 
				
			||||||
| 
						 | 
					@ -190,7 +189,7 @@ static int bcm_proc_show(struct seq_file *m, void *v)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		seq_printf(m, "rx_op: %03X %-5s ", op->can_id,
 | 
							seq_printf(m, "rx_op: %03X %-5s ", op->can_id,
 | 
				
			||||||
			   bcm_proc_getifname(ifname, op->ifindex));
 | 
								   bcm_proc_getifname(net, ifname, op->ifindex));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (op->flags & CAN_FD_FRAME)
 | 
							if (op->flags & CAN_FD_FRAME)
 | 
				
			||||||
			seq_printf(m, "(%u)", op->nframes);
 | 
								seq_printf(m, "(%u)", op->nframes);
 | 
				
			||||||
| 
						 | 
					@ -219,7 +218,7 @@ static int bcm_proc_show(struct seq_file *m, void *v)
 | 
				
			||||||
	list_for_each_entry(op, &bo->tx_ops, list) {
 | 
						list_for_each_entry(op, &bo->tx_ops, list) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		seq_printf(m, "tx_op: %03X %s ", op->can_id,
 | 
							seq_printf(m, "tx_op: %03X %s ", op->can_id,
 | 
				
			||||||
			   bcm_proc_getifname(ifname, op->ifindex));
 | 
								   bcm_proc_getifname(net, ifname, op->ifindex));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (op->flags & CAN_FD_FRAME)
 | 
							if (op->flags & CAN_FD_FRAME)
 | 
				
			||||||
			seq_printf(m, "(%u) ", op->nframes);
 | 
								seq_printf(m, "(%u) ", op->nframes);
 | 
				
			||||||
| 
						 | 
					@ -242,7 +241,7 @@ static int bcm_proc_show(struct seq_file *m, void *v)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int bcm_proc_open(struct inode *inode, struct file *file)
 | 
					static int bcm_proc_open(struct inode *inode, struct file *file)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return single_open(file, bcm_proc_show, PDE_DATA(inode));
 | 
						return single_open_net(inode, file, bcm_proc_show);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const struct file_operations bcm_proc_fops = {
 | 
					static const struct file_operations bcm_proc_fops = {
 | 
				
			||||||
| 
						 | 
					@ -267,7 +266,7 @@ static void bcm_can_tx(struct bcm_op *op)
 | 
				
			||||||
	if (!op->ifindex)
 | 
						if (!op->ifindex)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev = dev_get_by_index(&init_net, op->ifindex);
 | 
						dev = dev_get_by_index(sock_net(op->sk), op->ifindex);
 | 
				
			||||||
	if (!dev) {
 | 
						if (!dev) {
 | 
				
			||||||
		/* RFC: should this bcm_op remove itself here? */
 | 
							/* RFC: should this bcm_op remove itself here? */
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
| 
						 | 
					@ -764,7 +763,7 @@ static void bcm_remove_op(struct bcm_op *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)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (op->rx_reg_dev == dev) {
 | 
						if (op->rx_reg_dev == dev) {
 | 
				
			||||||
		can_rx_unregister(&init_net, dev, op->can_id,
 | 
							can_rx_unregister(dev_net(dev), dev, op->can_id,
 | 
				
			||||||
				  REGMASK(op->can_id), bcm_rx_handler, op);
 | 
									  REGMASK(op->can_id), bcm_rx_handler, op);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* mark as removed subscription */
 | 
							/* mark as removed subscription */
 | 
				
			||||||
| 
						 | 
					@ -800,7 +799,7 @@ static int bcm_delete_rx_op(struct list_head *ops, struct bcm_msg_head *mh,
 | 
				
			||||||
				if (op->rx_reg_dev) {
 | 
									if (op->rx_reg_dev) {
 | 
				
			||||||
					struct net_device *dev;
 | 
										struct net_device *dev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					dev = dev_get_by_index(&init_net,
 | 
										dev = dev_get_by_index(sock_net(op->sk),
 | 
				
			||||||
							       op->ifindex);
 | 
												       op->ifindex);
 | 
				
			||||||
					if (dev) {
 | 
										if (dev) {
 | 
				
			||||||
						bcm_rx_unreg(dev, op);
 | 
											bcm_rx_unreg(dev, op);
 | 
				
			||||||
| 
						 | 
					@ -808,7 +807,8 @@ static int bcm_delete_rx_op(struct list_head *ops, struct bcm_msg_head *mh,
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			} else
 | 
								} else
 | 
				
			||||||
				can_rx_unregister(&init_net, NULL, op->can_id,
 | 
									can_rx_unregister(sock_net(op->sk), NULL,
 | 
				
			||||||
 | 
											  op->can_id,
 | 
				
			||||||
						  REGMASK(op->can_id),
 | 
											  REGMASK(op->can_id),
 | 
				
			||||||
						  bcm_rx_handler, op);
 | 
											  bcm_rx_handler, op);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1220,9 +1220,9 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 | 
				
			||||||
		if (ifindex) {
 | 
							if (ifindex) {
 | 
				
			||||||
			struct net_device *dev;
 | 
								struct net_device *dev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			dev = dev_get_by_index(&init_net, ifindex);
 | 
								dev = dev_get_by_index(sock_net(sk), ifindex);
 | 
				
			||||||
			if (dev) {
 | 
								if (dev) {
 | 
				
			||||||
				err = can_rx_register(&init_net, dev,
 | 
									err = can_rx_register(sock_net(sk), dev,
 | 
				
			||||||
						      op->can_id,
 | 
											      op->can_id,
 | 
				
			||||||
						      REGMASK(op->can_id),
 | 
											      REGMASK(op->can_id),
 | 
				
			||||||
						      bcm_rx_handler, op,
 | 
											      bcm_rx_handler, op,
 | 
				
			||||||
| 
						 | 
					@ -1233,7 +1233,7 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		} else
 | 
							} else
 | 
				
			||||||
			err = can_rx_register(&init_net, NULL, op->can_id,
 | 
								err = can_rx_register(sock_net(sk), NULL, op->can_id,
 | 
				
			||||||
					      REGMASK(op->can_id),
 | 
										      REGMASK(op->can_id),
 | 
				
			||||||
					      bcm_rx_handler, op, "bcm", sk);
 | 
										      bcm_rx_handler, op, "bcm", sk);
 | 
				
			||||||
		if (err) {
 | 
							if (err) {
 | 
				
			||||||
| 
						 | 
					@ -1273,7 +1273,7 @@ static int bcm_tx_send(struct msghdr *msg, int ifindex, struct sock *sk,
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dev = dev_get_by_index(&init_net, ifindex);
 | 
						dev = dev_get_by_index(sock_net(sk), ifindex);
 | 
				
			||||||
	if (!dev) {
 | 
						if (!dev) {
 | 
				
			||||||
		kfree_skb(skb);
 | 
							kfree_skb(skb);
 | 
				
			||||||
		return -ENODEV;
 | 
							return -ENODEV;
 | 
				
			||||||
| 
						 | 
					@ -1338,7 +1338,7 @@ static int bcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
 | 
				
			||||||
		if (ifindex) {
 | 
							if (ifindex) {
 | 
				
			||||||
			struct net_device *dev;
 | 
								struct net_device *dev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			dev = dev_get_by_index(&init_net, ifindex);
 | 
								dev = dev_get_by_index(sock_net(sk), ifindex);
 | 
				
			||||||
			if (!dev)
 | 
								if (!dev)
 | 
				
			||||||
				return -ENODEV;
 | 
									return -ENODEV;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1419,7 +1419,7 @@ static int bcm_notifier(struct notifier_block *nb, unsigned long msg,
 | 
				
			||||||
	struct bcm_op *op;
 | 
						struct bcm_op *op;
 | 
				
			||||||
	int notify_enodev = 0;
 | 
						int notify_enodev = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!net_eq(dev_net(dev), &init_net))
 | 
						if (!net_eq(dev_net(dev), sock_net(sk)))
 | 
				
			||||||
		return NOTIFY_DONE;
 | 
							return NOTIFY_DONE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (dev->type != ARPHRD_CAN)
 | 
						if (dev->type != ARPHRD_CAN)
 | 
				
			||||||
| 
						 | 
					@ -1491,6 +1491,7 @@ static int bcm_init(struct sock *sk)
 | 
				
			||||||
static int bcm_release(struct socket *sock)
 | 
					static int bcm_release(struct socket *sock)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sock *sk = sock->sk;
 | 
						struct sock *sk = sock->sk;
 | 
				
			||||||
 | 
						struct net *net = sock_net(sk);
 | 
				
			||||||
	struct bcm_sock *bo;
 | 
						struct bcm_sock *bo;
 | 
				
			||||||
	struct bcm_op *op, *next;
 | 
						struct bcm_op *op, *next;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1522,14 +1523,14 @@ static int bcm_release(struct socket *sock)
 | 
				
			||||||
			if (op->rx_reg_dev) {
 | 
								if (op->rx_reg_dev) {
 | 
				
			||||||
				struct net_device *dev;
 | 
									struct net_device *dev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				dev = dev_get_by_index(&init_net, op->ifindex);
 | 
									dev = dev_get_by_index(net, op->ifindex);
 | 
				
			||||||
				if (dev) {
 | 
									if (dev) {
 | 
				
			||||||
					bcm_rx_unreg(dev, op);
 | 
										bcm_rx_unreg(dev, op);
 | 
				
			||||||
					dev_put(dev);
 | 
										dev_put(dev);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} else
 | 
							} else
 | 
				
			||||||
			can_rx_unregister(&init_net, NULL, op->can_id,
 | 
								can_rx_unregister(net, NULL, op->can_id,
 | 
				
			||||||
					  REGMASK(op->can_id),
 | 
										  REGMASK(op->can_id),
 | 
				
			||||||
					  bcm_rx_handler, op);
 | 
										  bcm_rx_handler, op);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1537,8 +1538,8 @@ static int bcm_release(struct socket *sock)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* remove procfs entry */
 | 
						/* remove procfs entry */
 | 
				
			||||||
	if (proc_dir && bo->bcm_proc_read)
 | 
						if (net->can.bcmproc_dir && bo->bcm_proc_read)
 | 
				
			||||||
		remove_proc_entry(bo->procname, proc_dir);
 | 
							remove_proc_entry(bo->procname, net->can.bcmproc_dir);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* remove device reference */
 | 
						/* remove device reference */
 | 
				
			||||||
	if (bo->bound) {
 | 
						if (bo->bound) {
 | 
				
			||||||
| 
						 | 
					@ -1561,6 +1562,7 @@ static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len,
 | 
				
			||||||
	struct sockaddr_can *addr = (struct sockaddr_can *)uaddr;
 | 
						struct sockaddr_can *addr = (struct sockaddr_can *)uaddr;
 | 
				
			||||||
	struct sock *sk = sock->sk;
 | 
						struct sock *sk = sock->sk;
 | 
				
			||||||
	struct bcm_sock *bo = bcm_sk(sk);
 | 
						struct bcm_sock *bo = bcm_sk(sk);
 | 
				
			||||||
 | 
						struct net *net = sock_net(sk);
 | 
				
			||||||
	int ret = 0;
 | 
						int ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (len < sizeof(*addr))
 | 
						if (len < sizeof(*addr))
 | 
				
			||||||
| 
						 | 
					@ -1577,7 +1579,7 @@ static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len,
 | 
				
			||||||
	if (addr->can_ifindex) {
 | 
						if (addr->can_ifindex) {
 | 
				
			||||||
		struct net_device *dev;
 | 
							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) {
 | 
							if (!dev) {
 | 
				
			||||||
			ret = -ENODEV;
 | 
								ret = -ENODEV;
 | 
				
			||||||
			goto fail;
 | 
								goto fail;
 | 
				
			||||||
| 
						 | 
					@ -1596,11 +1598,11 @@ static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len,
 | 
				
			||||||
		bo->ifindex = 0;
 | 
							bo->ifindex = 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (proc_dir) {
 | 
						if (net->can.bcmproc_dir) {
 | 
				
			||||||
		/* unique socket address as filename */
 | 
							/* unique socket address as filename */
 | 
				
			||||||
		sprintf(bo->procname, "%lu", sock_i_ino(sk));
 | 
							sprintf(bo->procname, "%lu", sock_i_ino(sk));
 | 
				
			||||||
		bo->bcm_proc_read = proc_create_data(bo->procname, 0644,
 | 
							bo->bcm_proc_read = proc_create_data(bo->procname, 0644,
 | 
				
			||||||
						     proc_dir,
 | 
											     net->can.bcmproc_dir,
 | 
				
			||||||
						     &bcm_proc_fops, sk);
 | 
											     &bcm_proc_fops, sk);
 | 
				
			||||||
		if (!bo->bcm_proc_read) {
 | 
							if (!bo->bcm_proc_read) {
 | 
				
			||||||
			ret = -ENOMEM;
 | 
								ret = -ENOMEM;
 | 
				
			||||||
| 
						 | 
					@ -1687,6 +1689,31 @@ static const struct can_proto bcm_can_proto = {
 | 
				
			||||||
	.prot       = &bcm_proto,
 | 
						.prot       = &bcm_proto,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int canbcm_pernet_init(struct net *net)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* create /proc/net/can-bcm directory */
 | 
				
			||||||
 | 
						if (IS_ENABLED(CONFIG_PROC_FS)) {
 | 
				
			||||||
 | 
							net->can.bcmproc_dir =
 | 
				
			||||||
 | 
								proc_net_mkdir(net, "can-bcm", net->proc_net);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void canbcm_pernet_exit(struct net *net)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* remove /proc/net/can-bcm directory */
 | 
				
			||||||
 | 
						if (IS_ENABLED(CONFIG_PROC_FS)) {
 | 
				
			||||||
 | 
							if (net->can.bcmproc_dir)
 | 
				
			||||||
 | 
								remove_proc_entry("can-bcm", net->proc_net);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static struct pernet_operations canbcm_pernet_ops __read_mostly = {
 | 
				
			||||||
 | 
						.init = canbcm_pernet_init,
 | 
				
			||||||
 | 
						.exit = canbcm_pernet_exit,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __init bcm_module_init(void)
 | 
					static int __init bcm_module_init(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
| 
						 | 
					@ -1699,17 +1726,14 @@ static int __init bcm_module_init(void)
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* create /proc/net/can-bcm directory */
 | 
						register_pernet_subsys(&canbcm_pernet_ops);
 | 
				
			||||||
	proc_dir = proc_mkdir("can-bcm", init_net.proc_net);
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void __exit bcm_module_exit(void)
 | 
					static void __exit bcm_module_exit(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	can_proto_unregister(&bcm_can_proto);
 | 
						can_proto_unregister(&bcm_can_proto);
 | 
				
			||||||
 | 
						unregister_pernet_subsys(&canbcm_pernet_ops);
 | 
				
			||||||
	if (proc_dir)
 | 
					 | 
				
			||||||
		remove_proc_entry("can-bcm", init_net.proc_net);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module_init(bcm_module_init);
 | 
					module_init(bcm_module_init);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue