博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
tun/tap 设备
阅读量:4216 次
发布时间:2019-05-26

本文共 2704 字,大约阅读时间需要 9 分钟。

tun/tap是一个虚拟网卡驱动,为用户态程序提供网络数据包的发送和接收能力,tun/tap 包含一个字符设备驱动和一个网卡驱动,利用网卡驱动接收来自tcp/ip协议栈的网络分包并发送或者将接收到的网络分包传给协议栈处理。用户可以通过ip tuntao add veth1 mode tap的方式来创建tap设备其驱动是一个ko,源码在drivers/net/tun.c中从下面的入口函数可以和明显看到tun分为字符设备和模拟物理链路部分static int __init tun_init(void){	int ret = 0;	pr_info("%s, %s\n", DRV_DESCRIPTION, DRV_VERSION);#模拟物理链路部分用于数据的发送和接收	ret = rtnl_link_register(&tun_link_ops);	if (ret) {		pr_err("Can't register link_ops\n");		goto err_linkops;	}#注册字符设备,主要用于将从用户空间copy数据	ret = misc_register(&tun_miscdev);	if (ret) {		pr_err("Can't register misc device %d\n", TUN_MINOR);		goto err_misc;	}#注册通知链	ret = register_netdevice_notifier(&tun_notifier_block);	if (ret) {		pr_err("Can't register netdevice notifier\n");		goto err_notifier;	}	return  0;}从字符设备的poll函数中可以看到是通过ptr_ring_empty来检测队列是否为nullstatic __poll_t tun_chr_poll(struct file *file, poll_table *wait){	struct tun_file *tfile = file->private_data;	struct tun_struct *tun = tun_get(tfile);	struct sock *sk;	__poll_t mask = 0;	if (!tun)		return EPOLLERR;	sk = tfile->socket.sk;	tun_debug(KERN_INFO, tun, "tun_chr_poll\n");	poll_wait(file, sk_sleep(sk), wait);#检测队列是否为null,如果不为空的话,最后会调用tun_chr_read_iter来读,也就是从user space读到kernel space	if (!ptr_ring_empty(&tfile->tx_ring))		mask |= EPOLLIN | EPOLLRDNORM;	/* Make sure SOCKWQ_ASYNC_NOSPACE is set if not writable to	 * guarantee EPOLLOUT to be raised by either here or	 * tun_sock_write_space(). Then process could get notification	 * after it writes to a down device and meets -EIO.	 */	if (tun_sock_writeable(tun, tfile) ||	    (!test_and_set_bit(SOCKWQ_ASYNC_NOSPACE, &sk->sk_socket->flags) &&	     tun_sock_writeable(tun, tfile)))		mask |= EPOLLOUT | EPOLLWRNORM;	if (tun->dev->reg_state != NETREG_REGISTERED)		mask = EPOLLERR;	tun_put(tun);	return mask;}如果需要发送数据的话,则调用tun_chr_write_iterstatic ssize_t tun_chr_write_iter(struct kiocb *iocb, struct iov_iter *from){	struct file *file = iocb->ki_filp;	struct tun_file *tfile = file->private_data;	struct tun_struct *tun = tun_get(tfile);	ssize_t result;	if (!tun)		return -EBADFD;#新建skb 来发送数据	result = tun_get_user(tun, tfile, NULL, from,			      file->f_flags & O_NONBLOCK, false);	tun_put(tun);	return result;}当调用ioctl中的TUNSETIFF	if (cmd == TUNSETIFF) {		ret = -EEXIST;		if (tun)			goto unlock;		ifr.ifr_name[IFNAMSIZ-1] = '\0';#创建网络设备		ret = tun_set_iff(net, file, &ifr);		if (ret)			goto unlock;		if (copy_to_user(argp, &ifr, ifreq_len))			ret = -EFAULT;		goto unlock;	}最终通过alloc_netdev_mqs来注册网络设备,这样就可以通过网口来发送和接收数据static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr){			dev = alloc_netdev_mqs(sizeof(struct tun_struct), name,				       NET_NAME_UNKNOWN, tun_setup, queues,				       queues);		if (!dev)			return -ENOMEM;	}

 

转载地址:http://lsnmi.baihongyu.com/

你可能感兴趣的文章
【屌丝程序的口才逆袭演讲稿50篇】第七篇:请留意我们身边的风景 【张振华.Jack】
查看>>
【屌丝程序的口才逆袭演讲稿50篇】第八篇:坚持的力量 【张振华.Jack】
查看>>
【屌丝程序的口才逆袭演讲稿50篇】第九篇:春节那些事-过年回家不需要理由【张振华.Jack】
查看>>
【屌丝程序的口才逆袭演讲稿50篇】第十篇:程序员们请看看外面的世界吧【张振华.Jack】
查看>>
【屌丝程序的口才逆袭演讲稿50篇】第十一篇:马云乌镇40分钟演讲实录【张振华.Jack】
查看>>
Java并发编程从入门到精通 张振华.Jack --我的书
查看>>
【屌丝程序的口才逆袭演讲稿50篇】第十二篇:世界上最快的捷径【张振华.Jack】
查看>>
Android中Java代码和XML布局效率问题
查看>>
android TextView属性大全(转)
查看>>
Conclusion for Resource Management
查看>>
Conclusion for Constructors,Destructors,and Assignment Operators
查看>>
Conclusion for Accustoming Yourself to C++
查看>>
面试题1:赋值运算函数(offer)
查看>>
面试题15:在O(1)时间删除链表结点
查看>>
面试题16:调整数组顺序使奇数位于偶数前面
查看>>
面试题17:链表中倒数第k个结点(offer)
查看>>
面试题18:反转链表
查看>>
面试题19:合并两个排序的链表(offer)
查看>>
QT之局域网聊天实现
查看>>
poco之文件系统
查看>>