1. Hello
控制器與交互及互相發送 Hello 消息。Hello消息中只包含有OpenFlow Header,其中的 type 字段爲 OFPT_HELLO,version 字段爲發送方所支持的最高版本 OpenFlow 。這時候會出現兩種狀況:緩存
若是雙方 OpenFlow 版本能夠兼容,則 OpenFlow 鏈接創建成功。
Q1:Hello 消息是使用什麼協議傳輸?TCP?UDP?
Q2:全部的網絡協議在升級的時候都必須向前兼容更低版本的協議?cookie
2. Features Request
OpenFlow 鏈接創建以後,就像你剛到手一部新手機,你最想知道的就是手機的配置如何同樣,控制器最須要得到交換機的特性信息,交換機的特性信息包括交換機的 ID(DPID),交換機緩衝區數量,交換機端口及端口屬性等等。
控制器向交換機發送 Features Request 消息查詢交換機特性,Features Request 消息只包含 OpenFlow Header,其中 type 字段爲 OFPT_FEATURES_REQUEST。網絡
3. Features Reply
交換機在收到控制器發出的 Features Request 消息後返回 Features Request 消息,Features 消息包括 OpenFlow Header 和 Features Reply Message。後者結構以下:大數據
struct ofp_switch_features{ struct ofp_header header; uint64_t datapath_id; /*惟一標識 id 號*/ uint32_t n_buffers; /*交緩衝區能夠緩存的最大數據包個數*/ uint8_t n_tables; /*流表數量*/ uint8_t pad[3]; /*align to 64 bits*/ uint32_t capabilities; /*支持的特殊功能,具體見 ofp_capabilities*/ uint32_t actions; /*支持的動做,具體見 ofp_actions_type*/ struct ofp_phy_port ports[0]; /*物理端口描述列表,具體見 ofp_phy_port*/ };
Q3:uint8_t pad[3] 這一字段的做用是什麼?爲了保證整個結構體長度是 64bits 的整數倍?ui
ofp_capabilities 結構以下:
ofp_actions_type 結構以下:
ofp_phy_port 結構以下:code
struct ofp_phy_port{ uint16_t port_no; /*物理端口的編號*/ uint8_t hw_addr[OFP_EHT_ALEN]; /*MAC地址*/ char name[OFP_MAX_PORT_NAME_LEN]; /*端口的名稱*/ uint32_t config; /*端口配置,見 ofp_port_config*/ uint32_t state; /*端口狀態,見ofp_port_state*/ uint32_t curr; /*物理屬性*/ uint32_t advertised; /*物理屬性*/ uint32_t supported; /*物理屬性*/ uint32_t peer; /*物理屬性*/ };
ofp_port_config 和 ofp_port_state 結構以下:
4. Set config
知道了交換機的特性以後就要配置交換機了。OpenFlow 交換機只有兩個屬性須要控制器配置:blog
5. Packet-in
有兩種狀況會觸發交換機向控制器發送 Packet-in 消息:rem
struct ofp_packet_in { struct ofp_header header; uint32_t buffer_id; /*Packet-in消息所攜帶的數據包在交換機緩存區中的ID*/ uint16_t total_len; /*data字段的長度*/ uint16_t in_port; /*數據包進入交換機時的端口號*/ uint8_t reason; /*發送Packet-in消息的緣由,具體見 ofp_packet_in_reason*/ uint8_t pad; uint8_t data[0]; /*攜帶的數據包*/ };
ofp_packet_in_reason 結構以下:工作流
enum ofp_packet_in_reason { OFPR_NO_MACTH /*沒有匹配的條目*/ OFPR_ACTION /*action列表中包含轉發給控制器的動做*/ };
6. Flow-Mod / Packet-out
當控制器收到 Packet-in 消息時有兩種響應的方式:
Flow-Mod
控制器收到 Packet‐in 消息後,能夠發送 Flow‐Mod 消息向交換機寫一個流表項。並
且將 Flow‐Mod 消息中的 buffer_id 字段設置爲 Packet‐in 消息中的 buffer_id 值。從而
控制器向交換機寫入了一條與數據包相關的流表項,而且指定該數據包按照此流表項的 action 列表處理。
Flow-Model 消息共有五種類型:it
struct ofp_flow_mod { struct ofp_header header; struct ofp_match match; /*流表的匹配域*/ uint64_t cookie; /*流表項標識符*/ uint16_t command; /*能夠是ADD,DELETE,DELETE-STRICT,MODIFY,MODIFY-STRICT*/ uint16_t idle_timeout; /*空閒超時時間*/ uint16_t hard_timeout; /*最大生存時間*/ uint16_t priority; /*優先級,優先級高的流表項優先匹配*/ uint32_t buffer_id; /*緩存區ID ,用於指定緩存區中的一個數據包按這個消息的action列表處理*/ uint16_t out_port; /*若是這條消息是用於刪除流表則須要提供額外的匹配參數*/ uint16_t flags; /*標誌位,能夠用來指示流表刪除後是否發送flow‐removed消息,添加流表時是否檢查流表重複項,添加的流表項是否爲應急流表項。*/ struct ofp_action_header actions[0]; /*action列表*/ };
Packet-Out
並非全部的數據包都須要 向交換機中添加一條流表項來匹配處理,網絡中有些數據包出現的數量不多(如ARP、 IGMP等),不必經過流表項來指定這一類數據包的處理方法。此時可使用 Packet-Out 消息,高速交換機某一個數據包如何處理。
struct ofp_packet_out { struct ofp_header header; uint32_t buffer_id; /*交換機緩存區id,若是爲-1則指定的爲packet-out消息攜帶的data字段*/ uint16_t in_port; /*若是buffer_id爲‐1,而且action列表中指定了Output=TABLE的動做,in_port將做爲data段 數據包的額外匹配信息進行流表查詢*/ uint16_t actions_len; /*action列表的長度,能夠用來區分actions和data段*/ struct ofp_action_header actions[0]; /*動做列表*/ uint8_t data[0]; /*數據緩存區,能夠存儲一個以太網幀,可選*/ }
Flow-Mod 是指定一類數據包的處理方法,而 Packet-Out 則是指定某一個數據包的處理方法。不只如此,Packet-Out 消息還可讓交換機產生一個數據包並按照 action 列表處理。
基於 OpenFlow 的 SDN 工做流程,以下圖: