2.ip_rcv_finish
ip_rcv_finish首 先取得ip头的指针,然后检查skb->dst,如果此时还不知道此报文的目的地址,那么查询路由子系统得到dst。如果是上行的入报文,从前面的 总结来看,此时是不知道dst的,所以这种场景下肯定会入路由子系统查询。如果一切正常,那么做一下用于流量管理的统计计数。随后就是一个重要的 点:option的预处理。(注意这里选项的处理是在路由查询之前,而在报文出设备的情况下,顺序应该是相反的?)做完这些 后,ip_rcv_finish的工作完成,通过dst_input(skb)将接力棒传递给了下一站:ip_local_deliver或者 ip_forward。
3.ip_options_compile
这里完成options的"预处理",所谓的预处理是指这里并不作实际的option处理工作,只是根据入报文的option,设置skb_buff中的一些字段,方便后续的处理,这些信息包括:option中有哪些选项,这些选项相对于ip头的偏移各自是多少,处理这些选项是否需要更新校验和(isChanged指示)。ip_rcv_finish调用ip_rcv_options,由后者调用ip_options_compile,下面以一种option来仔细看看ip_options_compile的处理过程。
首先,ip_options_compile的工作可以说只是收集一些信息--填充输入的opt结构,因为不同的option的处理分布在各处,这里统一做 一个预处理是必要的。其次,ip_options_compile有两种被调用的环境:ip_rcv_finish,ip_options_get。上面 说的就是前者,至于ip_options_get以后将会谈及。ip_rcv_finish调用ip_options_compile时,传入的skb非空,opt为NULL;而ip_options_get调用ip_options_compile时,则恰恰相反(书中说skb为空,但是从代码来看并非 如此),这样,ip_options_compile就能判断出自己处在一种什么样的执行环境中了。
在ip_options_compile的开始处,会根据是何种环境,选择在适当的地方保存opt。