Try   HackMD

Virtual Router 學網路 - 從 0 到 100 的 ping

tags: virtual-router, arp, icmp, ping

Source code: https://github.com/kevinbird61/virtual-router
Author: Kevin Cyu, kevinbird61@gmail.com

學習目標

  1. ping 指令的使用
  2. 節點間如何尋找彼此位置 - ARP
  3. Routing
  4. 網路控制協定 - ICMP (Internet Control Message Protocol)

說明

參考我們的實驗拓樸:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

  • 我們現在從 namespace 的一端 h1 (10.0.0.1) 發起 ping 到另一個 namespace h2 (10.0.1.1)
    • 注意: windows 版本的 ping 與 linux 版本的在封包上有些微的差異存在 (ICMP 的部分)
  • 此時我們從 ARP 的原理可以知道,ARP 可以用來查找目標節點的 MAC address,讓封包得以正確的傳遞給目標; 而我們的角色此時是 router,因此與 h1 對接的 port1 此時就會收到 h1 發出的 arp request, 藉此得知 port1 的 MAC address。
    • 注意: 發出 ARP request 的用戶只知道對方的 ip address,但不知道其 MAC address。
    • 為何 h1 ping h2 會先詢問 port1 資訊? 原因是在 h1 與 h2 互為不同的 network domain,而此時需要中間的 gateway 來做轉發才能夠將彼此的流量傳輸到正確的位置。 因此我們在建立虛擬拓樸時,便將一條 route 加到各自的 namespace 上來指定當目標匹配這些 rule 時,需要先經過指定的 gateway。使這些 network namespace 能夠依據這條 route 來對這個 gateway 做位置的確認,也就是發出 ARP 的動作。
  • 在解釋 router 收到 arp 行為前,我們先分析一下 arp 的封包格式:
    • arp 為 layer 3 的 protocol,位於 layer 2 (e.g. Ethernet) 之上
    • 封包當中主要夾帶的資訊有:
      • sender ip: 發送者的 IP
      • sender mac: 發送者的 MAC
      • target ip: 目標的 IP
      • target mac: 目標的 MAC
      • opcode: 決定該 arp packet 的操作種類 (request/reply )
    • 當 opcode 為 arp request 時, target mac 為空,並且 L2 ethernet 的 destination mac address 為 broadcast
    • 而當目標收到 arp request 後,接著便會送回 arp reply; 此時的 sender 為目標, 而 target 則為 request 發起者,此時這四個主要資訊都是填寫完畢,並且 L2 ethernet 也是以 unicast 的方式送回去。
  • 當我們 router 收到 ARP 時,target ip 為我們 port1 的 IP,因此在收到這個 arp 時,我們便直接回覆 arp reply 給 h1; h1 在收到 arp reply 後便得知這個 gateway 是活著的,因此接下來則會將 ICMP 發出給 port1,讓 port1 來轉發給目標 h2;
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →
  • 再根據 routing table 中的內容,來將封包正確轉給正確的 port 做轉送
  • 而我們 router (port2) 查找 h2 資訊時,發現 arp cache 沒有該筆資料,因此發出 arp request 來詢問與 port2 相同網域的機器有無 h2 的資訊; h2 再收到 arp request 後一樣回復 arp reply 回來,因此 port2 也更新自己的 arp cache;
  • 此時 ICMP 的封包再來就能夠將其導向到正確的位置上,完成流量的轉發 ( 反之從 h2 回去的 ICMP echo reply 也是類似的處理流程! )
    Image Not Showing Possible Reasons
    • The image file may be corrupted
    • The server hosting the image is unavailable
    • The image path is incorrect
    • The image format is not supported
    Learn More →

    前兩個 packet 用來觸發 arp 更新,被目前實作的版本給 drop 掉,導致 ping 顯示前兩個封包遺失

  • 當 host 送 ping 給 port 時,Virtual router 便需要收上來處理 ICMP 封包,將 echo request 更改成 echo reply,以及相關的 mac address 修改完成後再送回去給 Host:
    • ping
      Image Not Showing Possible Reasons
      • The image file may be corrupted
      • The server hosting the image is unavailable
      • The image path is incorrect
      • The image format is not supported
      Learn More →
    • router's debug message
      Image Not Showing Possible Reasons
      • The image file may be corrupted
      • The server hosting the image is unavailable
      • The image path is incorrect
      • The image format is not supported
      Learn More →

執行程式

  • 執行 .scripts/create_topo.sh 來建立我們測試用的網路
    • 腳本會建立兩個 tuntap client: tap0, tap1
  • 執行我們的 virtual router: ./router -i tap0 tap1 來讀取這兩個 tap0 tap1 作為我們 router port; 並將收到的封包抓起來做後續處理
    • 注意: 預設是將 debug mode 關掉,所以要顯示所有封包資訊請在 router.exe 啟動後輸入 debug packet
  • 透過 ip netns exec <host> 來呼叫 namespace 中的 host 執行特定指令,像是流量產生: ip netns exec h1 ping 10.0.1.1,從 h1 產生 ping 流量到 h2 上。