linux网络驱动 协议栈,linux网络协议栈结构

本结构框图

178d49f5ecfd48d27c6a35e62717b7f7.gif

引用的,出处未知...

协议栈结构的说明

1、驱动中,使用ISR/POLL/NAPI等方式从硬件收包

2、收包接口中通过netif_receive_skb()上交协议栈

3、在netif_receive_skb()函数中做协议解析

core/dev.c中,为报文处理的第二层,用于分离收到的以太网报文的协议类型,同我们某产品上一个叫做Packet Handler模块一样,逐级分发报文。

该模块有一个list_head链表,链表上挂了很多packet_type数据结构,packet_type数据结构中包括ether_type, dev指针以及func指针等成员。

为加快对报文的分发速度,这个链表实现成了一个HASH表,共16way,使用ethertype作为索引。

内核中常注册的ethertype类型:

ETH_P_IP

ETH_P_ARP

ETH_P_HDLC

ETH_P_DEC

ETH_P_PPP

PKT_TYPE_LACPDU

ETH_P_PPP_SES

ETH_P_PPP_DISC

ETH_P_BPQ

ETH_P_PARP

ETH_P_802_2

ETH_P_TR_802_2

ETH_P_X25

ETH_P_8021Q

ETH_P_ALL用于所有

其中Func是上层协议的钩子函数,常用的有ip_rcv()和arp_rcv()等,然后iprcv()中又会解析ip上的协议,调用icmp_rcv/igmp_rcv/udp_rcv/tcp_rcv()等等。

新的协议类型可以在驱动模块加载时,通过下面的接口增加到packet_type_list中:

void dev_add_pack()用于增加一种协议类型,将其packet_type指针加到链表上。

void dev_remove_pack()用于从list_head上删除一种协议类型

4、解析完报文协议之后,将报文放到skb_queue队列中

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);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值