tun驱动之open

news/2024/10/31 2:21:16/

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


http://www.ppmy.cn/news/28209.html

相关文章

Java 主流日志工具库

日志系统 java.util.logging (JUL) JDK1.4 开始,通过 java.util.logging 提供日志功能。虽然是官方自带的log lib,JUL的使用确不广泛。 JUL从JDK1.4 才开始加入(2002年),当时各种第三方log lib已经被广泛使用了JUL早期存在性能问题&#x…

2023年三月份图形化三级打卡试题

活动时间 从2023年3月1日至3月21日,每天一道编程题。 本次打卡的规则如下: 小朋友每天利用10~15分钟做一道编程题,遇到问题就来群内讨论,我来给大家答疑。 小朋友做完题目后,截图到朋友圈打卡并把打卡的截图发到活动群…

【C++】类与对象理解和学习(下)

放在专栏【C知识总结】,会持续更新,期待支持🌹建议先看完【C】类与对象理解和学习(上)【C】类与对象理解和学习(中)本章知识点概括Ⅰ本章知识点概括Ⅱ初始化列表前言在上一篇文章中,…

【数据结构】二叉树的四种遍历方式——必做题

写在前面学完上一篇文章的二叉树的遍历之后,来尝试下面的习题吧开始做题144. 二叉树的前序遍历 - 力扣(LeetCode)94. 二叉树的中序遍历 - 力扣(LeetCode)145. 二叉树的后序遍历 - 力扣(LeetCode&#xff09…

C#:Krypton控件使用方法详解(第九讲) ——kryptonRadioButton

今天介绍的Krypton控件中的kryptonRadioButton,这是一个单选按钮控件。下面开始介绍这个控件的属性:首先介绍的是外观属性,如下图所示:Cheacked属性:表示设置kryptonRadioButton控件的初始选中状态是什么样的&#xff…

Java-重排序,happens-before 和 as-if-serial 语义

目录1. 如何解决重排序带来的问题2. happens-before1. 如何解决重排序带来的问题 对于编译器,JMM 的编译器重排序规则会禁止特定类型的编译器重排序。对于处理器重排序,JMM 的处理器重排序规则会要求编译器在生成指令序列时,插入特定类型的内…

Python控制CANoe使能TestCase

前面介绍了多种CANoe配置下的dbc文件添加,常见的配置我们能够常用的就是testcase的使能和环境变量的设置,针对于环境变量的问题,我们下次再进行详聊,今天主要聊一下测试脚本的使能。在做这块之前,我们第一步就需要了解我们的测试脚本的层级是都包含有哪些? 一、测试脚本结…

typedef在c语言中的作用

在 C 语言中,typedef 是一个非常有用的关键字,用于给数据类型定义一个新的名字。typedef 的作用有以下几个方面: 定义新类型名:typedef 可以定义一个新的数据类型名称,使得该类型名称可以在程序中使用。这样可以提高代…