在 ip_queue_xmit 中,也即 IP 层的发送函数里面,有三部分逻辑。第一部分,选取路由,也即我要发送这个包应该从哪个网卡出去。
这件事情主要由 ip_route_output_ports 函数完成。接下来的调用链为:ip_route_output_ports->ip_route_output_flow->__ip_route_output_key->ip_route_output_key_hash->ip_route_output_key_hash_rcu。
ip_route_output_key_hash_rcu 先会调用 fib_lookup。FIB 全称是 Forwarding Information Base,转发信息表。其实就是咱们常说的路由表。
一个著名的实现,就是内核模块 ip_tables。在用户态,还有一个客户端程序 iptables,用命令行来干预内核的规则。
iptables 有表和链的概念,最终要的是两个表。filter 表处理过滤功能,主要包含以下三个链。
- INPUT 链:过滤所有目标地址是本机的数据包
- FORWARD 链:过滤所有路过本机的数据包
- OUTPUT 链:过滤所有由本机产生的数据包
nat 表主要处理网络地址转换,可以进行 SNAT(改变源地址)、DNAT(改变目标地址),包含以下三个链。
- PREROUTING 链:可以在数据包到达时改变目标地址
- OUTPUT 链:可以改变本地产生的数据包的目标地址
- POSTROUTING 链:在数据包离开时改变数据包的源地址
在这里,网络包马上就要发出去了,因而是 NF_INET_LOCAL_OUT,也即 ouput 链,如果用户曾经在 iptables 里面写过某些规则,就会在 nf_hook 这个函数里面起作用。
此文章为11月Day24学习笔记,内容来源于极客时间《趣谈Linux操作系统》,推荐该课程。