本文主要重點討論OpenFlow Switch規范的指令集,它們深刻影響着數據包在Switch中的處理行為,下面開始從以下幾個部分談起。
1、Instructions
每一個Flow Entry里都包含有一系列的Instructions,這些Instructions會在與該Flow Entry成功匹配的數據包上執行,進而導致數據包頭信息的修改、Action Set的更新或者改變Pipeline Processing的處理行為。Instructions大致有下列幾種類型,OpenFlow Switch不需要支持所有的類型,但是加黑的類型必須得支持:
1)Meter meter_id:將數據包直接轉發給指定的Meter處理。
2)Apply-Actions action(s):立即對數據包執行指定的action(s),而不是將這些action(s)更新到Actions Set中。這些action(s)可能會修改數據包的信息,它們以Action List的形式組織。
3)Clear-Actions:立即清除Actions Set中的所有action(s)。
4)Write-Actions action(s):將指定的action(s)合並到當前的Actions Set中;如果給定類型的action當前已經存在於Actions Set中,那么會覆寫,否則直接加入。
5)Write-Metadata metadata/mask:將指定的metadata值寫到當前的Metadata值域中。
6)Goto-Table next-table-id:指定了在Pipeline Processing中的下一張Flow Table。這里的table-id必須大於當前的Flow Table id,並且Pipeline的最后一張Flow Table中不能含有這個指令;如果僅有一張Flow Table的OpenFlow Switch也不能支持該指令。
每一個Flow Entry里每種類型(如上列表)的Instruction最多只能有一個,並且這些Instructins必須得按照上述列表的順序來依次執行。往往在實際上,唯一的限制就是 Meter 指令必須在 Apply-Actions 指令前執行,Clear-Actions 指令必須在 Write-Actions 指令前執行,Goto-Table 必須放在最后執行。
一個OpenFlow Swtich必須拒絕它不能支持的Instructions的Flow Entry,並且發出一個unsupported flow error給Remote Controller。Flow Tables可能會不支持每一個match,每一個instruction或者每一個action。
2、Action Set
Action Set是與每個數據包相關聯的,初始時是一個空集合;一個Flow Entry可以通過Write-Actions或者Clear-Actions指令來修改Action Set,這個Action Set會在不同的Flow Table之間進行傳遞,當一個Flow Entry的Instructions里不包含Goto-Table指令時,那么整個Pipeline Processing就會在此Flow Entry停止,然后開始執行與該數據包關聯的Action Set里所有的action(s)。
同樣地,一個Action Set里每種類型的action最多只有一個,action類型大致如下所示:
1)copy TTL inwards:在數據包上執行copy TTL inwards操作。
2)pop:pop出數據包里所有的tag。
3)push-MPLS:push MPLS tag到數據包里。
4)push-PBB:push PBB tag到數據包里。
5)push-VLAN:push VLAN tag到數據包里。
6)copy TTL outwards:在數據包上執行copy TTL outwards操作。
7)decrement TTL:降低數據包的TTL。
8)set:在數據包上執行set-fields操作。
9)qos:執行與qos相關的操作,比如set_queue。
10)group:轉到指定的Group Table里繼續執行其Action Bucket里的action(s)。
11)output:如果沒有group action指定,那么將數據包轉發到指定的port里。
Apply-Actions指令會觸發立即執行Action Set里的action(s),並且這些action(s)必須按照上述列表的順序來依次執行,而不管這些action(s)加入到Action Set的順序,另外output action一定要是最后執行的;如果一個Action Set里同時存在output action和group action,那么此時group action將優先被執行,而output action將會被忽略,反之,如果一個Action Set里都不存在output action和group action,那么該數據包將會被丟棄。如果OpenFlow Switch支持的情況下,Group Action Bucket是可以遞歸執行的,即Action Bucket是可以繼續指定另一個Group。
3、Action List
Apply-Actions指令和packet-out消息都包含有一個Action List,這些Action List里的action(s)會依照上文列表的順序依次執行,並且執行的結果會立即累積地反映到數據包信息里,比如Action List里有兩個push-VLAN的action,那么這兩個VLAN tag都會被加入到數據包頭里。如果Action List里包含有output action,那么基於當前狀態的數據包會被克隆一份,進而該克隆體被轉發到指定的port里;如果Action List里包含有group action,那么同樣地基於當前狀態的數據包會被克隆一份,進而該克隆體被轉發到指定的Group里。
當數據包的Apply-Actions指令執行完成后,Pipeline會繼續在修改過的數據包上繼續執行后續的處理,而Action Set不會因為Action List的執行被修改。
4、Actions
OpenFlow Switch並不需要支持所有的Action類型,但是下面加黑的類型必須得支持:
1)Output:該action指將一個數據包轉發到指定的OpenFlow Ports。
2)Set-Queue:該action指為一個數據包設置一個queue id。當一個數據包通過output action轉發到某個port時,該queue id 決定了該數據包被放在哪個queue用來調度轉發,此方式可以用來實現QoS支持。
3)Drop:沒有顯示的action來表示丟棄數據包,作為替代方案,如果一個數據包的Action Set里沒有output action,那么將此數據包將會被丟棄。
4)Group:將數據包轉發到指定的Group繼續處理。
5)Push-Tag / Pop-Tag:Switch應該有能力支持下列的push-tag/pop-tag的操作:
6)Set-Fields:不同的set-fields action以其不同的field type來唯一標識,通過它可以修改數據包頭的某些值域信息,比如VLAN tag的修改等。
7)Change-TTL:該action可以修改數據包頭的IPv4 TTL,IPv6 Hop Limit 或者 MPLS TTL等信息,具體如下: