tun驱动之open
创始人
2024-05-27 00:09:11

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_fopsif (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结构,并进行了相关字段的初始化。

相关内容

热门资讯

冰箱性能排行榜TOP3 学生党... 深夜赶论文时顺手拿出一盒酸奶,周末囤几瓶冰可乐犒劳自己,期末前把水果蔬菜分层码放避免串味——这些看似...
即便市场走势不明 坚持持仓仍有... 当前美股市场走弱,部分投资者计划缩减股票持仓、待行情明朗后重新进场,该内容指出这并非最优策略,建议长...
英特尔涨幅达220% 代工业务... 英特尔近期股价从17美元上方攀升至65美元以上,累计涨幅超220%,市值突破7000亿美元,市场已不...
SOL价格取决于65美元关口 ... 核心事件:截至2026年6月28日,索拉纳(SOL)进入关键行情抉择阶段,当前报价71美元,自202...
诺和诺德公布多项在华合作 启动... 经济观察网 诺和诺德于链博会公布多项在华合作布局,同时启动最高112亿丹麦克朗股票回购计划。全产业链...