STT協議全稱是Stateless Transport Tunneling Protocol,是nicira.com給ietf提交的一個隧道協議的draft
http://tools.ietf.org/html/draft-davie-stt-01
STT是一種mac over ip的協議,和vxlan, nvgre類似,都是把二層的幀封裝在一個ip報文的payload中,在ip報文的payload中,除了虛擬網路的二層包以外,還要把構造的一個tcp頭,和一個stt頭加在最前面,可以參考上面文檔第9頁的圖
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Version | Flags | L4 Offset | Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Max. Segment Size | PCP |V| VLAN ID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ Context ID (64 bits) +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Padding | data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +
| |
Figure 3: STT Frame Format
是STT的頭結構
Version 為0
Flags一共有8位,bit0表示csum已經被驗證,bit1表示csum只是在tcp/ip為包頭的情況下才會被計算,由於STT必然會利用TSO/LRO的特性來提高效能,所以這兩位基本都是01。bit2表示IP協議版本,1表示ipv4,0表示ipv6,那麼如果是arp呢?我個人認為應該是0,表示一種non-ip protocol,bit3表示L4版本,1表示TCP,0表示其他,說實話我覺得這兩位沒啥用。剩下bit4-bit7保留,全部裝置0
L4 Offset 表示STT頭+TCP頭的長度
MSS,STT frame(即STT包頭+payload)是要按照這個MSS的大小分段的,分段之後每個段會加上TCP包頭,利用TSO機制交給網卡
PCP表示優先順序,可以不設
V|VLAN是VLAN相關的設定,略過了
Context ID表示tenant ID,每個租戶不同
STT依賴於TSO和LRO(GRO)的特性,所以STT協議很聰明的在STT頭前面增加了TCP頭,把自己偽裝成一個TCP包,但和TCP協議不同的是,這隻是一個偽裝的TCP包,既沒有3次握手的流程,也沒有用到TCP那些擁塞控制,丟包重傳,因此這個TCP頭是精心構造出來的,目的是利用網卡的TSO/LRO功能,把分段/合并功能和TCP校檢轉移到網卡上去做
STT構造的TCP頭和一般的TCP結構上沒有區別,但填的資料不同
Source Port和Dst Port都是隨機選的,注意Dst Port 的範圍在1024 - 49151之間,Src Port的範圍建議在49152 - 65535之間,對於tunnel兩個固定的endpoint而言,兩者之間的通訊應該用固定的Source/Destination Port
SEQ/ACK 也不會用做視窗重傳或者擁塞控制,而是用作一個STT frame的分段/合并,所以被分段的同一STT frame,其TCP頭的ACK欄位都是相同的,不同STT frame的ACK欄位不同。SEQ的高16位,用於記錄STT frame的長度(byte為單位),低16位用於記錄當前STT frame 分段的位移量(byte為單位)
其他的位基本沒用,都可以置0,除了最後一個STT frame分段對ACK,PSH兩個bit置位
這裡拋出個問題,如果被分段的ip包在傳輸中間丟了幾個段怎麼辦?STT endpoint是不會去要求重傳的,實際上,STT endpoint只是利用了LRO來接收tcp payload,經過解包之後,得到虛擬網路的二層包交給vm處理,一定記住tunnel裡是個不可靠通訊通道,如果需要可靠通訊需要vm的tcp stack去保證
還有一點,STT endpoint 需要給STT預留TCP port,所有發往這個port的tcp包會被認為是STT包,從而不會走正常的tcp stack路徑