《SDN淺談》這篇文章簡單介紹了SDN及其應用場景,臆測的成分大些。本文談談SDN的基石:openflow。
我們知道,SDN的核心是將control plane(下文統稱controller)和data plane(下文統稱oSwitch,openflow switch)分離,由一箇中央集權的controller(好比一個軍團的將領)指揮成百上千的oSwitch(好比千千萬萬的士兵),共同完成網絡中數據的傳輸。而openflow,as a protocol,是這套體系正常運作的基石。
本文難度稍大,可能不適合沒有網絡設備基礎知識的讀者閱讀。我會在下節中稍微講一些基礎概念,如果無法理解,則不建議讀下去。
1. 網絡基礎知識
- 網絡設備(下文統稱device)的運作遵循 ISO OSI 7層模型,但網絡設備本身一般只關心:port (physical layer),ethernet/VLAN header (link layer) [1],IP header (network layer) layer,TCP/UDP header (transport layer)。有些設備會繼續深入到application layer,如IPS,這裏略過不表。
- Ingress port:packets從device的哪個接口進入。
- Egress port:packets從device的哪個接口轉發出去。
- Vlan:將局域網邏輯上分成不同的虛擬網絡,網絡之間相互隔離。詳見 虛擬局域網。
- Switch:根據destination MAC/vlan id轉發packets的設備。一般會在網絡中學習MAC地址和port的對應關係,構建一個二層轉發表(forwarding database, or FDB)。
- Router:根據destination IP address轉發packets的設備。一般會通過路由協議來學習網絡中IP地址和port [2]的對應關係,構建一個三層轉發表(routing table/forwarding information table, or RIB/FIB)。
- Firewall:根據5 tuple(src IP/src port/dst IP/dst port/protocol)及ingress port轉發packets的設備。一般會通過配置靜態策略(policy)來決定packets如何轉發。在TCP/UDP連接建立時會創建session,構建一個四層轉發表(session table)來使能雙向數據的轉發。
- unicast, broadcast, multicast這些概念就不多說,翻翻教科書就知道了。
- packets處理方法:
- 轉發(可以是unicast, broadcast, multicast),總之把包轉到egress port。
- 丟棄:不滿足轉發要求,在device上丟棄,如找不到路由。
- enqueue:放入隊列等待後續處理。比如要做traffic shaping。
- 修改packet並reinject:根據規則對packet進行修改,如做source NAT(對源地址做網絡地址轉換),或者terminate VPN(將外層VPN包頭去掉),再將packets以一個新的ingress port丟回device處理。
- 如果到這裏還沒有暈的話,可以繼續讀下去。
2. OPENFLOW PACKETS處理
openflow定義了oSwitch端如何協同controller來處理網絡中的packets。這包含兩個部分:1) oSwitch端packets處理邏輯 2) oSwitch轉發依據,即oSwitch和controller之間的protocol。本文重點討論再oSwitch端,packets是如何處理的。
解決問題的思路
我們先放着openflow不表,看看網絡設備(switch,router,firewall)進行packets處理的共性,如下圖所示:
- 它們都有一張 table(或者叫database)做爲決策依據。
- table建立的依據是一系列的 rule。
- packets到達時,嘗試 match table中的某個entry。
- 如果match不到任何entry,會嘗試根據rule來創建entry,無法創建,就丟棄。
- 如果match到,則根據entry中的 action 來決定後續的處理。
這樣做的好處是:
- 低耦合,高內聚,每個部分解決一個問題。
- 便於硬件化。如上圖的TLU,TCU,TAU,爲performance可以部分或全部硬件化。
以相對複雜的firewall爲例,看看packets實際是如何處理的:
- client 1.1.1.1發起一個到server 2.2.2.2的SYN請求(TCP連接,端口爲12345->80),firewall得到這個SYN packet後,進行Table Lookup,因爲是第一次請求,所以找不到對應的entry。
- SYN packet進入到Table Creation Unit,查找有沒有相關的rule來建立entry ,結果找到一條,於是entry被創建出來,action是forward。
- SYN packet進入到Table Action Unit,按照entry的action進行處理,所以包被轉發到2.2.2.2。
- 服務器收到SYN packet後,發送SYN/ACK,SYN/ACK packet到達firewall,進行Table Lookup,找到一個entry。
- SYN packet進入到Table Action Unit,按照entry的action進行處理,所以包被轉發給client。
理解了這一思路後,openflow的packets處理方法就很容易明白了。
FLOW TABLE
openflow關心從L1-L4的所有packet header,從這點上看,oSwitch端的很多處理和firewall很像。
openflow定義了能夠match L1-L4 的flow entry:
其中,假定instructions使用64bit,那麼整個entry大小爲76bytes,如果能夠支持1M的flow,那麼flow table會消耗76M內存。
當packets到達時,openflow是如何match並處理呢?openflow-spec的這張圖講的很明白,我就不多說了:
openflow允許系統中存在一到多張flow table並且他們之間以一種pipeline的方式運行。
什麼情況下一個packet從一張flow table裏出來,進入另一張flow table呢?有不少這樣的case,我們說一個比較容易理解的。
~假定flow table 1存放IPSec VPN tunnel的flow entry,flow table 2存放普通flow entry。當一個IPSec packet進入flow table 1後match對應的flow entry,其instruction爲:1) decryption 2) FWD to flow table 2。當packet被解密,inner ip packet重見天日時,就可以用flow table 2中的flow entry進行轉發。
注:這個理解可能有些錯誤,因爲openflow規定flow table是有序的,但這個VPN in的例子如果換成VPN out的例子則flow table的順序正好相反,所以和openflow的spec violate...等筆者搞明白些再回過頭來修訂這個例子。
Update:
看Open vSwitch時想到一種multi table的模式:即L2,L3,L4各一張table。這說得過去,而且各個flow table是嚴格有序的。
INSTRUCTIONS
當packet match到一個flow entry後,要執行對應的instructions,openflow定義瞭如下instruction:
- Apply-Actions: 對packet立即執行某些action。
- Clear-Actions: 將packet上的action set清空。
- Write-Actions: 修改/添加packet上的action set。
- Write-Metadata: 修改flow entry的metadata。
- Goto-Table: 將packet轉到另外一張flow table。
單獨理解instructions有些困難,請繼續往下讀。
ACTION SET
每個packet都有一個action set,初始時爲空,當match flow entry時被修改。如果所有instruction都執行完,且沒有後續的Goto-Table instruction時,packet上的action set被執行(這裏也有個疑問,set一般是無序的,但action的執行必定有序,執行的先後對結果影響很大,我們姑且認爲是順序執行吧)。所以上述的instruction大部分實在操作packet上的action set,即定義我們如何進一步處理這個packet。
Action的執行按照如下順序:
- copy TTL inwards
- pop tag
- push tag
- copy TTL outwards
- decrement TTL
- modify packet (apply all set-field actions)
- qos
- group
- output
具體action的列表和作用請參考openflow-spec的p13-16。
我們舉一個簡單的例子,你在公司訪問google.com(假定IP是203.208.46.200)。你的局域網IP是10.0.0.222,ISP分配給你公司的公網IP是22.22.22.22。對於這樣一個很常見的網絡訪問,openflow需要應用如下actions:
- pop VLAN tag (if any)
- decrement TTL
- modify src IP from 10.0.0.222 to 22.22.22.22
- modify src port from X to Y
- output
3. OPENFLOW TABLE INSTALLATION
上文詳述了openflow的flow table如何定義,如何match和怎樣處理packets,完全是data plane的事兒。讀者一定有一個疑問,那麼flow table是如何install到oSwtich中?
這個問題的答案也是SDN的精華所在。我們知道,傳統的網絡設備,即使將data plane和control plane完全分離到不同的board上,還是在同一臺設備中做決策(control plane)及執行決策(data plane)。flow table的installation是由每臺網絡設備自行決定。而openflow在這裏將control plane完全分隔,在oSwitch/Controller之間運行protocol來傳遞消息,比如說:
- flow entry installation
- flow entry deletion
我們用下圖來詮釋oSwitch和Controller間如何來協作進行packet forwarding:
- 客戶端發出一個packet,到達oSwitch。
- oSwitch match flow table失敗,packet enqueue,同時發送flow entry inquiry給controller。
- Controller獲取相關的路由信息。
- Controller發送flow entry到各個相關的oSwitch。
- packet被依次forward到下一個oSwitch,直至到達destination。
當然,這是很被動的處理方式,first packet的latency會很高。其實也可以採取主動模式,Controller收集到拓撲信息後主動向各個oSwitch發送計算好的flow entries。
具體protocol的細節就不在本文詳述,看spec就好了。
4. 參考文檔
[1] open flow spec: http://www.openflow.org/documents/openflow-spec-v1.1.0.pdf
[2] open flow white paper: http://www.openflow.org/documents/openflow-wp-latest.pdf
5. 腳註
[1] 這裏指LAN主要使用的link layer protocol;WAN不在本文討論之列
[2] interface更爲準確,但這裏就不引入新概念了
摘自覓珠人博文