起因:
最近在完成网关的一个相关功能时,对于网关本身通过socket发送的数据包,没有从正确的wan接口发送出去,但是在udp_sendmsg
函数里打印出来的
信息显示路由查找是正确的,但是当数据包进入OUTPUT HOOK点的hook函数处理后,其路由缓存就发生了变化,难道netfilter模块还
会修改数据包的路由缓存吗?
本文主要是因为上面所说的问题而进行分析的,其实也就是自己阅读netfilter的代码不够仔细,导致没有注意到netfilter模块也会改变数据包的
路由缓存,
所以本文以此命题,以提醒自己。
1. 修改数据包路由缓存的case
修改数据包的路由缓存,按模块来分,可分为两个方面
NAT模块:
a)在PRE_ROUTING链,当修改了数据包的目的地址后,若数据包的dst指针不为空,则需要release该dst指针,迫使协议栈重新查找路由
(但是这个查找路由还是由协议栈实现的)。
b)在OUTPUT链,当修改了数据包的目的地址后,由于此时的数据包已经进行了路由查找,接下来协议栈也不会再进行路由查找,所以此时
就会调用ip_route_me_harder重新查找路由,这次查找就由netfilter模块代劳了 MANGLE模块
a)在OUTPUT链,当修改了数据包的源ip地址/目的ip地址/tos/mark后,则会调用函数ip_route_me_harder
综上,可以发现。当netfilter模块修改了数据包的ip地址、tos或者mark后,若是后续协议栈还会进行路由查找,则netfilter模块只是将数据包的dst指针
设置为空; 若后续协议栈不再进行路由查找了,则netfilter模块则会自己调用路由查找函数,为数据包重新查找路由。
例如,当我们在mangle表的OUTPUT链,增加了一个修改数据包的mark值的规则后,就需要小心了,如果我们使用了策略路由,增加了策略规
则参数,但是ip_route_me_harder里却没有在flowi的查找变量里增加对该变量的设置后,就可能使策略路由匹配出错。
在我实现的功能里,就在策略规则里增加了新的判断成员,但是仅仅考虑了协议栈中路由查找的函数,却忘了在netfilter模块的路由查找函数里也
增加对该成员的判断,从而对本地发出的数据包,出现策略路由匹配失败的问题。
也怪自己没有对路由代码有一个全面的分析,对于路由查找还不是很熟悉,后面会开始学习路由。