随笔分类 -  Linux内核协议栈

摘要:概述 IP层输出数据包会根据路由的下一跳查询邻居项,如果不存在则会调用__neigh_create创建邻居项,然后调用邻居项的output函数进行输出; __neigh_create完成邻居项的创建,进行初始化之后,加入到邻居项hash表,然后返回,其中,如果hash表中有与新建邻居项相同的项会复用 阅读全文
posted @ 2019-10-28 20:40 AlexAlex 阅读(1164) 评论(0) 推荐(0)
摘要:概述 邻居子系统支持多种实现,例如ARP,ND等,这些实现需要在其初始化的时候,调用neigh_table_init将邻居表项添加到全局邻居子系统数组中,并对实例中的字段(如hash,定时器等)进行相关初始化; 源码分析 分析过程以ARP为例,引出邻居表的初始化,在arp_init初始化中,调用ne 阅读全文
posted @ 2019-10-28 20:39 AlexAlex 阅读(1114) 评论(0) 推荐(0)
摘要:概述 ip_fragment函数用于判断是否进行分片,在没有设置DF标记的情况下进入分片,如果设置了DF标记,则继续判断,如果不允许DF分片或者收到的最大分片大于MTU大小,则回复ICMP,释放skb,其余情况仍然需要走分片; ip_do_fragment是详细的分片流程,整个过程分为快速分片和慢速 阅读全文
posted @ 2019-10-28 20:37 AlexAlex 阅读(3196) 评论(0) 推荐(0)
摘要:概述 ip_output-设置输出设备和协议,然后经过POST_ROUTING钩子点,最后调用ip_finish_output; ip_finish_output-对skb进行分片判断,需要分片,则分片后输出,不需要分片则知直接输出; ip_finish_output2-对skb的头部空间进行检查, 阅读全文
posted @ 2019-10-28 20:36 AlexAlex 阅读(2972) 评论(0) 推荐(1)
摘要:概述 ip层在构造好ip头,检查完分片之后,会调用邻居子系统的输出函数neigh_output进行输出,输出分为有二层头缓存和没有两种情况,有缓存时调用neigh_hh_output进行快速输出,没有缓存时,则调用邻居子系统的输出回调函数进行慢速输出; 源码分析 1 static inline in 阅读全文
posted @ 2019-10-28 20:36 AlexAlex 阅读(1910) 评论(0) 推荐(1)
摘要:概述 将要从本地发出的数据包,会在构造了ip头之后,调用ip_local_out函数,该函数设置数据包的总长度和校验和,然后经过netfilter的LOCAL_OUT钩子点进行检查过滤,如果通过,则调用dst_output函数,实际上调用的是ip数据包输出函数ip_output; 源码分析 1 in 阅读全文
posted @ 2019-10-28 20:35 AlexAlex 阅读(2379) 评论(1) 推荐(0)
摘要:概述 ip_queue_xmit是ip层提供给tcp层发送回调,大多数tcp发送都会使用这个回调,tcp层使用tcp_transmit_skb封装了tcp头之后,调用该函数,该函数提供了路由查找校验、封装ip头和ip选项的功能,封装完成之后调用ip_local_out发送数据包; ip_build_ 阅读全文
posted @ 2019-10-28 20:34 AlexAlex 阅读(2200) 评论(0) 推荐(0)
摘要:概述 tcp_transmit_skb的作用是复制或者拷贝skb,构造skb中的tcp首部,并将调用网络层的发送函数发送skb;在发送前,首先需要克隆或者复制skb,因为在成功发送到网络设备之后,skb会释放,而tcp层不能真正的释放,是需要等到对该数据段的ack才可以释放;然后构造tcp首部和选项 阅读全文
posted @ 2019-10-28 20:33 AlexAlex 阅读(2312) 评论(0) 推荐(0)
摘要:概述 tcp_write_xmit函数完成对待发送数据的分段发送,过程中会遍历发送队列,进行窗口检查,需要TSO分段则分段,然后调用tcp_transmit_skb发送数据段; 源码分析 1 static bool tcp_write_xmit(struct sock *sk, unsigned i 阅读全文
posted @ 2019-10-28 14:44 AlexAlex 阅读(2356) 评论(0) 推荐(0)
摘要:概述 sendmsg系统调用在tcp层的实现是tcp_sendmsg函数,该函数完成以下任务:从用户空间读取数据,拷贝到内核skb,将skb加入到发送队列的任务,调用发送函数;函数在执行过程中会锁定控制块,避免软中断在tcp层的影响;函数核心流程为,在发送数据时,查看是否能够将数据合并到发送队列中最 阅读全文
posted @ 2019-10-28 14:43 AlexAlex 阅读(1976) 评论(0) 推荐(0)
摘要:概述 recvmsg系统调用在tcp层的实现是tcp_recvmsg函数,该函数完成从接收队列中读取数据复制到用户空间的任务;函数在执行过程中会锁定控制块,避免软中断在tcp层的影响;函数会涉及从接收队列receive_queue,预处理队列prequeue和后备队列backlog中读取数据;其中从 阅读全文
posted @ 2019-10-28 14:42 AlexAlex 阅读(2438) 评论(0) 推荐(0)
摘要:概述 快速路径:用于处理预期的,理想情况下的数据段,在这种情况下,不会对一些边缘情形进行检测,进而达到快速处理的目的; 慢速路径:用于处理那些非预期的,非理想情况下的数据段,即不满足快速路径的情况下数据段的处理; 首部预测字段格式:首页预测字段,实际上是与TCP首部中的【头部长度+保留字段+标记字段 阅读全文
posted @ 2019-10-28 14:41 AlexAlex 阅读(1417) 评论(0) 推荐(0)
摘要:tcp_data_queue作用为数据段的接收处理,其中分为多种情况: (1) 无数据,释放skb,返回; (2) 预期接收的数据段,a. 进行0窗口判断;b. 进程上下文,复制数据到用户空间;c. 不满足b或者b未完整拷贝此skb的数据段,则加入到接收队列;d. 更新下一个期望接收的序号;e. 若 阅读全文
posted @ 2019-10-28 14:39 AlexAlex 阅读(1961) 评论(0) 推荐(0)
摘要:tcp_queue_rcv用于将接收到的skb加入到接收队列receive_queue中,首先会调用tcp_try_coalesce进行分段合并到队列中最后一个skb的尝试,若失败则调用__skb_queue_tail添加该skb到队列尾部; 1 static int __must_check tc 阅读全文
posted @ 2019-10-28 14:38 AlexAlex 阅读(1282) 评论(0) 推荐(0)
摘要:概述 tcp_rcv_established用于处理已连接状态下的输入,处理过程根据首部预测字段分为快速路径和慢速路径; 1. 在快路中,对是有有数据负荷进行不同处理: (1) 若无数据,则处理输入ack,释放该skb,检查是否有数据发送,有则发送; (2) 若有数据,检查是否当前处理进程上下文,并 阅读全文
posted @ 2019-10-28 14:31 AlexAlex 阅读(2552) 评论(0) 推荐(0)
摘要:在未开启tcp_low_latency的情况下,软中断将skb送上来,加入到prequeue中,然后 在未启用tcp_low_latency且有用户进程在读取数据的情况下,skb入队到prequeue,入队之后,若达到队列长度上限或者内存上限,则将队列中的skb出队,调用tcp_v4_do_rcv处 阅读全文
posted @ 2019-10-28 14:25 AlexAlex 阅读(988) 评论(0) 推荐(0)
摘要:tcp_v4_rcv函数为TCP的总入口,数据包从IP层传递上来,进入该函数;其协议操作函数结构如下所示,其中handler即为IP层向TCP传递数据包的回调函数,设置为tcp_v4_rcv; 1 static struct net_protocol tcp_protocol = { 2 .earl 阅读全文
posted @ 2019-10-28 13:44 AlexAlex 阅读(3519) 评论(0) 推荐(1)
摘要:概述 以前的TCP请求控制块没有独立的状态,而是依赖于他们的父控制块的状态,也就是TCP_LISTEN状态,现在要把请求控制块加入到全局的ehash中,所以需要一个状态,而TCP_SYN_RECV状态被fast open sokets使用了,所以新加了一个TCP_NEW_SYN_RECV状态; 以下 阅读全文
posted @ 2019-10-28 13:38 AlexAlex 阅读(2343) 评论(0) 推荐(0)
摘要:概述 在主动关闭方发送了FIN之后,进入FIN_WAIT_1状态,在此状态收到了ACK,则进入FIN_WAIT_2状态,而FIN_WAIT_2后续要做的工作是等待接收对端发过来的FIN包,并且发送ACK,进而进入到TIME_WAIT状态;本文主要关注从FIN_WAIT_1进入FIN_WAIT_2状态 阅读全文
posted @ 2019-10-28 13:35 AlexAlex 阅读(7515) 评论(0) 推荐(0)
摘要:概述 本文对两个LINGER相关的套接字选项进行源码层面的分析,以更明确其各自的作用和区别; man page SO_LINGER,该选项是socket层面的选项,通过struct linger结构来设置信息,如果启用该选项,那么使用close()和shutdown()(注意:虽然manpage这么 阅读全文
posted @ 2019-10-28 13:15 AlexAlex 阅读(2139) 评论(0) 推荐(0)