OpenFlow 交換機與控制器交互步驟

交互步驟

1. Hello
控制器與交互及互相發送 Hello 消息。Hello消息中只包含有OpenFlow Header,其中的 type 字段爲 OFPT_HELLO,version 字段爲發送方所支持的最高版本 OpenFlow 。這時候會出現兩種狀況:緩存

  • 雙方都支持 OpenFlow ,則選取 Hello 消息中最低版本的協議做爲通訊協議
  • 若是其中有一方不支持 OpenFlow 協議版本,則發送 Error 消息後斷開鏈接

若是雙方 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_capabilities
ofp_actions_type 結構以下:
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 結構以下:
ofp_port_config 和 ofp_port_state
4. Set config
知道了交換機的特性以後就要配置交換機了。OpenFlow 交換機只有兩個屬性須要控制器配置:blog

  • 第一個屬性爲 flags,用來指示交換機如何才處理 IP 分片數據包。
  • 第二個屬性爲 miss_send_len,用來指示當一個交換機沒法處理的數據包到達時,將數據包發給控制器的最大字節數。
    set config

5. Packet-in
有兩種狀況會觸發交換機向控制器發送 Packet-in 消息:rem

  • 當交換機收到一個數據包後,查找流表。若是流表中有匹配條目,則交換機按照流表所指示的 action 列表處理數據包。若是沒有,則交換機將數據包封裝在 Packet-in 消息中發送給控制器處理,注意這時候數據包仍然會被放進緩衝區等待處理而不是被丟棄。
  • 數據包在流表中有匹配的條目,可是其中所指示的 action 列表中包含轉發給控制器的動做(Output = CONTROLLER),注意這時候數據包不會被放進緩衝區。
    Packet-in消息格式以下:
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

  • ADD,用來添加一條新的流表項
  • DELETE,用來刪除全部符合必定條件的流表項
  • DELETE-STRICT,用來刪除某一條指定的流表項
  • MODIFY,用來修改全部符合必定條件的流表項
  • MODIFY-STRICT,用來修改某一條指定的流表項
    Flow-Mod 消息格式:
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 工做流程,以下圖:
工做流程

相關文章
相關標籤/搜索