skb_queue为系统底层与应用程序之间一个接口 。所有接收到的同类报文都会被挂到这个队列上,然后由协议栈上层接口来取 。
5、 协议上层接口通过系统调用获取skb 。代码位于net模块下:
sys_recv()
sys_recvfrom()
sock_recvmsg()
__sock_recvmsg()
udp_recvmsg()或者tcp_recvmsg()
__skb_recv_datagram()
ip_cmsg_recv()
从skb接收队列skb_queue收包
某项目中的代码
1. 驱动driver使用NAPI方式,从硬件queue中收包
2. 调用netif_receiv_skb()函数,上交收到的报文
这个项目支持NAPT,因此会在该函数中直接调用NAPT回调做NAT,而对于非NAPT印射的报文,进行如下处理:
先遍历ptype_all链表,list_for_each_entry_rcu(),最终调用packet_type.func()
编译内核时选上BRIDGE,则会执行网桥模块br_handle_frame_hook(skb),源文件为bridge/br.c
网桥模块的初始化pkt_type为PACKET_HOST或者PACKET_OTHERHOST
如果编译内核时选上了mac_VLAN模块,则会执行macvlan_handle_frame_hook
初始化为PACKET_BROADCAST、PACKET_MULTICAST、PACKET_HOST
最后一步,判断type==skb->protocol,会查询链表,找到匹配的protocol钩子并且调用 。
3. Skb的释放时机
如果是合法报文,放入接收队列,在用户系统调用取包时释放,否则在netif_receiv_skb()函数中释放 。
802.1q协议模块实现
带802.1qTAG的模块有自己单独的协议类型,一般是0x8100 。使用前面说的packet_list操作接口注册一个新的packet_type挂到链表中,这样,所有带TAG的报文会被转发到802.1q的接口上 。
应用程序里,每调用vconfig创建一个VLAN,就会创建一个新的net device,这个虚拟扩展的net device会在原来物理的net device上面工作,将VLAN对应的报文都转移到虚拟net device的收发接口上 。
new_dev = alloc_netdev(sizeof(struct vlan_dev_info), name,vlan_setup);
推荐阅读
- Windows和Linux通吃,最新远控木马“Dacls”来袭
- 利用Zabbix监控工具自动帮我们检测目标网络状况
- 细品Linux系统中文件的三个时间属性
- 山东日照绿茶产销新变化店面销变网络卖
- 日照:全面排查网络经营业户保护和提升“日照绿茶”品牌形象
- 开源交换机操作系统
- 如何在 Ubuntu 和其它 Linux 发行版上更新 grub
- Linux发行版之一CentOS的安装与网卡配置
- Linux系统管理命令:openssl
- 有趣的arp攻击
