tun驱动之open

tun驱动对应的设备文件是:/dev/net/tun,其详细信息如下:

crw-rw-rw- 1 root root 10, 200 2月  26 08:05 tun

主次设备号的定义如下:

#define MISC_MAJOR 10

#define TUN_MINOR 200

由于tun驱动属于misc设备驱动,因此用户调用open打开/dev/net/tun时,会调用到misc_open。

static int misc_open(struct inode *inode, struct file *file)
{
	int minor = iminor(inode);
	struct miscdevice *c;
	int err = -ENODEV;
	const struct file_operations *new_fops = NULL;

	mutex_lock(&misc_mtx);

	// 根据次设备号,查找miscdevice,获取其fops(对于tun设备,就是tun_fops)
	list_for_each_entry(c, &misc_list, list) {
		if (c->minor == minor) {
			new_fops = fops_get(c->fops);
			break;
		}
	}

	if (!new_fops) {
		mutex_unlock(&misc_mtx);
		request_module("char-major-%d-%d", MISC_MAJOR, minor);
		mutex_lock(&misc_mtx);

		list_for_each_entry(c, &misc_list, list) {
			if (c->minor == minor) {
				new_fops = fops_get(c->fops);
				break;
			}
		}
		if (!new_fops)
			goto fail;
	}

	/*
	 * Place the miscdevice in the file's
	 * private_data so it can be used by the
	 * file operations, including f_op->open below
	 */
	file->private_data = c;

	err = 0;
	replace_fops(file, new_fops); // 将file->f_ops设置为tun_fops
	if (file->f_op->open)
		err = file->f_op->open(inode, file); // 调用tun_fops
fail:
	mutex_unlock(&misc_mtx);
	return err;
}

 代码中已经加了注释,最终调用到tun_fops中的open,即tun_chr_open。

static int tun_chr_open(struct inode *inode, struct file * file)

{

struct net *net = current->nsproxy->net_ns;

struct tun_file *tfile;

DBG1(KERN_INFO, "tunX: tun_chr_open\n");

// sk_alloc返回struct sock类型,tun_file第一个成员是struct sock类型,所以可以进行类型转换

tfile = (struct tun_file *)sk_alloc(net, AF_UNSPEC, GFP_KERNEL,

&tun_proto, 0);

if (!tfile)

return -ENOMEM;

RCU_INIT_POINTER(tfile->tun, NULL);

tfile->flags = 0;

tfile->ifindex = 0;

init_waitqueue_head(&tfile->wq.wait);

RCU_INIT_POINTER(tfile->socket.wq, &tfile->wq);

tfile->socket.file = file;

tfile->socket.ops = &tun_socket_ops;

sock_init_data(&tfile->socket, &tfile->sk);

tfile->sk.sk_write_space = tun_sock_write_space;

tfile->sk.sk_sndbuf = INT_MAX;

file->private_data = tfile;

INIT_LIST_HEAD(&tfile->next);

sock_set_flag(&tfile->sk, SOCK_ZEROCOPY);

memset(&tfile->tx_array, 0, sizeof(tfile->tx_array));

return 0;

}

 sk_alloc申请的内存的大小,是由tun_proto.obj_size来指定的。上面的代码中,比较重要的几个地方,已经加粗。下面是涉及到的两个结构。

struct tun_file {

struct sock sk;

struct socket socket;

struct socket_wq wq;

... ...

};

static struct proto tun_proto = {

.name = "tun",

.owner = THIS_MODULE,

.obj_size = sizeof(struct tun_file), // 指定动态申请的tun_file大小

};

最后做下总结:用户空间打开/dev/net/tun驱动文件时,最终是调用tun_chr_open来处理的。在tun_chr_open中申请struct tun_file结构,并进行了相关字段的初始化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值