原版OpenFlow Switch Specification Version 1.3.0 (Wire Protocol 0x04) June 25, 2012 包含兩部分惕虑,前一部分是交換機(jī)規(guī)范盐茎,共6個(gè)章節(jié)行贪,可以簡(jiǎn)稱為“規(guī)范”;后一部分是將OpenFlow協(xié)議本身作為附件嵌言,可以認(rèn)為是整體第7章,可以簡(jiǎn)稱為“協(xié)議”雷绢。
本系列作為中文版,基本忠實(shí)原文語句和術(shù)語峰弹,大部分關(guān)鍵詞都是中英文對(duì)照。將規(guī)范和協(xié)議再切分為2部分芜果,共4篇完整呈現(xiàn)鞠呈。
OpenFlow 交換機(jī)規(guī)范 1.3.0 第一部分 1-5章
http://www.reibang.com/p/acfeae1771b3
OpenFlow 交換機(jī)規(guī)范 1.3.0 第二部分 6章
http://www.reibang.com/p/82e238eb8d14
OpenFlow協(xié)議第一部分
http://www.reibang.com/p/7eb86d164d26
OpenFlow協(xié)議第二部分
http://www.reibang.com/p/9cc08c698106
A.3.5 多部消息(Multipart Messages)
(多部消息用于編碼請(qǐng)求或應(yīng)答那些可能攜帶大量數(shù)據(jù)而且不能裝進(jìn)單個(gè) OpenFlow 消息(僅限于 64 kb)的情況。請(qǐng)求或應(yīng)答是編碼序列與特定的多部分類型的多部分消息 师幕。請(qǐng)求被放在一個(gè)或多個(gè) OFPT_MULTIPART_REQUEST 消息)
在系統(tǒng)運(yùn)行中粟按,控制器使用OFPT_MULTIPART_REQUEST消息從datapath請(qǐng)求狀態(tài)信息。
struct ofp_multipart_request {
struct ofp_header header;
uint16_t type; /* OFPMP_*之一. */
uint16_t flags; /* OFPMPF_REQ_*標(biāo)記. */
uint8_t pad[4];
uint8_t body[0]; /* 請(qǐng)求的 body霹粥。0或多個(gè)字節(jié). */
};
OFP_ASSERT(sizeof(struct ofp_multipart_request) == 16);
enum ofp_multipart_request_flags {
OFPMPF_REQ_MORE= 1 << 0 /* 更多的請(qǐng)求跟隨. */
};
交換機(jī)用一個(gè)或多個(gè) OFPT_MULTIPART_REPLY消息進(jìn)行響應(yīng):
struct ofp_multipart_reply {
struct ofp_header header;
uint16_t type; /* 一個(gè) OFPMP_*常數(shù). */
uint16_t flags; /* OFPMPF_REPLY_*標(biāo)記. */
uint8_t pad[4];
uint8_t body[0]; /* 回答的 body灭将,0 或更多字節(jié). */
};
OFP_ASSERT(sizeof(struct ofp_multipart_reply) == 16);
enum ofp_multipart_reply_flags {
OFPMPF_REPLY_MORE= 1 << 0 /* 更多回復(fù)跟隨 */
};
在請(qǐng)求和回復(fù)中為 flags 定義的值是唯一的, 是否更多的請(qǐng)求 / 回復(fù)會(huì)跟隨這個(gè) ——這個(gè)值就是 0x0001后控。為了方便實(shí)現(xiàn) , 控制器允許發(fā)送請(qǐng)求和交換機(jī)允許發(fā)送回復(fù)時(shí)不攜帶額外的表項(xiàng)( 即一個(gè)空的 body)庙曙。然而 , 另一個(gè)消息必須使用更多的標(biāo)志設(shè)置去跟隨一個(gè)消息『铺裕跨越多個(gè)消息 ( 有一個(gè)或多個(gè)消息設(shè)置了更多的標(biāo)志 ) 的請(qǐng)求或應(yīng)答, 消息隊(duì)列中的所有消息必須使用相同的復(fù)合類型和事務(wù) id(xid)捌朴。如果多個(gè)未回答的復(fù)合請(qǐng)求或回復(fù)同時(shí)在傳輸中,復(fù)合請(qǐng)求或應(yīng)答的消息可能與其他 OpenFlow 消息類型 交替 , 包括其他復(fù)合請(qǐng)求或回復(fù) , 但必須有不同的事務(wù) id张抄∩氨危回復(fù)的事務(wù) id 必須匹配激起他們的請(qǐng)求。
在請(qǐng)求和響應(yīng)中署惯, type 字段指所傳遞信息的種類左驾,并決定如何解析 body 字段:
enum ofp_multipart_type {
/* 描述這個(gè) OpenFlow 交換機(jī)。
*請(qǐng)求 body 是空的极谊。
*回復(fù)主體是 struct ofp_desc. */
OFPMP_DESC= 0,
/* 單獨(dú)流統(tǒng)計(jì)诡右。
* 請(qǐng)求 body 是 ofp_flow_stats_request 結(jié)構(gòu)。
*回復(fù) body 是一個(gè) struct ofp_flow_stats 數(shù)組轻猖。. */
OFPMP_FLOW= 1,
/* 總的流統(tǒng)計(jì)帆吻。
* 請(qǐng)求 body 是 ofp_aggregate_stats_request 結(jié)構(gòu)。
*回復(fù) body 是
ofp_aggregate_stats_reply 結(jié)構(gòu). */
OFPMP_AGGREGATE= 2,
/* 流表統(tǒng)計(jì)咙边。
*請(qǐng)求 body 是空的猜煮。
*回復(fù) body 是 ofp_table_stats 結(jié)構(gòu)數(shù)組。 */
OFPMP_TABLE= 3,
/* 端 口 統(tǒng) 計(jì)败许。
* 請(qǐng) 求 body 是 ofp_port_stats_request 結(jié) 構(gòu)友瘤。
* 回 復(fù) body 是ofp_port_stats 結(jié)構(gòu)數(shù)組。 */
OFPMP_PORT_STATS= 4,
/* 一個(gè)端口的隊(duì)列統(tǒng)計(jì)
*請(qǐng)求的 body 是 ofp_queue_stats_request 結(jié)構(gòu)體.
*回復(fù) body 是 ofp_queue_stats 結(jié)構(gòu)體數(shù)組 */
OFPMP_QUEUE=5,
/* 組計(jì)數(shù)器統(tǒng)計(jì)檐束。
*請(qǐng)求的 body 是 ofp_group_stats_request 結(jié)構(gòu)體.
*回復(fù)是 ofp_group_stats 結(jié)構(gòu)體數(shù)組 */
OFPMP_GROUP=6,
/* 組描述辫秧。
*請(qǐng)求 body 是空的。
/* 回復(fù) body 是 ofp_group_desc 結(jié)構(gòu)體數(shù)組 */
OFPMP_GROUP_DESC=7,
/* 組特征被丧。
*請(qǐng)求 body 為空盟戏。
*回復(fù) body 是 ofp_group_features 結(jié)構(gòu)體绪妹。 */
OFPMP_GROUP_FEATURES=8,
/* 計(jì)量器統(tǒng)計(jì)
*請(qǐng)求 body 是 ofp_meter_multipart_requests 結(jié)構(gòu)體。
*回復(fù) body 是 ofp_meter_stats 結(jié)構(gòu)體數(shù)組 */
OFPMP_METER=9,
/* 計(jì)量器配置
*請(qǐng)求 body 是 ofp_meter_multipart_requests 結(jié)構(gòu)體.
*回復(fù) body 是 ofp_meter_config 結(jié)構(gòu)體數(shù)組柿究。 */
OFPMP_METER_CONFIG==10,
/* 計(jì)量器特征
*請(qǐng)求 body 為空邮旷。
*回復(fù) body 是 ofp_meter_features 結(jié)構(gòu)體。 */
OFPMP_METER_FEATURES=11,
/* 表特征
*請(qǐng)求 body 是空的或包含 ofp_table_features 結(jié)構(gòu)體數(shù)組蝇摸, 包含控制器所需的交換機(jī)視
圖婶肩。如果交換機(jī)不能設(shè)置特定的視圖,就會(huì)返回一個(gè) error.
*回復(fù) body 是一組 ofp_table_features 結(jié)構(gòu)體 .*/
OFPMP_TABLE_FEATURES=12,
/* 端口說明
*請(qǐng)求 body 是空的貌夕。
*回復(fù) body 是 ofp_port 結(jié)構(gòu)體數(shù)組 */
OFPMP_PORT_DESC=13,
/* 實(shí)驗(yàn)者擴(kuò)展項(xiàng)
*請(qǐng)求 body 和回復(fù) body 都以 ofp_experimenter_multipart_header 結(jié)構(gòu)體開始律歼。
*而請(qǐng)求 body 和回復(fù) body 是由實(shí)驗(yàn)者定義的。 */
OFPMP_EXPERIMENTER=0xffff
};
如果一個(gè)復(fù)合請(qǐng)求跨越多個(gè)消息并且擴(kuò)展到交換機(jī)不能緩沖的大小啡专,那么交換機(jī)必須回復(fù) 一 個(gè) OFPET_BAD_REQUEST類 型 的 錯(cuò) 誤 消 息 并 且 編 碼 為OFPBRC_MULTIPART_BUFFER_OVERFLOW险毁。如果一個(gè)復(fù)合請(qǐng)求包含一個(gè)不支持的類型,交換機(jī)必須回復(fù)一個(gè) OFPET_BAD_REQUEST 類型的錯(cuò)誤消息并且編碼為 OFPBRC_BAD_MUTIPART.
在所有包含統(tǒng)計(jì)數(shù)字復(fù)合應(yīng)答中们童,如果在交換機(jī)中沒有指定的數(shù)字計(jì)數(shù)器畔况,其值必須被設(shè)置為字段最大值(無符號(hào)數(shù) =-1)。計(jì)數(shù)器是無符號(hào)的并且循環(huán)時(shí)無溢出指示慧库。
A.3.5.1 說明
關(guān)于交換機(jī)廠商跷跪、硬件修訂、軟件修訂齐板、序列號(hào)和描述字段的信息吵瞻,可以從 OFPMP_DESC multipart 請(qǐng)求類型中獲得:
/*OFPMP_DESC請(qǐng)求的回復(fù)部分。每個(gè)表項(xiàng)都是 NULL結(jié)束的 ASCII 碼字符串 */
struct ofp_desc {
char mfr_desc[DESC_STR_LEN]; /* 廠商說明. */
char hw_desc[DESC_STR_LEN]; /* 硬件說明. */
char sw_desc[DESC_STR_LEN]; /* 軟件說明. */
char serial_num[SERIAL_NUM_LEN]; /* 序列號(hào). */
char dp_desc[DESC_STR_LEN]; /* 可讀的數(shù)據(jù)通道描述. */
};
OFP_ASSERT(sizeof(struct ofp_desc) == 1056);
每個(gè)表項(xiàng)都是 ASCII 碼格式并且用空字節(jié)( \0 )從右邊填充覆积。DESC_STR_LEN是 256听皿,SERIAL_NUM_LEN是 32熟呛。dp_desc 是一個(gè)自由形式的字符串宽档, 調(diào)試時(shí)用來描述數(shù)據(jù)通道, 例如:“switch3 in room 3120”庵朝。因此吗冤,它不能被保證是唯一的并且不應(yīng)用作數(shù)據(jù)通道的主要標(biāo)識(shí)—- 使用交換機(jī)的 datapath_id 字段來代替。
A.3.5.2 單個(gè)的流統(tǒng)計(jì)
關(guān)于單個(gè)流表項(xiàng)的信息使用 OFPMP_FLOW復(fù)合請(qǐng)求類型進(jìn)行請(qǐng)求:
/*OFPMP_FLOW的 ofp_multipart_request 部分*/
struct ofp_flow_stats_request {
uint8_t table_id; /* 要讀的 table_ID (from ofp_table_stats),
OFPTT_ALL表示所有表. */
uint8_t pad[3]; /* 對(duì)齊到 32 bits. */
uint32_t out_port; /* 作為一個(gè)輸出端口要求包含這個(gè)匹配項(xiàng). 一個(gè)OFPP_ANY值表示沒有限制九府。 */
uint32_t out_group; /* 作為一個(gè)輸出組要求包含這個(gè)匹配項(xiàng)椎瘟, 一個(gè)OFPG_ANY值表示沒有限制 */
uint8_t pad2[4]; /* 對(duì)齊到 64 bits. */
uint64_t cookie; /* 要求匹配項(xiàng)要包含這個(gè) cookie 值。*/
uint64_t cookie_mask; /* 掩碼用來限制那些必須匹配的 cookie bits . 0 表示沒有限制*/
Struct ofp_match match; /* 用來匹配的字段侄旬,可變大小 */
};
OFP_ASSERT(sizeof(struct ofp_flow_stats_request)==40);
匹配字段包含需匹配的流表項(xiàng)說明肺蔚,還可含有通配符和掩碼字段。這些字段的匹配行為在6.4 中介紹儡羔。
Table_id 表示一個(gè)將讀取的一個(gè)流表的索引值宣羊, OFPTT_ALL表示所有流表璧诵。
Out_port 和out_group 字段可又輸出端口和組選擇過濾。如果 out_port 或out_group 包含一個(gè)分別不同于 OFPP_ANY和OFPG_ANY的值仇冯,它會(huì)在匹配的時(shí)候引進(jìn)一個(gè)約束之宿。這個(gè)約束就是流表項(xiàng)必須包含一個(gè)指定端口或組的輸出行動(dòng)。其它約束例如 ofp_match結(jié)構(gòu)仍然在使用苛坚; 這是純粹一個(gè)額外的約束比被。注意為了禁止輸出過濾, out_port 和out_group 都必須分別設(shè)置為OFPP_ANY和OFPG_ANY泼舱。
Cookie和cookie_mask字段的用法見 6.4 部分等缀。
回復(fù)一個(gè) OFPMP_FLOW復(fù)合請(qǐng)求的部分由下列隊(duì)列組成:
/* 回復(fù)一個(gè) OFPMP_FLOW請(qǐng)求的部分。 */
struct ofp_flow_stats {
uint16_t length; /* 這個(gè)項(xiàng)的長(zhǎng)度 */
uint8_t table_id; /* 流的來源表 ID */
uint8_t pad;
uint32_t duration_sec; /* 流已生成的時(shí)間柠掂,以秒記 */
uint32_t duration_nsec; /* 流存在的時(shí)間超過 duration_sec 的時(shí)間项滑,以 ns記 */
uint16_t priority; /* 流表項(xiàng)的優(yōu)先權(quán) */
uint16_t idle_timeout; /* 在到期之前閑置的秒數(shù) */
uint16_t hard_timeout; /* 到期之前的秒數(shù) */
uint16_t flags; /*OFPFF_* flags 位圖. */
uint8_t pad2[4]; /* 對(duì)齊到 64-bits. */
uint64_t cookie; /* 控制器發(fā)出的不透明標(biāo)識(shí)符 */
uint64_t packet_count; /* 流里的包的數(shù)目。 */
uint64_t byte_count; /* 流的字節(jié)數(shù). */
struct ofp_match match; /* 字段說明. 可變大小 */
/* 可變大小和填充的匹配總是跟隨著指令. */
//struct ofp_instruction instructions[0]; /* 指令集 -- 0 或者更多. */
};
OFP_ASSERT(sizeof(struct ofp_flow_stats) == 56);
由創(chuàng)建流表項(xiàng)的 flow_mod提供的字段(見 A.3.4.1 )涯贞,加上插入到流表項(xiàng)中的 table_id枪狂,packet_count 和byte_count 對(duì)所有被流表項(xiàng)處理的數(shù)據(jù)包進(jìn)行計(jì)數(shù)。
duration_nsec 和duration_sec 字段顯示流表項(xiàng)安裝在交換機(jī)中已過去的時(shí)間宋渔。 總共持續(xù)的時(shí)間可用 duration_sec*10^9+duration_nsec 計(jì)算出州疾。 實(shí)現(xiàn)的話要求提供第二精度; 在能夠獲得的情況下鼓勵(lì)用更高的精度皇拣。
A.3.5.3 總計(jì)的流統(tǒng)計(jì)
關(guān)于多個(gè)的流表項(xiàng)的總計(jì)信息用 OFPMP_AGGREGATE復(fù)合請(qǐng)求類型來請(qǐng)求:
/*OFPMP_AGGREGATE類型的 ofp_aggregate_atats_request 部分*/
struct ofp_aggregate_stats_request {
uint8_t table_id; /* 要讀取的表 ID( 來自ofp_table_stats)严蓖,OFPTT_ALL為所有的表 */
uint8_t pad[3]; /* 排列到 32 bits. */
uint32_t out_port; /* 包含此項(xiàng)匹配的流表項(xiàng)要求作為一個(gè)輸出端口. OFPP_ANY值表示沒有限制*/
uint32_t out_group; /* 包含此項(xiàng)匹配的流表項(xiàng)要求作為一個(gè)輸出組, OFPG_ANY值表示沒有限制*/
uint8_t pad2[4]; /* 排列到 64 bits. */
uint64_t cookie; /* 要求正在匹配的流表項(xiàng)去包含這些 cookie 值*/
uint64_t cookie_mask;/* 掩碼(mask)用來限制那些必須匹配的 cookie 比特氧急, 0表示沒有限制.*/
struct ofp_match match; /* 將匹配的字段. 可變大小. */
};
OFP_ASSERT(sizeof(struct ofp_aggregate_stats_request) == 40);
在這個(gè)消息的中的字段與在單獨(dú)的流統(tǒng)計(jì)請(qǐng)求( OFPMP_FLOW)里有相同的含義颗胡。
回復(fù)部分的組成如下:
/*OFPMP_AGGREGATE 請(qǐng)求的回復(fù)部分. */
struct ofp_aggregate_stats_reply {
uint64_t packet_count; /* 流中的數(shù)據(jù)包數(shù). */
uint64_t byte_count; /* 流中的字節(jié)數(shù). */
uint32_t flow_count; /* 流的數(shù)目. */
uint8_t pad[4]; /* 排列到 64 bits. */
};
OFP_ASSERT(sizeof(struct ofp_aggregate_stats_reply) == 24);
A.3.5.4 表統(tǒng)計(jì)
請(qǐng)求關(guān)于表的信息使用 OFPMP_TABLE復(fù)合請(qǐng)求類型。在請(qǐng)求內(nèi)不包含任何數(shù)據(jù)吩坝。
回復(fù)部分由如下一個(gè)數(shù)組組成:
/* 回復(fù)給 OFPMP_TABLE請(qǐng)求的部分. */
struct ofp_table_stats {
uint8_t table_id; /* 表標(biāo)識(shí)符 . 低數(shù)值的表第一個(gè)訪問 */
uint8_t pad[3]; /* 排列到 32-bits. */
uint32_t active_count; /* 活躍的流表項(xiàng)數(shù)量. */
uint64_t lookup_count; /* 表中處理過的數(shù)據(jù)包數(shù)量. */
uint64_t matched_count; /* 表中匹配的數(shù)據(jù)包數(shù)量毒姨。 */
};
OFP_ASSERT(sizeof(struct ofp_table_stats) == 24);
在交換機(jī)支持的每一個(gè)表中,數(shù)組都有一個(gè)結(jié)構(gòu)钉寝。流表項(xiàng)是以數(shù)據(jù)包通過表的順序返回的弧呐。
A.3.5.5 表特征
OFPMP_TABLE_FEATURES復(fù)合類型允許一個(gè)控制器去查詢現(xiàn)存的表的能力和選擇要求交換機(jī)去重新配置表去匹配一個(gè)已有的配置。一般來講嵌纲,表的能力體現(xiàn)了一個(gè)表的所有可能的特征俘枫,然而一些能力互不兼容,目前的能力結(jié)構(gòu)不允許我們?nèi)ソ鉀Q兼容問題逮走。
A.3.5.5.1 表特征請(qǐng)求和回復(fù)
如果 OFPMP_TABLE_FEATURES 請(qǐng)求是空的鸠蚪,交換機(jī)將返回一組包含當(dāng)前配置流表能力的ofp_table_features 結(jié)構(gòu)體。
如果請(qǐng)求部分包含一個(gè)或更多 ofp_table_features 結(jié)構(gòu)體的隊(duì)列,交換機(jī)將嘗試去改變它的流表去匹配被請(qǐng)求的流表配置茅信。這個(gè)操作配置整個(gè)流水線酣栈,流水線里的流表設(shè)置必須和請(qǐng)求的設(shè)置匹配,否則必須返回一個(gè) error汹押。 尤其是矿筝, 如果這個(gè)配置成功進(jìn)行了設(shè)置,則給一個(gè)或更多交換機(jī)支持的流表的請(qǐng)求結(jié)構(gòu)若不包含一個(gè)ofp_table_features 結(jié)構(gòu)體棚贾,這些流表將從流水線中被移除窖维。配置改變成功會(huì)修改請(qǐng)求里面的所有流表的特性,也就是說妙痹,要么在請(qǐng)求里被指定的所有流表都修改铸史,要么一個(gè)都不改,并且新的流表的功能必須是超集或者和
被請(qǐng)求的功能相同怯伊。如果流表配置成功了琳轿,已刪除的流表或在新舊配置里能力改變的流表,其 流 表 項(xiàng) 都 將 從 流 表 中 刪 除耿芹。如果交換機(jī)不能設(shè)置所請(qǐng)求的配置崭篡,將返回一個(gè)OFPET_TABLE_FEATURES_FAILED 類型錯(cuò)誤并帶有適當(dāng)錯(cuò)誤代碼。
含有ofp_table_features 的請(qǐng)求和回復(fù)至少要滿足以下要求:
●每個(gè) ofp_table_features 結(jié)構(gòu)的 table_id 字段的值在消息所有的 ofp_table_features 結(jié)構(gòu)里應(yīng)該是唯一的吧秕。
●每個(gè) ofp_table_features 結(jié)構(gòu)的屬性字段必須包含一個(gè) ofp_table_feature_prop_type 屬性琉闪,以及另外兩個(gè)。 第一砸彬, the_MISS后綴可能被忽略颠毙,如果它和常規(guī)流表項(xiàng)相應(yīng)的屬性相同;
第二砂碉, OFPTFPT_EXPERIMENTER 和OFPTFPT_EXPRIMENTER_MISS 類型的屬性可能會(huì)被多次忽略或使用蛀蜜。排序未規(guī)定,但鼓勵(lì)使用在規(guī)范上列出的次序增蹭。 (見A.3.5.5.2 )
一個(gè)交換機(jī)接收到一個(gè)請(qǐng)求滴某,若不滿足所需請(qǐng)求,應(yīng)該返回一個(gè)OFPET_TABLE_FEATURES_FALLED 類型的錯(cuò)誤并帶有適當(dāng)?shù)拇a沪铭。
下面的結(jié)構(gòu)說明表特性請(qǐng)求和回復(fù)的部分:
/* OFPMP_TABLE_FEATURES 類的ofp_multipart_request 部分./
/* 回復(fù)OFPMP_TABLE_FEATURES請(qǐng)求的部分. */
struct ofp_table_features {
uint16_t length; /* 長(zhǎng)度被填至 64 bits. */
uint8_t table_id; /* 表的標(biāo)識(shí)符. 低編號(hào)先詢問. */
uint8_t pad[5]; /* 排到64-bits. */
char name[OFP_MAX_TABLE_NAME_LEN];
uint64_t metadata_match; /* 表能匹配元數(shù)據(jù)的位數(shù). */
uint64_t metadata_write; /* 表能寫的元數(shù)據(jù)位數(shù). */
uint32_t config; /*OFPTC_*值的位圖 */
uint32_t max_entries; /* 流表項(xiàng)被支持的最大數(shù). */
/* 表特征屬性列舉 */
struct ofp_table_feature_prop_header properties[0]; /* 屬性舉例 */
};
OFP_ASSERT(sizeof(struct ofp_table_features) == 64);
數(shù)組有一個(gè)結(jié)構(gòu)給每個(gè)被交換機(jī)支持的流表壮池。 流表項(xiàng)總是按照數(shù)據(jù)表通過流表的順序返回偏瓤。OFP_MAX_TABLLE_NAME_LEN是32杀怠。
該metadata_match字段表示流表利用 ofp_match結(jié)構(gòu)體元數(shù)據(jù)字段時(shí)可匹配的元數(shù)據(jù)字段的位數(shù)。值0xFFFFFFFFFFFFFFFF表明表可以匹配整個(gè)元數(shù)據(jù)字段厅克。
該metadata_write 字段顯示表可以使用 ofpit_write_metadata 指令寫元數(shù)據(jù)字段的位數(shù)赔退。值 0xFFFFFFFFFFFFFFFF表明表可以寫整個(gè)元數(shù)據(jù)字段。
配置字段是表的配置,通過表的配置信息對(duì)表進(jìn)行設(shè)置(見 A.3.3 )
Max_entries 字段表示能插入表的流表項(xiàng)最大數(shù)量硕旗。由于現(xiàn)代的硬件的限制窗骑,該max_entries 值應(yīng)考慮建議值和接近表最大努力的性能。不考慮表的高層抽象漆枚,在實(shí)踐中通過一個(gè)單一的流表項(xiàng)所消耗的資源是不固定的创译。例如,一個(gè)流表項(xiàng)可能消耗多個(gè)流表項(xiàng)的資源墙基,取決于它的匹配參數(shù)( e.g.IPv4 vs. IPv6)软族。而且,在同個(gè) OPENFLOW層不同的表可能實(shí)
際上共享相同的底層物理資源残制。進(jìn)一步說立砸,基于 OpenFlow 混合交換機(jī),這些表可能與非OpenFlow 功能部分共享初茶。結(jié)果是交換機(jī)實(shí)現(xiàn)者應(yīng)該報(bào)告所支持的總的流表項(xiàng)值颗祝,并且控制器的作者不應(yīng)該把這個(gè)值設(shè)為固定的,物理常數(shù)恼布。
properties字段是表特征屬性的一個(gè)列表螺戳,描敘表的不同性能。
A.3.5.5.2 表特征屬性
目前定義的表特征屬性類型的清單是:
/* 表特征屬性類型.
* 最低位被清除表示一個(gè)常規(guī)流表項(xiàng)的一個(gè)屬性.
* 最低位被設(shè)置表示 Table-Miss Flow Entry 的一個(gè)屬性 .*/
enum ofp_table_feature_prop_type {
OFPTFPT_INSTRUCTIONS= 0, /* 指令屬性. */
OFPTFPT_INSTRUCTIONS_MISS= 1, /* table-miss 的指令. */
OFPTFPT_NEXT_TABLES= 2, /* Next Table 屬性. */
OFPTFPT_NEXT_TABLES_MISS= 3, /* Next Table for table-miss. */
OFPTFPT_WRITE_ACTIONS= 4, /* Write Actions 屬性. */
OFPTFPT_WRITE_ACTIONS_MISS= 5, /* Write Actions for table-miss. */
OFPTFPT_APPLY_ACTIONS= 6, /* Apply Actions 屬性. */
OFPTFPT_APPLY_ACTIONS_MISS= 7, /* Apply Actions for table-miss. */
OFPTFPT_MATCH= 8, /* 匹配屬性. */
OFPTFPT_WILDCARDS= 10, /* Wildcards 屬性. */
OFPTFPT_WRITE_SETFIELD= 12, /* Write Set-Field 屬性. */
OFPTFPT_WRITE_SETFIELD_MISS= 13, /* Write Set-Field for table-miss. */
OFPTFPT_APPLY_SETFIELD= 14, /* Apply Set-Field 屬性. */
OFPTFPT_APPLY_SETFIELD_MISS= 15, /* Apply Set-Field for table-miss. */
OFPTFPT_EXPERIMENTER= 0xFFFE, /* Experimenter 屬性. */
OFPTFPT_EXPERIMENTER_MISS= 0xFFFF, /* Experimenter for table-miss. */
};
_MISS后綴的屬性描述漏表流表項(xiàng)的功能 (見 5.4 )折汞,而其他屬性描述常規(guī)流表項(xiàng)的功能温峭。
如果一個(gè)指定屬性沒有任何功能(例如不支持 Set_Field ),一個(gè)空列表屬性也必須被包含在屬性列表里字支。 當(dāng)漏表流表項(xiàng)的一個(gè)屬性和常規(guī)流表項(xiàng)相應(yīng)的屬性相同凤藏, (i.e. 兩個(gè)屬性都有相同的功能清單),這個(gè)漏表屬性可以從屬性列表里清除堕伪。
一個(gè)屬性定義包含屬性類型揖庄、長(zhǎng)度和關(guān)聯(lián)的數(shù)據(jù):
/* 所有表特征屬性常用的標(biāo)頭 */
struct ofp_table_feature_prop_header {
uint16_t type; /* OFPTFPT_*中之一. */
uint16_t length; /* 這個(gè)屬性占字節(jié)長(zhǎng)度. */
};
OFP_ASSERT(sizeof(struct ofp_table_feature_prop_header) == 4);
OFPTFPT_INSTRUCTIONS 和OFPTFPT_INSTRUCTIONS_MISS 屬性使用如下結(jié)構(gòu)和字段:
/* 指令屬性 */
struct ofp_table_feature_prop_instructions {
uint16_t type; /*OFPTFPT_INSTRUCTIONS和OFPTFPT_INSTRUCTIONS_MISS 之一. */
uint16_t length; /* 這個(gè)屬性的字節(jié)長(zhǎng)度. */
/* 接下來是:
* - 準(zhǔn)確地講 (length - 4) 個(gè)字節(jié)包含指令的 id, 其次
* - 精確地 (length + 7)/8*8 - (length) (between 0 and 7)
* 全零字節(jié)的字節(jié)數(shù) */
struct ofp_instruction instruction_ids[0]; /* 指令列表 */
};
OFP_ASSERT(sizeof(struct ofp_table_feature_prop_instructions) == 4);
Instruction_ids 是被這個(gè)表支持的指令列表(見 5.9 )。列表里的元素是可變大小的欠雌,用于實(shí)驗(yàn)者表述指令的蹄梢,非實(shí)驗(yàn)者指令是 4 字節(jié)。
OFPTFPT_NEXT_TABLES和 OFPTFPT_NEXT_TABLES_MISS屬性使用如下結(jié)構(gòu)和字段:
A.3.5.6 端口統(tǒng)計(jì)
關(guān)于端口統(tǒng)計(jì)的信息使用 OFPMP_PORT_STATS復(fù)合請(qǐng)求類型進(jìn)行請(qǐng)求:
/* Body for ofp_multipart_request of type OFPMP_PORT.*/
struct ofp_port_stats_request {
uint32_t port_no; /* OFPMP_PORT 消息必須請(qǐng)求統(tǒng)計(jì)富俄,要么給一個(gè)單一的端口 ( 在port_no 中指定的) 或者所有端口 (port_no == OFPP_ANY). */
uint8_t pad[4];
};
OFP_ASSERT(sizeof(struct ofp_port_stats_request) == 8);
port_no 字段 有選擇的 過濾統(tǒng)計(jì)請(qǐng)求到給定的端口禁炒。若訪問所有端口的統(tǒng)計(jì) ,port_no 必須設(shè)置成 OFPP_ANY.
回復(fù)部分由以下數(shù)組組成:
/* OFPMP_PORT 請(qǐng)求的回復(fù)部分 . 如果一個(gè)計(jì)數(shù)器不被支持 , 設(shè)置該字段給所有的( ones). */
struct ofp_port_stats {
uint32_t port_no;
uint8_t pad[4]; /* 排到 64-bits. */
uint64_t rx_packets; /* 收到包的數(shù)量. */
uint64_t tx_packets; /* 已傳送包的數(shù)量 */
uint64_t rx_bytes; /* 收到的字節(jié)數(shù). */
uint64_t tx_bytes; /* 傳送的字節(jié)數(shù). */
uint64_t rx_dropped; /* 被 RX丟棄的包數(shù). */
uint64_t tx_dropped; /* 被TX丟棄的包數(shù). */
uint64_t rx_errors; /* 接受到錯(cuò)誤的數(shù)量. 這是一個(gè)超集( super-set )更具體的接收錯(cuò)誤,應(yīng)該大于或等于所有 rx_ * _err 值的總和霍比。 */
uint64_t tx_errors; /* 傳送錯(cuò)誤的數(shù)量 . 這是一個(gè)超集更具體的傳輸錯(cuò)誤幕袱,應(yīng)該大于或等于所有 tx_ * _err 值的總和(沒有當(dāng)前定義的。 )*/
uint64_t rx_frame_err; /* 幀調(diào)整的錯(cuò)誤數(shù)量. */
uint64_t rx_over_err; /* 在RX溢出的數(shù)據(jù)包數(shù). */
uint64_t rx_crc_err; /* CRC錯(cuò)誤數(shù). */
uint64_t collisions; /* 沖突數(shù)量. */
uint32_t duration_sec; /* 端口已經(jīng)生存了的秒數(shù). */
uint32_t duration_nsec; /* 端口已生存的時(shí)間超過 duration_sec 的納秒數(shù). */
};
OFP_ASSERT(sizeof(struct ofp_port_stats) == 112);
duration_sec 和 duration_nsec 字段表示端口已配置成 OpenFlow 通道已過去的時(shí)間悠瞬。
持續(xù)的總的納秒數(shù)可以被算成 duration_sec*10^9+duration_nsec. 實(shí)現(xiàn)時(shí)要求提供第二精度们豌,在能獲得的條件下鼓勵(lì)提供更高的精度涯捻。
A.3.5.7 端口描述
端口描述請(qǐng)求 OFPMP_PORT_DESCRIPTION 能使控制器獲得支持 OpenFlow系統(tǒng)里所有的端口描述。請(qǐng)求部分是空的望迎≌习回復(fù)部分由如下數(shù)組構(gòu)成:
/* 一個(gè)端口的描述 */
struct ofp_port {
uint32_t port_no;
uint8_t pad[4];
uint8_t hw_addr[OFP_ETH_ALEN];
uint8_t pad2[2]; /* 排到64 bits. */
char name[OFP_MAX_PORT_NAME_LEN];/* Null-terminated */
uint32_t config; /* OFPPC_*flags 的位圖. */
uint32_t state; /* OFPPS_*flags 的位圖. */
/* 描述特性的 OFPPF_*的位圖. 如果不支持或不可用的所有位清零 */
uint32_t curr; /* 當(dāng)前特征 */
uint32_t advertised; /* 端口公布的特性. */
uint32_t supported; /* 端口支持的特性. */
uint32_t peer; /* 對(duì)端公布的特性 . */
uint32_t curr_speed; /* 當(dāng)前端口的比特率, kbps. */
uint32_t max_speed; /* 最大端口比特率 kbps */
};
OFP_ASSERT(sizeof(struct ofp_port) == 64);
這個(gè)結(jié)構(gòu)被描述在 A.2.1.
A.3.5.8 隊(duì)列統(tǒng)計(jì)
OFPMP_QUEUE復(fù)合請(qǐng)求消息提供隊(duì)列統(tǒng)計(jì)給一個(gè)或多個(gè)端口和一個(gè)或多個(gè)隊(duì)列辩尊。請(qǐng)求部分包含一個(gè) port_no 字段為請(qǐng)求的統(tǒng)計(jì)標(biāo)識(shí)出 OpenFlow 端口涛浙,或者 OFPP_ANY去查閱所有的端口。 queue_id 字段識(shí)別優(yōu)先隊(duì)列之一摄欲』饶茫或者 OFPQ_ALL指向在指定端口配置的所有隊(duì)列。
OFPQ_ALL是 0xffffffff蒿涎。
struct ofp_queue_stats_request {
uint32_t port_no; /* 如果是 OFPP_ANY表示所有端口. */
uint32_t queue_id; /* 如果是 OFPQ_ALL表示所有隊(duì)列. */
};
OFP_ASSERT(sizeof(struct ofp_queue_stats_request) == 8);
回復(fù)部分由下列結(jié)構(gòu)組成:
struct ofp_queue_stats {
uint32_t port_no;
uint32_t queue_id; /* 隊(duì)列i.d */
uint64_t tx_bytes; /* 傳送的字節(jié)數(shù). */
uint64_t tx_packets; /* 傳送的包數(shù). */
uint64_t tx_errors; /* 由于溢出丟棄的數(shù)據(jù)包數(shù)量. */
uint32_t duration_sec; /* 隊(duì)列已經(jīng)生成的秒數(shù). */
uint32_t duration_nsec; /* 隊(duì)列已經(jīng)生成超出 duration_sec 的納秒數(shù). */
};
OFP_ASSERT(sizeof(struct ofp_queue_stats) == 40);
Duration_sec 和 duration_nsec 字段表示隊(duì)列已經(jīng)安裝在交換機(jī)里過去了的時(shí)間哀托。持續(xù)的總時(shí)間可以用 duration_sec*10^9+duration_nsec. 實(shí)現(xiàn)時(shí)要求提供第二精度, 在能獲得的條件下鼓勵(lì)提供更高的精度劳秋。
A.3.5.9 組統(tǒng)計(jì)
OFPMP_GROUP復(fù)合請(qǐng)求消息為一個(gè)或多個(gè)組提供統(tǒng)計(jì)仓手。請(qǐng)求部分由 group_id 字段組成。
它也能被設(shè)置為 OFPG_ALL表示交換機(jī)里所有的組玻淑。
/*OFPMP_GROUP 請(qǐng)求部分. */
struct ofp_group_stats_request {
uint32_t group_id; /* 如果是 OFPG_ALL表示所有的表. */
uint8_t pad[4]; /* 拍到 64 bits. */
};
OFP_ASSERT(sizeof(struct ofp_group_stats_request) == 8);
回復(fù)部分由如下結(jié)構(gòu)組成:
/* 回復(fù)給 OFPMP_GROUP 請(qǐng)求的部分. */
struct ofp_group_stats {
uint16_t length; /* 這個(gè)流表項(xiàng)的長(zhǎng)度. */
uint8_t pad[2]; /* 排到64 bits. */
uint32_t group_id; /* 組標(biāo)識(shí)符. */
uint32_t ref_count; /* 直接指向該組的流或組的數(shù)量 */
uint8_t pad2[4]; /* 排到64 bits. */
uint64_t packet_count; /* 組處理過的包的數(shù)量. */
uint64_t byte_count; /* 組處理過的字節(jié)數(shù)量. */
uint32_t duration_sec; /* 組已經(jīng)生存的秒數(shù). */
uint32_t duration_nsec; /* 組已經(jīng)生存的超過 duration_sec 的納秒數(shù). */
struct ofp_bucket_counter bucket_stats[0]; /* 每個(gè)存儲(chǔ)段設(shè)置一個(gè)計(jì)數(shù)器. */
};
OFP_ASSERT(sizeof(struct ofp_group_stats) == 40);
字段包括創(chuàng)建組的 group_mod 提供的嗽冒,加上 ref_count 表示計(jì)算與組相關(guān)的流的數(shù)量,packet_count补履,和 byte_count 計(jì)算所有組處理的數(shù)據(jù)包添坊。
Duration_sec 和 duration_nsec 字段表示組安裝在交換機(jī)里已經(jīng)過去的時(shí)間◇锎福總的持續(xù)的納秒數(shù)可以用 duration_sec*10^9+duration_nsec. 實(shí)現(xiàn)時(shí)要求提供第二精度贬蛙, 在能獲得的條件下鼓勵(lì)提供更高的精度。
Bucket_stats 字段由一組 ofp_bucket_counter 結(jié)構(gòu)體組成:
/* 用來做組統(tǒng)計(jì)回復(fù). */
struct ofp_bucket_counter {
uint64_t packet_count; /* 存儲(chǔ)段處理的包數(shù). */
uint64_t byte_count; /* 存儲(chǔ)段處理的字節(jié)數(shù). */
};
OFP_ASSERT(sizeof(struct ofp_bucket_counter) == 16);
A.3.5.10 組描述
OFPMP_GROUP_DESC復(fù)合請(qǐng)求消息提供一個(gè)方式將交換機(jī)上的組設(shè)置列出來谚攒, 以及它們相應(yīng)的存儲(chǔ)段行動(dòng)阳准。請(qǐng)求部分是空的,而回復(fù)部分是如下結(jié)構(gòu)的數(shù)組:
/* 回復(fù)給 OFPMP_GROUP_DESC請(qǐng)求的部分. */
struct ofp_group_desc {
uint16_t length; /* 流表項(xiàng)的長(zhǎng)度. */
uint8_t type; /*OFPGT_*中之一. */
uint8_t pad; /* 填充至 64 bits. */
uint32_t group_id; /* 組標(biāo)識(shí)符. */
struct ofp_bucket buckets[0]; /* 存儲(chǔ)段列表 -- 0 或更多. */
};
OFP_ASSERT(sizeof(struct ofp_group_desc) == 8);
描述組的字段和那些 ofp_group_mod 結(jié)構(gòu)體使用的一樣 ( 見 A.3.4.2)馏臭。
A.3.5.11 組特征
OFPMP_GROUP_FEATURES 復(fù)合請(qǐng)求消息提供一個(gè)方式列出交換機(jī)上組的功能野蝇。請(qǐng)求部分是空的,而回復(fù)部分是如下結(jié)構(gòu):
/* 回復(fù)給 OFPMP_GROUP_FEATURES 請(qǐng)求的部分. 組特征. */
struct ofp_group_features {
uint32_t types; /* OFPGT_*值支持的位圖. */
uint32_t capabilities; /* OFPGFC_*功能支持的位圖. */
uint32_t max_groups[4]; /* 每個(gè)類型的組的最大數(shù)量. */
uint32_t actions[4]; /* 支持的 OFPAT_* 的位圖. */
};
OFP_ASSERT(sizeof(struct ofp_group_features) == 40);
max_groups字段是每個(gè)類型的組的最大數(shù)量括儒。 行動(dòng)是每個(gè)組類型支持的行動(dòng)绕沈。 功能使用如下標(biāo)志的一個(gè)組合:
/* 組配置標(biāo)志 */
enum ofp_group_capabilities {
OFPGFC_SELECT_WEIGHT= 1 << 0, /* 選擇組支持的重量 */
OFPGFC_SELECT_LIVENESS= 1 << 1, /* 選擇組支持的活躍度 */
OFPGFC_CHAINING= 1 << 2, /* 支持鏈接組 */
OFPGFC_CHAINING_CHECKS= 1 << 3, /* 為循環(huán)檢查和刪除鏈接 */
A.3.5.12 計(jì)量器統(tǒng)計(jì)
OFPMT_METER統(tǒng)計(jì)請(qǐng)求消息給一個(gè)或多個(gè)計(jì)量器提供統(tǒng)計(jì)。請(qǐng)求部分由一個(gè) meter_id字段組成帮寻,它能設(shè)置成 OFPM_ALL表示交換機(jī)上所有計(jì)量器乍狐。
/* OFPMP_METER和 OFPMP_METER_CONFIG請(qǐng)求部分 */
struct ofp_meter_multipart_request {
uint32_t meter_id; /* 計(jì)量器實(shí)例 , 或者是 OFPM_ALL.*/
uint8_t pad[4]; /* 排列到 64 bits. */
};
OFP_ASSERT(sizeof(struct ofp_meter_multipart_request) == 8);
回復(fù)部分是如下結(jié)構(gòu):
/*OFPMP_METER請(qǐng)求的回復(fù)部分. 計(jì)量器統(tǒng)計(jì). */
struct ofp_meter_stats {
uint32_t meter_id; /* 計(jì)量器例子 */
uint16_t len; /* 統(tǒng)計(jì)的字節(jié)長(zhǎng)度. */
uint8_t pad[6];
uint32_t flow_count; /* 跳至計(jì)量器的流數(shù)量. */
uint64_t packet_in_count; /* 輸入數(shù)據(jù)包的數(shù)量. */
uint64_t byte_in_count; /* 輸入的字節(jié)數(shù). */
uint32_t duration_sec; /* 計(jì)量器已經(jīng)生成了的秒數(shù). */
uint32_t duration_nsec; /* 計(jì)量器已經(jīng)生存超出 duration_sec 的納秒數(shù). */
struct ofp_meter_band_stats band_stats[0];
/*band_stats 長(zhǎng)度是字段長(zhǎng)度里推出來的 */
};
OFP_ASSERT(sizeof(struct ofp_meter_stats) == 40);
packet_in_count 和 byte_in_count 對(duì) 計(jì) 量 器 處 理 過 的 所 有 數(shù) 據(jù) 包 進(jìn) 行 計(jì) 數(shù)。
duration_sec 和duration_nsec 字段表示計(jì)量器安裝在交換機(jī)上過去了的時(shí)間规婆±教桑總的持續(xù)時(shí)間可以用 duration_sec*10^9+duration_nsec。實(shí)現(xiàn)時(shí)要求提供第二精度抒蚜,在能獲得的條件下鼓勵(lì)提供更高的精度掘鄙。
band_stats 字段由 ofp_meter_band_stats 結(jié)構(gòu)組成:
/* 給每個(gè)計(jì)量帶寬的統(tǒng)計(jì) */
struct ofp_meter_band_stats {
uint64_t packet_band_count; /* 帶內(nèi)的數(shù)據(jù)包數(shù)量. */
uint64_t byte_band_count; /* 帶內(nèi)的字節(jié)數(shù)量. */
};
OFP_ASSERT(sizeof(struct ofp_meter_band_stats) == 16);
packet_band_count 和 byte_band_count 對(duì)帶寬處理的數(shù)據(jù)包進(jìn)行計(jì)數(shù)。帶寬統(tǒng)計(jì)的順序必須和 OFPMT_METER_CONFIG 統(tǒng)計(jì)回復(fù)里的一樣嗡髓。
A.3.5.13 計(jì)量器配置統(tǒng)計(jì)
OFPMT_METER_CONFIG統(tǒng)計(jì)請(qǐng)求消息給一個(gè)或多個(gè)計(jì)量器提供配置操漠。請(qǐng)求部分由一個(gè)meter_id 字段組成 , 它可以被設(shè)置成
OFPM_ALL表示交換機(jī)上所有的計(jì)量器。
/*OFPMP_METER和OFPMP_METER_CONFIG請(qǐng)求部分. */
struct ofp_meter_multipart_request {
uint32_t meter_id; /* 計(jì)量器實(shí)例 , 或者OFPM_ALL. */
uint8_t pad[4]; /* 對(duì)齊到 64 bits. */
};
OFP_ASSERT(sizeof(struct ofp_meter_multipart_request) == 8);
回復(fù)部分由一個(gè)如下結(jié)構(gòu)組成:
/*OFPMP_METER_CONFIG 請(qǐng)求的回復(fù)部分 . 計(jì)量器配置 */
struct ofp_meter_config {
uint16_t length; /* 流表項(xiàng)的長(zhǎng)度. */
uint16_t flags; /* All OFPMC_*表示申請(qǐng). */
uint32_t meter_id; /* 計(jì)量器實(shí)例. */
struct ofp_meter_band_header bands[0]; /* 帶寬的長(zhǎng)度從字段長(zhǎng)度里推導(dǎo)出 */
};
OFP_ASSERT(sizeof(struct ofp_meter_config) == 8);
該字段和用來配置計(jì)量器的字段相同 ( 見 A.3.4.4 )
A.3.5.14 儀表功能統(tǒng)計(jì)
OFPMT_METER_FEATRUES 統(tǒng)計(jì)請(qǐng)求消息提供了計(jì)量子系統(tǒng)功能集合饿这。
請(qǐng)求部分是空的浊伙,和回復(fù)部分由以下結(jié)構(gòu)組成:
/* 回復(fù) ofpmp_meter_features 請(qǐng)求。計(jì)量功能 */
struct ofp_meter_features {
uint32_t max_meter; /* 計(jì)量器的最大數(shù)值. */
uint32_t band_types; /* 支持位圖 ofpmbt_ *的值*/
uint32_t capabilities; /*ofp_meter_flags 的位圖 */
uint8_t max_bands; /* 每個(gè)計(jì)量的的最大頻帶 */
uint8_t max_color; /* 最大的彩色值 */
uint8_t pad[2];
};
OFP_ASSERT(sizeof(struct ofp_meter_features) == 16);
A.3.5.15 實(shí)驗(yàn)者復(fù)合
實(shí)驗(yàn)者特定復(fù)合消息通過 OFPMP_EXPERIMENTER復(fù)合類型進(jìn)行請(qǐng)求长捧, 請(qǐng)求的第一個(gè)字節(jié)和回復(fù)部分結(jié)構(gòu)如下:
/*ofp_multipart_request 部分/ 回復(fù)OFPMP_EXPERIMENTER. */
struct ofp_experimenter_multipart_header {
uint32_t experimenter;
/* 實(shí)驗(yàn)者標(biāo)識(shí)符嚣鄙,與 ofp_experimenter_header 中格式相同 */
uint32_t exp_type; /* 實(shí)驗(yàn)者定義 */
/* 實(shí)驗(yàn)者自定義附加數(shù)據(jù) */
};
OFP_ASSERT(sizeof(struct ofp_experimenter_multipart_header) == 8);
剩余的請(qǐng)求和回復(fù)部分是由實(shí)驗(yàn)者定義
experimenter 字段是實(shí)驗(yàn)者的 ID,與 OFPMP_EXPERIMENTER中的格式相同串结。
A.3.6 隊(duì)列配置消息
隊(duì)列配置超出了 OpenFlow 協(xié)議范圍哑子,可通過一個(gè)命令行工具,或通過一個(gè)外部的專用配置協(xié)議肌割。
控制器使用下列結(jié)構(gòu)來查詢交換機(jī)端口上已配置隊(duì)列:
/* 查詢端口隊(duì)列配置 */
struct ofp_queue_get_config_request {
struct ofp_header header;
uint32_t port; /* 查詢的端口卧蜓;應(yīng)該指向一個(gè)有效的物理端口(或 OFPP_ANY 要求所有配置隊(duì)列) */
uint8_t pad[4];
};
OFP_ASSERT(sizeof(struct ofp_queue_get_config_request) == 16);
交換機(jī)使用 OFP_QUEUE_GET_CONFIG_REPLY 命令回復(fù),其中包含配置隊(duì)列的列表把敞。
/* 給定端口的隊(duì)列配置 */
struct ofp_queue_get_config_reply {
struct ofp_header header;
uint32_t port;
uint8_t pad[4];
struct ofp_packet_queue queues[0]; /* 已配置的隊(duì)列列表 */
};
OFP_ASSERT(sizeof(struct ofp_queue_get_config_reply) == 16);
A.3.7 分組報(bào)文
當(dāng)控制器通過數(shù)據(jù)通路發(fā)送一個(gè)數(shù)據(jù)包弥奸,就使用 OFPT_PACKET_OUT 消息:
/* 發(fā)送數(shù)據(jù)包(控制器 ->通路) */
struct ofp_packet_out {
struct ofp_header header;
uint32_t buffer_id; /* 指定的標(biāo)識(shí)符通過數(shù)據(jù)通路( OFP_NO_BUFFER如果沒有) */
uint32_t in_port; /* 分組的輸入端口或 OFPP_CONTROLLER*/
uint16_t actions_len; /* 以字節(jié)數(shù)組的大小的作用 */
uint8_t pad[6];
struct ofp_action_header actions[0]; /* 行動(dòng)列表 -0 或更多 */
/* 可變大小的行動(dòng)清單可在后面跟著分組數(shù)據(jù)。
*如果 buffer_id = -1 目前的數(shù)據(jù)是有意義的奋早。
/ *uint8_t 數(shù)據(jù)[ 0 ] 盛霎;*/ /* 分組數(shù)據(jù) 長(zhǎng)度是從長(zhǎng)度字段的頭部計(jì)算的 */
};
OFP_ASSERT(sizeof(struct ofp_packet_out) == 24
buffer_id 與 ofp_packet_in 消息中給出的是相同的。 如果 buffer_id 是 OFP_NO_BUFFER耽装,
則數(shù)據(jù)包位于數(shù)據(jù)陣列中摩渺, 和封裝在消息里的數(shù)據(jù)包由行動(dòng)的消息進(jìn)行處理。 OFP_NO_BUFFER
等于 0xffffffff剂邮。如果 buffer_id 是有效的摇幻,相關(guān)的端口被行動(dòng)消息從緩沖區(qū)刪除。
in_port 字段表示入端口挥萌,端口必須與 OpenFlow 處理數(shù)據(jù)包相關(guān)绰姻。它必須設(shè)置為一個(gè)有效的標(biāo)準(zhǔn)交換機(jī)端口(見 4.2 )或 OFPP_CONTROLLER. 例如,當(dāng)使用 OFPP_TABLE,OFPP_IN_PORT, OFPP_ALL 和組處理數(shù)據(jù)包時(shí)就使用這個(gè)字段引瀑。
Action 是一個(gè)行動(dòng)列表定義交換機(jī)如何處理數(shù)據(jù)包的字段狂芋。可包括包修改憨栽, 組處理和一個(gè)輸出端口帜矾。 一個(gè) OFPT_PACKET_OUT 行動(dòng)清單消息也可以指定 OFPP_TABLE 保留端口作為輸出行動(dòng)來處理 OpenFlow 流水線中的數(shù)據(jù)包翼虫,從第一個(gè)流表開始(見 4.5 )。如果OFPP_TABLE 被指定屡萤, in_port 作為查找時(shí)流表的入端口珍剑。
在某些情況下,發(fā)送到 OFPP_TABLE 的數(shù)據(jù)包死陆,經(jīng)過流表項(xiàng)行動(dòng)或漏表后招拙,可能轉(zhuǎn)發(fā)給控制器。對(duì)這樣控制器到交換機(jī)回路的檢測(cè)和執(zhí)行行動(dòng)不在本規(guī)范范圍內(nèi)措译。一般來說别凤,OpenFlow 的消息不保證是順序處理。
因此领虹,如果一個(gè)使用 OFPP_TABLE 的 OFPP_TABLE 消息依賴于最近發(fā)送到交換機(jī)( 與 OFPT_FLOW_MOD 消 息 ) 的 流规哪, 一 個(gè) OFPT_BARRIER_REQUEST 消 息 需 要 在OFPT_PACKET_OUT 消息之前,確保在執(zhí)行 OFPP_TABLE 之前把流表項(xiàng)交給流表塌衰。
A.3.8 屏障消息
當(dāng) 控 制 器 要 想 確 保 消 息 已 送 到 或 想 接 收 到 通 知 來 完 成 操 作由缆, 它 可 以 使 用 一 個(gè)OFPT_BARRIER_REQUEST 消息。此消息沒有內(nèi)容猾蒂。 收到后均唉, 在執(zhí)行基于 Barrier Request任何消息之前,交換機(jī)必須處理完所有先前收到的信息肚菠,包括發(fā)送相應(yīng)的回復(fù)或錯(cuò)誤信息舔箭。
當(dāng)處理完成,交換機(jī)必須發(fā)送一個(gè)消息 OFPT_BARRIER_REPLY 攜帶 XID 最初的請(qǐng)求蚊逢。
A.3.9 任務(wù)請(qǐng)求消息
當(dāng)控制器要轉(zhuǎn)變角色层扶,它使用 OFPT_ROLE_REQUEST 消息,結(jié)構(gòu)如下:
/* 請(qǐng)求和回復(fù)消息的角色 */
struct ofp_role_request {
struct ofp_header header; /* ofpt_role_request / ofpt_role_reply 型 */
uint32_t role; /* ofpcr_role_ *之一 */
uint8_t pad[4]; /* 對(duì)齊到 64 位*/
uint64_t generation_id; /* 主設(shè)備選擇產(chǎn)生的標(biāo)識(shí)符
*/
};
OFP_ASSERT(sizeof(struct ofp_role_request) == 24);
role 字段就是控制器要擔(dān)任的新角色烙荷,并且可以有以下值:
/* 控制器的角色 */
enum ofp_controller_role {
OFPCR_ROLE_NOCHANGE = 0, /* 不改變目前的角色 */
OFPCR_ROLE_EQUAL= 1, /* 默認(rèn)角色镜会,完全訪問。 */
OFPCR_ROLE_MASTER= 2, /* 完全訪問终抽,最多一個(gè)主設(shè)備戳表。 */
OFPCR_ROLE_SLAVE= 3, /* 只讀訪問 */
};
如果消息中的角色值是 OFPCR_ROLE_MASTER 或 OFPCR_ROLE_SLAVE,交換機(jī)必須驗(yàn)證 generation_id檢查過期消息(見6.3.4)昼伴。如果驗(yàn)證失敗匾旭,交換機(jī)必須拋棄角色要求和返回OFPET_ROLE_REQUEST_FAILED 類型和 OFPRRFC_STALE 代碼的錯(cuò)誤消息。
如果角色值是 OFPCR_ROLE_MASTER, 所有其他角色是 OFPCR_ROLE_MASTER 的控制器都要改變?yōu)镺FPCR_ROLE_SLAVE (見6.3.4)圃郊。如果角色值 是OFPCR_ROLE_NOCHANGE, 控制器當(dāng)前的角色就不改變价涝; 這使控制器查詢其目前的角色而無需改變它。
收到一個(gè) OFPT_ROLE_REQUEST 的消息后持舆,如果沒有錯(cuò)誤色瘩,交換機(jī)必須返回一個(gè)OFPT_ROLE_REPLY 消息伪窖。這則消息的結(jié)構(gòu)與 OFPT_ROLE_REQUEST 消息是完全一樣的,role字段就是當(dāng)前控制的角色居兆。generation_id設(shè)置為當(dāng)前generation_id(上一次成功角色請(qǐng)求的 generation_id覆山,角色是OFPCR_ROLE_MASTER 或OFPCR_ROLE_SLAVE ),
如果目前的 generation_id 控制器沒有設(shè)置史辙,回復(fù)中的 generation_id 必須設(shè)置為最大字段 (無符號(hào)值相當(dāng)于-1)汹买。
A.3.10 設(shè)置異步配置信息
在一個(gè)給定的OpenFlow通道上佩伤,分別使用OFPT_SET_ASYNC 和OFPT_GET_ASYNC_REQUEST 消息聊倔,控制器能設(shè)置和查詢它想要接收的異步消息(除錯(cuò)誤消息)。
交換機(jī)使用 OFPT_GET_ASYNC_REPLY 消息響應(yīng)一個(gè) OFPT_GET_ASYNC_REQUEST消息生巡;它不回復(fù)一個(gè)設(shè)置配置的請(qǐng)求耙蔑。
基 于 OpenFlow 頭 部 的 OFPT_GET_ASYNC_REQUEST 消 息 沒 有 body。
OFPT_SET_ASYNC 和 OFPT_GET_ASYNC_REPLY 消息的格式如下:
/* 異步消息的配置孤荣。 */
struct ofp_async_config {
struct ofp_header header; /* OFPT_GET_ASYNC_REPLYor OFPT_SET_ASYNC.*/
uint32_t packet_in_mask[2]; /* ofpr_ *值的位掩碼 */
uint32_t port_status_mask[2]; /* ofppr_ *值的位掩碼甸陌。 */
uint32_t flow_removed_mask[2]; /* ofprr_ *值的位掩碼。. */
};
OFP_ASSERT(sizeof(struct ofp_async_config) == 32);
結(jié)構(gòu) struct ofp_async_config 包含三個(gè)二維數(shù)組盐股。每個(gè)數(shù)組控制是否接收控制器一個(gè)特定 的 枚 舉 ofp_type 異 步 消 息钱豁。 當(dāng) 控 制 器 是 OFPCR_ROLE_EQUAL 或OFPCR_ROLE_MASTER 角色時(shí),每個(gè)數(shù)組中的元素 0 表示感興趣的消息疯汁。當(dāng)控制器是OFPCR_ROLE_SLAVE 角色時(shí)牲尺, 元素為 1。每個(gè)數(shù)組元素的位掩碼中的 0 禁止接收與比特位置有關(guān)的 reason 代碼消息幌蚊。而 1 則可以接收谤碳。例如,在 port_status_mask [1] 中比特值為
2
2
=4溢豆, 當(dāng) 控 制 器 的 角 色 是 OFPCR_ROLE_SLAVE 時(shí)蜒简, 決 定 控 制 器 是 否 接 收 理 由 是OFPPR_MODIFY (值為 2)的 OFPT_PORT_STATUS 消息。
OFPT_SET_ASYNC 設(shè)置控制器是否應(yīng)該接受一個(gè)交換機(jī)產(chǎn)生的異步消息漩仙。其他的OpenFlow 功能控制是否產(chǎn)生一個(gè)給定的消息搓茬;例如,在 OFPFF_SEND_FLOW_REM 標(biāo)志控制交換機(jī)在流表項(xiàng)刪除時(shí)是否產(chǎn)生 OFPT_FLOW_REMOVED 消息队他。
一個(gè)交換機(jī)的配置垮兑,例如使用 OpenFlow 配置協(xié)議,一旦 OpenFlow 建立連接漱挎, 就可以設(shè)置異步消息的初始配置系枪。交換機(jī)沒有配置的話,初始配置應(yīng):
在“master”或“ equal ”的角色磕谅,使能所有的 OFPT_PACKET_IN 消息私爷,除了那些帶有 OFPR_INVALID_TTL 原 因 的雾棺, 使 能 所 有 的 OFPT_PORT_STATUS 和OFPT_FLOW_REMOVED 消息。
在 “ slave ” 角 色衬浑, 使 能 所 有 OFPT_PORT_STATUS 消 息捌浩,并禁用所有OFPT_PACKET_IN 和 OFPT_FLOW_REMOVED 的消息。
利用 OFPT_SET_ASYNC 的配置設(shè)置是針對(duì)一個(gè)特定的 OpenFlow 的通道工秩,它不會(huì)影響任何其他 OpenFlow 通道尸饺,無論是目前建立的或是以后建立的。
配置設(shè)置 OFPT_SET_ASYNC 不過濾器或影響的錯(cuò)誤消息助币。
A.4 異步消息
A.4.1 包輸入消息
當(dāng)數(shù)據(jù)包通過數(shù)據(jù)通路進(jìn)行接收和發(fā)送給控制器浪听,都使用 OFPT_PACKET_IN 消息:
/* 端口接收到的數(shù)據(jù)包(數(shù)據(jù)通路 ->控制器) */
struct ofp_packet_in {
struct ofp_header header;
uint32_t buffer_id; /* 分配的數(shù)據(jù)通路 ID。 */
uint16_t total_len; /* 幀全長(zhǎng) */
uint8_t reason; /* 包被發(fā)送的原因(一個(gè) ofpr_ *)*/
uint8_t table_id; /* 被查詢的流表標(biāo)識(shí)符 */
uint64_t cookie; /* 查詢的流表項(xiàng) cookie */
struct ofp_match match; /* 分組元數(shù)據(jù)眉菱〖Kǎ可變尺寸。 */
/* 可變大小和填充匹配總是跟著:
* 2 個(gè)全零填充字節(jié)俭缓,然后是以太網(wǎng)幀克伊,其長(zhǎng)度是根據(jù) header.length 推斷。
*以太網(wǎng)幀前填充的字節(jié)华坦,確保以太網(wǎng)報(bào)頭后的 IP 頭部(如果有的話)是 32 位
*/
//uint8_t pad[2]; /* 對(duì)齊 64 位+ 16 位 */
//uint8_t data[0]; /* 以太網(wǎng)幀 */
};
OFP_ASSERT(sizeof(struct ofp_packet_in) == 32);
buffer_id 是個(gè)不透明的值愿吹,數(shù)據(jù)通路使用它識(shí)別一個(gè)緩沖數(shù)據(jù)包。 當(dāng)一個(gè)數(shù)據(jù)包進(jìn)行緩存惜姐,消息的某些字節(jié)將包含在消息的數(shù)據(jù)部分犁跪。如果數(shù)據(jù)包是因?yàn)椤鞍l(fā)送給控制器”的行動(dòng)而發(fā)送, 那么流建立請(qǐng)求的ofp_action_output 會(huì)發(fā)送 max_len 字節(jié)载弄。 如果數(shù)據(jù)包其他原因發(fā)送耘拇,如無效的 TTL, 然后 OFPT_SET_CONFIG 消息至少發(fā)送 miss_send_len 字節(jié)忽妒。默認(rèn)miss_send_len是 128 字節(jié)丢间。如果數(shù)據(jù)包沒有緩沖 - 要么是因?yàn)闆]有可用的緩沖區(qū),或因明確表示通過 OFPCML_NO_BUFFER 請(qǐng)求- 整個(gè)數(shù)據(jù)包都包含在數(shù)據(jù)部分著觉, 而且 buffer_id 就是OFP_NO_BUFFER逞刷。
實(shí)現(xiàn)緩沖的交換機(jī)希望通過文檔公開嘉涌,可用的緩沖數(shù)量和緩沖區(qū)可重復(fù)使用前的時(shí)間長(zhǎng)度。交換機(jī)必須妥善處理這樣的事件夸浅,當(dāng)一個(gè) packet_in 消息緩沖仑最,而控制器沒有反應(yīng)的情況。交換機(jī)應(yīng)防止緩沖區(qū)被重復(fù)使用帆喇,直到它已由控制器處理警医,或經(jīng)過一段時(shí)間(文檔中說明)。
data 字段包含的數(shù)據(jù)包本身,或緩沖包的一小部分预皇。包頭部反映了前面處理對(duì)數(shù)據(jù)包的任何變化侈玄。
reason字段可以是這些值的某個(gè):
/* 為什么這個(gè)包被發(fā)送到控制器? */
enum ofp_packet_in_reason {
OFPR_NO_MATCH= 0, /* 沒有匹配的流(漏表流表項(xiàng)) */
OFPR_ACTION= 1, /* 輸出給控制器的行動(dòng)吟温。 */
OFPR_INVALID_TTL= 2, /* 包有無效的 TTL */
};
OFPR_INVALID_TTL 表明攜帶無效的 IP TTL 或 MPLS TTL 被 OpenFlow 流水線拒絕并 傳 給 控 制 器序仙。 不 需 要 對(duì) 每 一 個(gè) 數(shù) 據(jù) 包 都 進(jìn) 行 無 效 的 TTL 檢 查, 但 它 至 少 在 每 次OFPAT_DEC_MPLS_TTL 或OFPAT_DEC_NW_TTL 行動(dòng)應(yīng)用到一個(gè)包時(shí)進(jìn)行檢查鲁豪。
cookie 字段包含導(dǎo)致包被發(fā)送到控制器的流表項(xiàng) cookie潘悼。如果一個(gè) cookie 不能與一個(gè)特定的流有關(guān)的,這字段必須設(shè)置為 -1 (0xffffffffffffffff )爬橡。例如治唤,如果包輸入是在組存儲(chǔ)段里或從行動(dòng)集產(chǎn)生的。
當(dāng)有事件觸發(fā)包輸入消息發(fā)生堤尾,同時(shí)包含一組 OXM TLVs,match字段就反映分組的頭部和上下午。這個(gè)上下文包括與數(shù)據(jù)包以前處理發(fā)生的任何改變衔统,包括已經(jīng)執(zhí)行的行動(dòng)锦爵,行動(dòng)集的任何變化,除了無任何變化的湾宙。這OXM TLVs 必須包括上下文字段樟氢,也就是,其值不能從數(shù)據(jù)包確定的字段侠鳄。標(biāo)準(zhǔn)的上下文字段是OFPXMT_OFB_IN_PORT,
OFPXMT_OFB_IN_PHY_PORT,OFPXMT_OFB_METADATA 和OFPXMT_OFB_TUNNEL_ID. 所有位都是零的字段應(yīng)忽略埠啃。 OXM TLVs 可包括先前從分組中提取的數(shù)據(jù)包頭部字段,也包括那些在處理過程中的任何修改伟恶。
當(dāng)在物理端口直接收到一個(gè)包時(shí),而且未被邏輯端口處理博秫, OFPXMT_OFB_IN_PORT和 OFPXMT_OFB_IN_PHY_PORT 有 相 同 的 值潦牛, OpenFlow 物 理 端 口 的 port no鹃骂。
OFPXMT_OFB_IN_PHY_PORT 如果與 OFPXMT_OFB_IN_PORT 有相同的值則應(yīng)忽略。
當(dāng)一個(gè)包是通過一個(gè)物理端口的邏輯端口上接收的罢绽, OFPXMT_OFB_IN_PORT 是邏輯端口的端口的 port no畏线,OFPXMT_OFB_IN_PHY_PORT 是物理端口的 port no良价。例如,考慮一個(gè)包在隧道接口上接收痊银,接口是由兩個(gè)物理端口的鏈路匯聚組( LAG )進(jìn)行定義的抵蚊。如果隧道接口是綁定到 OpenFlow 的邏輯端口,那么OFPXMT_OFB_IN_PORT 是隧道 port no溯革,OFPXMT_OFB_IN_PHY_PORT 是已配置隧道的 LAG 物理端口 port no 成員贞绳。
OFPXMT_OFB_IN_PORT TLV 引用的端口必須是用來匹配流表項(xiàng)的端口(見 5.3 ),也必須對(duì) OpenFlow 處理有用(即 OpenFlow 可以轉(zhuǎn)發(fā)數(shù)據(jù)包到該端口致稀,依靠端口標(biāo)志)冈闭。
OFPXMT_OFB_IN_PHY_PORT 不需要有效匹配或進(jìn)行 OpenFlow 處理。
A.4.2 流刪除消息
如 果 控 制 器 請(qǐng) 求 通 知 流 表 項(xiàng) 超 時(shí) 或 從 表 中 刪 除 ( 見 5.5 )抖单, 數(shù) 據(jù) 通 路 使 用
OFPT_FLOW_REMOVED 消息:
/* 流刪除(數(shù)據(jù)通路 ->控制器) */
struct ofp_flow_removed {
struct ofp_header header;
uint64_t cookie; /* 不透明的控制器發(fā)出標(biāo)識(shí)符萎攒。 */
uint16_t priority; /* 流表項(xiàng)優(yōu)先級(jí)。 */
uint8_t reason; /* 一個(gè) ofprr_ *
uint8_t table_id; /* 流表的標(biāo)識(shí)符 */
uint32_t duration_sec; /* Time flow was alive in seconds. */
uint32_t duration_nsec;
/* Time flow was alive in nanoseconds beyond duration_sec. */
uint16_t idle_timeout; /* 從原來的 flow mod 空閑超時(shí) */
uint16_t hard_timeout; /* 從原來的 flow mod硬超時(shí)矛绘。 */
uint64_t packet_count;
uint64_t byte_count;
struct ofp_match match; /* 字段描述耍休。可變尺寸货矮。 */
};
OFP_ASSERT(sizeof(struct ofp_flow_removed) == 56);
Match羊精,cookie,和 priority 字段與那些在 flow mod 請(qǐng)求里使用的相同次屠。
Reason 字段是下列之一:
/* 為什么流中刪除园匹? */
enum ofp_flow_removed_reason {
OFPRR_IDLE_TIMEOUT= 0, /* 流idle_timeout 空閑時(shí)間超過 */
OFPRR_HARD_TIMEOUT= 1, /* 時(shí)間超過 hard_timeout。 */
OFPRR_DELETE= 2, /* 由 DELETEflow mod消除劫灶。 */
OFPRR_GROUP_DELETE= 3, /* 刪除的組裸违。 */
};
duration_sec 和 duration_nsec 字段在第 A.3.5.2 描述。
idle_timeout 和 hard_timeout 字段是直接從創(chuàng)建流表項(xiàng)的 flow mod復(fù)制本昏。
利用上述三個(gè)字段供汛,你可以找到流表項(xiàng)活躍的時(shí)間,以及流表項(xiàng)接收信息的時(shí)間。
packet_count 和 byte_count 分別表示與流表項(xiàng)相關(guān)聯(lián)的包和字節(jié)的數(shù)值怔昨。這些計(jì)數(shù)器應(yīng)像其他統(tǒng)計(jì)計(jì)數(shù)器 (見 A.3.5 )雀久;如果沒有設(shè)置, 它們都是無符號(hào)的趁舀, 并應(yīng)設(shè)置為字段最大值赖捌。
A.4.3 端口的狀態(tài)信息
當(dāng)端口被添加,修改矮烹,從數(shù)據(jù)通路中刪除越庇,利用 OFPT_PORT_STATUS 消息告知控制器:
/* 數(shù)據(jù)通路的一個(gè)物理端口改變 */
struct ofp_port_status {
struct ofp_header header;
uint8_t reason; /* 一個(gè) ofppr_*/
uint8_t pad[7]; /* 對(duì)齊到 64位。 */
struct ofp_port desc;
};
OFP_ASSERT(sizeof(struct ofp_port_status) == 80);
reason可以是下列值之一:
/* 是什么改變了關(guān)于物理端口 */
enum ofp_port_reason {
OFPPR_ADD= 0, /* 端口添加奉狈。 */
OFPPR_DELETE= 1, /* 端口被刪除 */
OFPPR_MODIFY= 2, /* 某些端口的屬性已經(jīng)改變了卤唉。 */
};
A.4.4 錯(cuò)誤消息
交換機(jī)需要把問題通知給控制器。這是通過 OFPT_ERROR_MSG 消息完成:
/* ofpt_error :錯(cuò)誤消息(數(shù)據(jù)通路 ->控制器)仁期。 */
struct ofp_error_msg {
struct ofp_header header;
uint16_t type;
uint16_t code;
uint8_t data[0]; /* 可變長(zhǎng)度的數(shù)據(jù)桑驱。用類型和代碼區(qū)分。無填充 */
};
OFP_ASSERT(sizeof(struct ofp_error_msg) == 12);
Type 的值表示錯(cuò)誤的高層次的類型跛蛋。代碼值是在類型基礎(chǔ)上解析熬的。 數(shù)據(jù)是可變長(zhǎng)度的并且基于類型和代碼解析。除非另有規(guī)定 data字段包含至少 64 字節(jié)的失敗請(qǐng)求问芬,導(dǎo)致錯(cuò)誤消息產(chǎn)生悦析,如果失敗請(qǐng)求小于 64 字節(jié)寿桨,它應(yīng)該是完整的請(qǐng)求而無填充此衅。
如果錯(cuò)誤消息是來自控制器的響應(yīng),例如亭螟, OFPET_BAD_REQUEST,OFPET_BAD_ACTION, OFPET_BAD_INSTRUCTION, OFPET_BAD_MATCH, 或OFPET_FLOW_MOD_FAILED, 那么頭部的 xid 字段必須匹配那個(gè)引起錯(cuò)誤的消息挡鞍。
以_EPERM 結(jié)束的錯(cuò)誤代碼表示一個(gè)允許產(chǎn)生的錯(cuò)誤, 例如预烙, 控制器和交換機(jī)之間插入一個(gè) OpenFlow 管理程序墨微。
目前定義的錯(cuò)誤類型是:
/*ofp_error_message 里的“ type ”值。這些值是不變的:他們不會(huì)在未來版本的協(xié)議改變(雖然新值可以添加) */
enum ofp_error_type {
OFPET_HELLO_FAILED= 0, /* hello 協(xié)議失敗 */
OFPET_BAD_REQUEST= 1, /* 請(qǐng)求不被理解 */
OFPET_BAD_ACTION= 2, /* 在行動(dòng)中描述的錯(cuò)誤扁掸。 */
OFPET_BAD_INSTRUCTION= 3, /* 指令表中錯(cuò)誤翘县。 */
OFPET_BAD_MATCH= 4, /* 錯(cuò)誤匹配。 */
OFPET_FLOW_MOD_FAILED= 5, /* 修改流表項(xiàng)問題谴分。 */
OFPET_GROUP_MOD_FAILED= 6, /* 修改組表項(xiàng)問題锈麸。 */
OFPET_PORT_MOD_FAILED= 7, /* 端口 屬性 請(qǐng)求失敗。 */
OFPET_TABLE_MOD_FAILED= 8, /* 流表請(qǐng)求失敗 */
OFPET_QUEUE_OP_FAILED= 9, /* 隊(duì)列操作失敗 */
OFPET_SWITCH_CONFIG_FAILED= 10, /* 交換機(jī)配置請(qǐng)求失敗 */
OFPET_ROLE_REQUEST_FAILED= 11, /* 控制器任務(wù)請(qǐng)求失敗 */
OFPET_METER_MOD_FAILED= 12, /* 計(jì)量器錯(cuò)誤 */
OFPET_TABLE_FEATURES_FAILED= 13, /* 設(shè)置流表功能失敗 */
OFPET_EXPERIMENTER= 0xffff /* 實(shí)驗(yàn)者的錯(cuò)誤消息 */
};
為 OFPET_HELLO_FAILED 錯(cuò)誤 type牺蹄,下面是目前定義的 codes:
/* 為OFPET_HELLO_FAILED ofp_error_msg “code”的值忘伞。 Data包含 ASCII 文本字符串,可以提供詳細(xì)的故障。 /
enum ofp_hello_failed_code {
OFPHFC_INCOMPATIBLE= 0, / 不兼容的版本 /
OFPHFC_EPERM= 1, / 允許失敗 */
};
Data 字段包含 ASCII 文本字符串氓奈,加上為什么發(fā)生錯(cuò)誤的細(xì)節(jié)翘魄。
為 OFPET_BAD_REQUEST 錯(cuò)誤 type,下面是目前定義的 code:
/* 為 OFPET_BAD_REQUESTofp_error_msg “code”的值舀奶。 Data 至少包含請(qǐng)求失敗的第一個(gè) 64
字節(jié)暑竟。 */
enum ofp_bad_request_code {
OFPBRC_BAD_VERSION= 0, /* ofp_header. 版本不支持。 */
OFPBRC_BAD_TYPE= 1, /* ofp_header.type 不支持的類型 */
OFPBRC_BAD_MULTIPART= 2, /* ofp_multipart_request.type 類型不支持 */
OFPBRC_BAD_EXPERIMENTER = 3, /* 不支持的實(shí)驗(yàn)者身份 ID(在 ofp_experimenter_header
或 ofp_multipart_request 或 ofp_multipart_reply )育勺。*/
OFPBRC_BAD_EXP_TYPE= 4, /* 實(shí)驗(yàn)者類型不支持光羞。 */
OFPBRC_EPERM= 5, /* 允許誤差 */
OFPBRC_BAD_LEN= 6, /* 類型錯(cuò)誤的請(qǐng)求長(zhǎng)度。 */
OFPBRC_BUFFER_EMPTY = 7, /* 已被使用的指定緩沖區(qū)怀大。 */
OFPBRC_BUFFER_UNKNOWN = 8, /* 指定的緩沖區(qū)不存在纱兑。 */
OFPBRC_BAD_TABLE_ID= 9, /* 指定的表標(biāo)識(shí)符無效或不存在。 */
OFPBRC_IS_SLAVE= 10, /* 拒絕因?yàn)榭刂破魇菑脑O(shè)備 */
OFPBRC_BAD_PORT= 11, /* 無效的端口 */
OFPBRC_BAD_PACKET= 12, /* 包輸出里無效的數(shù)據(jù)包 */
OFPBRC_MULTIPART_BUFFER_OVERFLOW = 13, /* ofp_multipart_request 分配的緩沖區(qū)溢出
*/
下面是目前定義 OFPET_BAD_ACTION 錯(cuò)誤type 的code:
/* OFPET_BAD_INSTRUCTION ofp_error_msg 'code'的值化借。數(shù)據(jù)至少包含請(qǐng)求失敗的第一個(gè) 64字節(jié)*/
enum ofp_bad_action_code {
OFPBAC_BAD_TYPE= 0, /* 未知的行動(dòng)類型潜慎。 */
OFPBAC_BAD_LEN= 1, /* 行動(dòng)的長(zhǎng)度問題。 */
OFPBAC_BAD_EXPERIMENTER = 2, /* 未知的實(shí)驗(yàn)者指定標(biāo)識(shí)符 */
OFPBAC_BAD_EXP_TYPE= 3, /* 實(shí)驗(yàn)者的標(biāo)識(shí)符蓖康。未知的行動(dòng) */
OFPBAC_BAD_OUT_PORT = 4, /* 問題有效輸出端口铐炫。*/
OFPBAC_BAD_ARGUMENT = 5, /* 不良行為的論證 */
OFPBAC_EPERM= 6, /* 允許的錯(cuò)誤 */
OFPBAC_TOO_MANY= 7, /* 不能處理這么多的行動(dòng)。 */
OFPBAC_BAD_QUEUE= 8, /* 問題驗(yàn)證輸出隊(duì)列蒜焊。*/
OFPBAC_BAD_OUT_GROUP = 9, /* 在轉(zhuǎn)發(fā)的動(dòng)作無效組標(biāo)識(shí)符 */
OFPBAC_MATCH_INCONSISTENT = 10, /* 行動(dòng)不能申請(qǐng)匹配倒信,或 設(shè)置字段丟失的前提。*/
OFPBAC_UNSUPPORTED_ORDER = 11, /* 應(yīng)用行動(dòng)指令的行動(dòng)列表不支持行動(dòng)排序 */
OFPBAC_BAD_TAG= 12, /* 行動(dòng)使用不支持的標(biāo)簽 / 封裝泳梆。 */
OFPBAC_BAD_SET_TYPE= 13, /* 在set_field 行動(dòng)不支持的類型鳖悠。 */
OFPBAC_BAD_SET_LEN= 14, /* 在set_field 行動(dòng)長(zhǎng)度問題。 */
OFPBAC_BAD_SET_ARGUMENT = 15, /* 在set_field 行動(dòng)不好的論據(jù) */
};
下面是目前定義為 OFPET_BAD_INSTRUCTION 錯(cuò)誤type 的code:
/* 為OFPET_BAD_INSTRUCTION ofp_error_msg “code”的值优妙。數(shù)據(jù)至少包含請(qǐng)求失敗的
第一個(gè) 64字節(jié)乘综。 */
enum ofp_bad_instruction_code {
OFPBIC_UNKNOWN_INST= 0, /* 未知的指令 */
OFPBIC_UNSUP_INST= 1, /* 交換機(jī)或表不支持的指令。 */
OFPBIC_BAD_TABLE_ID= 2, /* 指定流表標(biāo)識(shí)符無效套硼。 */
OFPBIC_UNSUP_METADATA= 3, /* 元數(shù)據(jù)值不支持的數(shù)據(jù)通路卡辰。 */
OFPBIC_UNSUP_METADATA_MASK = 4, /* 元數(shù)據(jù)的掩碼值不支持的數(shù)據(jù)通路。 */
OFPBIC_BAD_EXPERIMENTER= 5, /* 未知的實(shí)驗(yàn)者指定標(biāo)識(shí)符邪意。 */
OFPBIC_BAD_EXP_TYPE= 6, /* 實(shí)驗(yàn)者未知指令標(biāo)識(shí)符九妈。 */
OFPBIC_BAD_LEN= 7, /* 在指令長(zhǎng)度的問題。 */
OFPBIC_EPERM= 8, /* 允許的錯(cuò)誤雾鬼。 */
};
為OFPET_BAD_MATCH 錯(cuò)誤type萌朱,下面是目前定義的 code:
/* 為OFPET_BAD_MATCH ofp_error_msg “code”的值。數(shù)據(jù)至少包含請(qǐng)求失敗的第一個(gè) 64
字節(jié)呆贿。 */
enum ofp_bad_match_code {
OFPBMC_BAD_TYPE= 0, /* 不支持匹配指定的匹配類型 */
OFPBMC_BAD_LEN= 1, /* 匹配長(zhǎng)度問題 */
OFPBMC_BAD_TAG= 2, /* 匹配采用不支持的標(biāo)簽 / 封裝嚷兔。 */
OFPBMC_BAD_DL_ADDR_MASK = 3,
/* 不支持的數(shù)據(jù)地址掩碼–交換機(jī)不支持任意鏈路地址掩碼森渐。 */
OFPBMC_BAD_NW_ADDR_MASK = 4,
/* 不支持的網(wǎng)絡(luò)地址掩碼–交換機(jī)不支持任意網(wǎng)絡(luò)地址掩碼。 */
OFPBMC_BAD_WILDCARDS = 5, /* 不支持的域掩蔽或在匹配中省略的組合 */
OFPBMC_BAD_FIELD= 6, /* 在匹配中不支持的字段類型冒晰。 */
OFPBMC_BAD_VALUE= 7, /* 在匹配域不受支持的值同衣。 */
OFPBMC_BAD_MASK= 8,
/* 不支持匹配中指定的掩碼,字段不是 dl_address 或nw_address壶运。 */
OFPBMC_BAD_PREREQ= 9, /* 一個(gè)先決條件不滿足耐齐。 */
OFPBMC_DUP_FIELD= 10, /* 一種字段類型是重復(fù)的。 */
OFPBMC_EPERM= 11, /* 允許的錯(cuò)誤蒋情。 */
};
For the OFPET_FLOW_MOD_FAILEDerror type, the following codes are currently de_ned:
對(duì)于 OFPET_TABLE_MOD_FAILED 錯(cuò)誤type埠况,下面是目前定義的代碼:
/* 對(duì)于 OFPET_TABLE_MOD_FAILED 的ofp_error_msg “code”的值】醚ⅲ” data 至少包含
請(qǐng)求失敗第一個(gè) 64字節(jié)的辕翰。 */
enum ofp_flow_mod_failed_code {
OFPFMFC_UNKNOWN = 0, /* 未指定的錯(cuò)誤 */
OFPFMFC_TABLE_FULL= 1, /* 因?yàn)楸硪褲M,流不能添加狈谊。 */
OFPFMFC_BAD_TABLE_ID= 2, /* 流表不存在 */
OFPFMFC_OVERLAP= 3, /* 使用check_overlap 標(biāo)志嘗試添加重疊的流 */
OFPFMFC_EPERM= 4, /* 允許的錯(cuò)誤喜命。 */
OFPFMFC_BAD_TIMEOUT= 5, /* 因?yàn)椴恢С挚臻e / 硬超時(shí),流表不被添加河劝。 */
OFPFMFC_BAD_COMMAND = 6, /* 不支持的或未知的命令壁榕。 */
OFPFMFC_BAD_FLAGS= 7, /* 不支持的或未知的標(biāo)志。 */
};
對(duì)于 OFPET_SWITCH_CONFIG_FAILED 錯(cuò)誤type赎瞎,下面是目前定義的 code:
/* 為OFPET_SWITCH_CONFIG_FAILED 的ofp_error_msg “code”的值牌里。” data 至少包含請(qǐng)求失
敗第一個(gè) 64字節(jié)的 */
enum ofp_group_mod_failed_code {
OFPGMFC_GROUP_EXISTS = 0, /* 組不添加因?yàn)榻M添加試圖取代一個(gè)已經(jīng)存在的組 */
OFPGMFC_INVALID_GROUP= 1, /* 組不能添加因?yàn)榻M指定的組是無效的 */
OFPGMFC_WEIGHT_UNSUPPORTED = 2, /* 交換機(jī)在所選組中不支持不均等的負(fù)荷分擔(dān) */
OFPGMFC_OUT_OF_GROUPS = 3, /* 組表已滿务甥。 */
OFPGMFC_OUT_OF_BUCKETS = 4, /* 組的行動(dòng)存儲(chǔ)段已超過最大值牡辽。 */
OFPGMFC_CHAINING_UNSUPPORTED = 5, /* 交換機(jī)不支持需要轉(zhuǎn)發(fā)去的組 */
OFPGMFC_WATCH_UNSUPPORTED = 6, /* 這個(gè)組不能監(jiān)視 w指定的 atch_port 或watch_group。*/
OFPGMFC_LOOP= 7, /* 組表項(xiàng)會(huì)引起循環(huán) */
OFPGMFC_UNKNOWN_GROUP = 8, /* 組不能修改缓呛,因?yàn)樾薷慕M試圖修改一個(gè)不存在的組 */
OFPGMFC_CHAINED_GROUP = 9, /* 組不能刪除因?yàn)榱硪唤M是向其轉(zhuǎn)發(fā)催享。 */
OFPGMFC_BAD_TYPE= 10, /* 不支持的或未知的組類型 */
OFPGMFC_BAD_COMMAND = 11, /* 不支持的或未知的命令。 */
OFPGMFC_BAD_BUCKET = 12, /* 存儲(chǔ)段里的錯(cuò)誤 */
OFPGMFC_BAD_WATCH = 13, /* 在觀察端口 / 組的錯(cuò)誤哟绊。 */
OFPGMFC_EPERM= 14, /* 允許的錯(cuò)誤。 */
};
下面是目前定義為 OFPET_PORT_MOD_FAILED 錯(cuò)誤type 的代碼:
/* OFPET_METER_MOD_FAILED 的 ofp_error_msg “code”的值痰憎。Data至少包含請(qǐng)求失敗
的第一個(gè) 64字節(jié)*/
enum ofp_port_mod_failed_code {
OFPPMFC_BAD_PORT= 0, /* 指定的端口號(hào)不存在 */
OFPPMFC_BAD_HW_ADDR = 1, /* 指定的硬件地址不匹配端口號(hào) */
OFPPMFC_BAD_CONFIG= 2, /* 指定的配置無效 */
OFPPMFC_BAD_ADVERTISE= 3, /* 指定的標(biāo)識(shí)符是無效的票髓。 */
OFPPMFC_EPERM= 4, /* 允許的錯(cuò)誤. */
};
下面是目前定義為 OFPET_METER_MOD_FAILED 錯(cuò)誤type 的code:
/* OFPET_METER_MOD_FAILED 的 ofp_error_msg “code”的值。 Data至少包含請(qǐng)求
失敗的第一個(gè) 64字節(jié)*/
enum ofp_table_mod_failed_code {
OFPTMFC_BAD_TABLE= 0, /* 指定的流表不存在 */
OFPTMFC_BAD_CONFIG= 1, /* 指定的配置無效 */
OFPTMFC_EPERM= 2, /* 允許的錯(cuò)誤 */
};
下面是目前定義為 OFPET_TABLE_MOD_FAILED 錯(cuò)誤type 的code:
/* OFPET_TABLE_MOD_FAILED 的 ofp_error_msg “code”的值铣耘。 Data至少包含請(qǐng)求
失敗的第一個(gè) 64字節(jié)*/
enum ofp_queue_op_failed_code {
OFPQOFC_BAD_PORT= 0, /* 無效的端口(或端口不存在) */
OFPQOFC_BAD_QUEUE = 1, /* 隊(duì)列不存在 */
OFPQOFC_EPERM= 2, /* 允許的錯(cuò)誤 */
};
下面是目前定義為 OFPET_SWITCH_CONFIG_FAILED 錯(cuò)誤 type 的 code:
/* OFPET_SWITCH_CONFIG_FAILED 的 ofp_error_msg “code”的值洽沟。 Data至少包含請(qǐng)求失
敗的第一個(gè) 64字節(jié)*/
enum ofp_switch_config_failed_code {
OFPSCFC_BAD_FLAGS= 0, /* 指定的標(biāo)志無效 */
OFPSCFC_BAD_LEN= 1, /* 指定的長(zhǎng)度無效 */
OFPSCFC_EPERM= 2, /* 允許的錯(cuò)誤 */
};
下面是目前定義為 OFPET_ROLE_REQUEST_FAILED 錯(cuò)誤type 的code:
/* 對(duì)于 OFPET_ROLE_REQUEST_FAILED 的 ofp_error_msg “code”的值。 Data至少包含
請(qǐng)求失敗的第一個(gè) 64字節(jié)*/
enum ofp_role_request_failed_code {
OFPRRFC_STALE= 0, /* 過時(shí)消息: 舊的 generation_id. */
OFPRRFC_UNSUP= 1, /* 控制器不支持角色的變化 */
OFPRRFC_BAD_ROLE= 2, /* 無效的角色 */
};
下面是目前定義為 OFPET_METER_MOD_FAILED 錯(cuò)誤 type 的 code:
/* 對(duì)于 OFPET_METER_MOD_FAILED 的ofp_error_msg “code”的值蜗细。 Data至少包含請(qǐng)求
失敗的第一個(gè) 64字節(jié)*/
enum ofp_meter_mod_failed_code {
OFPMMFC_UNKNOWN = 0, /* 未指定的錯(cuò)誤. */
OFPMMFC_METER_EXISTS= 1, /* 計(jì)量器不加因?yàn)樵噲D取代現(xiàn)有的計(jì)量器 */
OFPMMFC_INVALID_METER= 2, /* 計(jì)量器不加因?yàn)橹付ǖ挠?jì)量器是無效的 */
OFPMMFC_UNKNOWN_METER = 3, /* 計(jì)量器不修改因?yàn)樵噲D修改一個(gè)不存在的計(jì)量器 */
OFPMMFC_BAD_COMMAND = 4, /* 不支持的或未知的命令 */
OFPMMFC_BAD_FLAGS= 5, /* 配置的標(biāo)志不支持 */
OFPMMFC_BAD_RATE= 6, /* 速率不支持 */
OFPMMFC_BAD_BURST = 7, /* 不支持的突發(fā)大小. */
OFPMMFC_BAD_BAND= 8, /* 頻帶不支持 */
OFPMMFC_BAD_BAND_VALUE = 9, /* 頻帶值不被支持 */
OFPMMFC_OUT_OF_METERS = 10, /* 沒有更多的計(jì)量器有效 */
OFPMMFC_OUT_OF_BANDS = 11, /* 對(duì)于計(jì)量器的屬性數(shù)量已超過最大值. */
};
下面是目前定義為 OFPET_TABLE_FEATURES_FAILED 錯(cuò)誤 type 的 codes:
/* 對(duì)于 OFPET_TABLE_FEATURES_FAILED 的 ofp_error_msg “code”的值裆操。 Data至
少包含請(qǐng)求失敗的第一個(gè) 64字節(jié)*/
enum ofp_table_features_failed_code {
OFPTFFC_BAD_TABLE= 0, /* 指定的流表不存在 */
OFPTFFC_BAD_METADATA= 1, /* 無效的元數(shù)據(jù)的掩碼 */
OFPTFFC_BAD_TYPE= 2, /* 未知的屬性類型. */
OFPTFFC_BAD_LEN= 3, /* 屬性長(zhǎng)度問題 */
OFPTFFC_BAD_ARGUMENT = 4, /* 不支持的屬性值 */
OFPTFFC_EPERM= 5, /* 允許的錯(cuò)誤 */
};
對(duì)于為 OFPET_EXPERIMENTER 錯(cuò)誤 type,錯(cuò)誤信息由以下結(jié)構(gòu)體和字段定義怒详,后面跟
著實(shí)驗(yàn)者定義的數(shù)據(jù):
/* OFPET_EXPERIMENTER: 錯(cuò)誤消息(數(shù)據(jù)通路 ->控制器) */
struct ofp_error_experimenter_msg {
struct ofp_header header;
uint16_t type; /* ofpet_experimenter*/
uint16_t exp_type; /* 實(shí)驗(yàn)者定義 */
uint32_t experimenter; / 實(shí)驗(yàn)者 ID與ofp_experimenter_header 中相同 */
uint8_t data[0]; /* 可變長(zhǎng)度的數(shù)據(jù)∽偾基于類型和代碼解析昆烁。無填充 */
};
OFP_ASSERT(sizeof(struct ofp_error_experimenter_msg) == 16);
實(shí)驗(yàn)者字段是實(shí)驗(yàn)者 ID,與 ofp_experimenter 結(jié)構(gòu)體中的相同(見 A.5.4 )缎岗。
A.5 對(duì)稱信息
A.5.1 Hello
OFPT_HELLO 消息由一 OpenFlow頭加一組可變尺寸 hello 元素静尼。
/* OFPT_HELLO. 此消息包含零個(gè)或多個(gè)可變尺寸的元素。未知的元素類型必須忽略 / 跳
過传泊,允許未來的擴(kuò)展 */
struct ofp_hello {
struct ofp_header header;
/* hello 元素列表 */
struct ofp_hello_elem_header elements[0]; /* 元素列表鼠渺, 0或更多 */
};
OFP_ASSERT(sizeof(struct ofp_hello) == 8);
Header字段中的 version 字段 (見A.1 )必須設(shè)置為發(fā)送者 (見6.3.1 )支持的最高 OpenFlow
協(xié)議版本。
Elemnets字段是一組 hello 元素眷细, 包含連接進(jìn)行初次握手時(shí)傳遞的可選數(shù)據(jù)拦盹。 實(shí)現(xiàn)時(shí)必須
忽略(跳過) Hello 消息中不支持的所有元素。列表中的元素類型定義如下:
/* Hello 元素類型 */
enum ofp_hello_elem_type {
OFPHET_VERSIONBITMAP= 1, /* 支持的版本位圖 */
};
元素定義包含元素的類型溪椎,長(zhǎng)度掌敬,和任何相關(guān)的數(shù)據(jù):
/* 所有hello 元素共同的頭 */
struct ofp_hello_elem_header {
uint16_t type; /* OFPHET_*之一*/
uint16_t length; /* 在本單元的字節(jié)長(zhǎng)度 */
};
OFP_ASSERT(sizeof(struct ofp_hello_elem_header) == 4);
OFPHET_VERSIONBITMAP 元素使用下列結(jié)構(gòu)和字段:
/*hello 元素的版本位圖 */
struct ofp_hello_elem_versionbitmap {
uint16_t type; /* OFPHET_VERSIONBITMAP.*/
uint16_t length; /* 在本元素的字節(jié)長(zhǎng)度 */
/* 其次是:
包含位圖的(長(zhǎng)度 -4 )字節(jié),然后(長(zhǎng)度+ 7)/ 8×8-( 長(zhǎng)度)(0 ~7) 的全零字節(jié) */
uint32_t bitmaps[0]; /* 位圖列表 - 支持的版本 */
};
OFP_ASSERT(sizeof(struct ofp_hello_elem_versionbitmap) == 4);
Bitmaps字段表示設(shè)備支持的 OpenFlow交換協(xié)議版本池磁, 可在版本協(xié)商后使用 (見6.3.1 )奔害。
對(duì)位圖的比特通過協(xié)議的 ofp_version 數(shù)索引;如果左位移數(shù)值表示的比特等于設(shè)置的ofp_version地熄,就支持這個(gè) OpenFlow版本华临。字段中包含的位圖數(shù)值取決于支持的最高版本號(hào):
ofp_version 0-31 在第一個(gè)位圖中編碼, ofp_version 32-63 在第二個(gè)位圖中編碼端考,以此類推雅潭。例如,如果一個(gè)交換機(jī)只支持 1.0 版( ofp_version= 0x01)和1.3 版(ofp_version= 0x04)却特,第一個(gè)位圖將被設(shè)置為 0x00000012扶供。
A.5.2 回送請(qǐng)求
回送請(qǐng)求消息包括一個(gè) OpenFlow頭加一個(gè)任意長(zhǎng)度的數(shù)據(jù)字段。數(shù)據(jù)字段可能是一個(gè)消息的時(shí)間戳來檢查延遲裂明,不同長(zhǎng)度來測(cè)量帶寬椿浓,或零大小來驗(yàn)證交換機(jī)和控制器之間是否活躍。
A.5.3 回送答復(fù)
回送應(yīng)答消息包括一個(gè) OpenFlow頭加上回聲請(qǐng)求消息中未修改的數(shù)據(jù)字段闽晦。
一個(gè)OpenFlow協(xié)議在實(shí)現(xiàn)時(shí)劃分成多個(gè)層扳碍, 回聲請(qǐng)求 / 應(yīng)答的邏輯應(yīng)該在 “最深” 的開發(fā)層實(shí)現(xiàn)。 例如仙蛉,在 OpenFlow的實(shí)現(xiàn)里笋敞,用戶空間進(jìn)程靠近內(nèi)核模塊,回聲請(qǐng)求 / 應(yīng)答是則在內(nèi)核模塊實(shí)現(xiàn)荠瘪。接收一個(gè)格式正確的回應(yīng)則表示端到端功能比在用戶空間的進(jìn)程中實(shí)現(xiàn)的回聲請(qǐng)求/ 應(yīng)答更可靠夯巷,同時(shí)也提供了更精確的端到端延遲時(shí)間赛惩。
A.5.4 實(shí)驗(yàn)者
實(shí)驗(yàn)者消息的定義如下:
/* 實(shí)驗(yàn)者的擴(kuò)展 */
struct ofp_experimenter_header {
struct ofp_header header; /* ofpt_experimenter*/
uint32_t experimenter; /* 實(shí)驗(yàn)者標(biāo)識(shí)符
* MSB0:低位字節(jié)由 IEEE OUI定義。
* MSB趁餐!= 0:ONF定義的 */
uint32_t exp_type; /* 實(shí)驗(yàn)者定義 */
/* 實(shí)驗(yàn)者定義任意附加數(shù)據(jù) */
};
OFP_ASSERT(sizeof(struct ofp_experimenter_header) == 16);
Experimenter 的字段是一個(gè) 32位的值喷兼,唯一標(biāo)識(shí)實(shí)驗(yàn)者。如果最高位字節(jié)是零澎怒,接下來的三個(gè)字節(jié)是實(shí)驗(yàn)者的 IEEE OUI褒搔。如果最高位字節(jié)不為零, 這是一個(gè) ONF分配的值喷面。 如果實(shí)驗(yàn)者沒有(或希望使用)他們的 OUI星瘾,他們應(yīng)該與 ONF聯(lián)系獲得一個(gè)唯一的實(shí)驗(yàn)者標(biāo)識(shí)符。
標(biāo)準(zhǔn)的 OpenFlow處理對(duì)其余部分不進(jìn)行解析惧辈,可由實(shí)驗(yàn)者任意定義琳状。
如果一個(gè)交換機(jī)不理解實(shí)驗(yàn)者的擴(kuò)充,它必須發(fā)送一個(gè)帶有OFPBRC_BAD_EXPERIMENTER 錯(cuò)誤代碼和 OFPET_BAD_REQUEST 錯(cuò)誤類型的OFPT_ERROR 消息盒齿。