在 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操作系統》,推薦該課程。