OVS(Open vSwitch)注包
OVS注包的場景:
UCloud的SDN網路是基於OVS做的。為了進行內網監控,需要測試用戶的兩台雲主機通信是否正常。但是,作為服務方我們是無法登陸到用戶的雲主機的。因此,採用了向源端的OVS中注入一個ping包的方法測試網路是否正常。
基本原理
- 實驗環境示意圖:實現不登陸進SRC VM的前提下,發送Ping的請求包給DST VM,並捕獲返回的應答包Ping Response。
- 染色:
用戶有可能自己也會發送Ping包,為了區分用戶的應答包和注入方式得到的應答包,需要對注入的Ping Request進行染色。首先看下ICMP包的格式,如下所示。
黃色標記起來的Identifier欄位含義如下(RFC 792)
The identifier and sequence number may be used by the echo sender to aid in matching the replies with the echo requests
通過設置Identifier的值,可以區分不同的請求對應的應答包。
這裡我們設置Identifier=111,捕獲數據包時,需要指定ICMP包 icmp[4:2]=111,表明ICMP的第四、第五個位元組的值等於111.
- 注入Ping Request包
需要使用ovs-ofctl packet-out進行注包操作,命令格式如下:
ovs-ofctl packet-out switch in_port actions packet...
說明:
1、packet-out:連接到OVS,並且讓OVS對Packet執行某個Action
Connects to switch and instructs it to execute the OpenFlow actions on each packet
2、switch:交換機的名字,比如實驗環境中的br0
3、in_port:SRC VM連接到OVS的埠號,就是實驗環境示意圖中的In Port
4、packet:數據包,實驗中就是染了色的Ping Request數據包。
5、Action:關鍵是Action的選擇,我們採用的是resubmit,說明如下。resubmit會找到數據包對應的流表,替換掉in_port並執行流表中的Action。
- resubmit([port],[table]):Re-searches this OpenFlow flow table with the in_port field replaced by port and executes the actions found
- 捕獲Ping的Response包
採用tcpdump進行捕獲染了色的Ping數據包。命令如下
tcpdump -c 1 -i VIRTUAL_INTERFACE icmp and src host SRC_IP and dst host DST_IP and icmp[4:2]=111
1. VIRTUAL_INTERFACE: 雲主機使用虛擬網卡的名字
2. SRC_IP:源雲主機的IP地址
3. DST_IP:目的雲主機的IP地址
4. 111:染色標記
golang實現的主邏輯
injectICMPCmd = util.GetInjectICMPPacket(srcIp, dstIp, srcMac, dstMac) //構造染了色的Ping Request包,以及注入命令tcpDumpCmd = util.TcpDumpICMPCommand(iface, srcIp, dstIp) //構造tcpdump的抓包命令tcpDumpResponse := make(chan string)srcHostIp := "XXX" //宿主機的IP地址go func() { command := fmt.Sprintf( "ssh %s@%s %s", "root", srcHostIp, tcpDumpCmd) util.SshRunWithChannelResponse(command, tcpDumpResponse)}() // inject Packet into OVStime.Sleep(100 * time.Millisecond)go func() { command := fmt.Sprintf( "ssh %s@%s %s", "root", srcHostIp, injectICMPCmd) util.SshRun(command)}() success := trueselect {case msg := <-tcpDumpResponse: if strings.Contains(msg, dstIp) { fmt.Printf("Checking Success, Response: %s
", msg) } else { success = false fmt.Printf("Checking Fail, Response: %s
", msg) }}return success
推薦閱讀:
※Inside Cisco IOS Software Architecture(第八章,QoS)
※浩方等對戰平台的原理是什麼?
※怎麼在移動端調試web前端?
※蘋果自家的 Web 伺服器和開發語言用的是什麼方案?
※Cookie 從哪裡來,網站用它來幹嘛?