一、 熟悉Flow-Mod消息觸發場景。
二、 掌握Flow-Mod消息格式和經常使用字段含義。shell
OpenFlow 協議支持3種消息類型:Controller-to-Switch
(控制器—交換機)、Asynchronous
(異步)和Symmetric
(對稱),每一類消息又有多個子消息類型。
一、 Controller-Switch
(控制器—交換機)消息,這類消息由控制器發起。包括Features、Configuration、Modify-State、Read-State、Send-Packet、Barrier等幾類消息,用於對OF交換機的管理。
二、 Asynchronous
(異步)消息,這類消息用來將網絡事件或交換機狀態的變化更新到控制器。主要包括4種子類型:Packet-in、Flow-Removed、Port-status和Error消息。
三、 Symmetric
(同步)消息與前兩類消息有所不一樣,Symmetric類的消息可由控制器或者OF交換機中的任意一側發起,這類消息包括如下3種類型:Hello、Echo和Vendor。
Modify-State消息是OpenFlow消息中最爲重要的消息類型,控制器經過Port-mod消息用來管理端口狀態,經過Flow-mod消息增刪交換機的流表項,考慮到流表在OpenFlow的重要意義,在此針對Flow-mod消息進行詳盡分析。
圖1是Flow-mod消息的具體格式,其主要字段含義介紹以下:數組
wildcard
字段,表示匹配時12元組的掩碼位,被掩蓋掉的元組不參加匹配。in_port
到tp_dst
字段,表示流表項12元組的信息。cookie
字段,在處理數據分組時不會用到,控制器經過該字段來過濾流的統計信息。command
字段,表示對流表的操做,包括增長(Add)、刪除(Delete)、修改(Modify)等。idle_time
字段,表示當這條流表項在這段時間內沒有匹配到數據分組,則該流表項失效。hard_time
字段,表示自流表項下發後只要過了這段時間即刻失效。priority
字段,表示該流表項被處理的優先級,原則上優先級越高,所屬的Table號就越小。buffer_id
字段,表示對應Packet-in消息的buffer_id。out_port
字段,僅在command爲Delete或者Delete Strict時有效,代表當某表項不只匹配了Flow-mod中給出的12元組,且轉發動做中指定端口等於該out_port的動做時才予以刪除,即對刪除操做的一種額外限制。flags
字段,該字段爲標誌位,OpenFlow v1.0中包括3項:OFPFF_SEND_FLOW_REM(流表失效時是否向控制器發送Flow-removed消息),OFPFF_CHECK_OVERLAP(交換機是否檢測流表衝突),OFPFF_EMERG(該流表項將被存於Emergency Flow Cache中,僅在交換機處於緊急模式時生效)。actions
字段,該字段是個數組,表示要對知足過濾條件的流作的動做列表,actions[0]即表明其中第一個動做。選擇控制器1,打開命令行終端,登陸RYU控制器。執行ifconfig命令,查看控制器IP,以下圖所示。cookie
執行cd openlab/ryu/ryu/app命令,進入RYU主程序所在的文件位置。網絡
執行以下命令,啓動RYU控制器。app
$sudo ryu-manager --verbose simple_switch_13.py ofctl_rest.py rest_topology.py
登陸Mininet所在主機,執行ifconfig命令,查看Mininet所在主機的IP,以下圖所示curl
登陸RYU控制器,啓動抓包工具Wireshark,捕獲控制器與交換機創建鏈接後,控制器自動發送給交換機的flow_mod消息。執行如下命令:異步
$ sudo wireshark
雙擊enp0s17網卡,查看enp0s17網卡上數據包收發狀況,以下圖所示。工具
選擇openflowV4過濾openflow13url
登陸mininet所在主機,鏈接控制器命令行
$ sudo mn --controller=remote,ip=30.0.1.3,port=6633
登陸RYU控制器,中止Wireshark,觀察數據包列表。
能夠看到控制器會發出flow_mod
消息,該消息的Commend
爲ADD,表示添加流表項。整個消息能夠分爲三部分:openflow主體部分、match部分、instruction部分,其中instruction部分能夠省略。match部分是匹配條件,instruction部分是指令,當一個數據包知足匹配條件就會執行instruction中的指令。控制器發送的add消息中action爲output,而output的端口是controller,也就是說讓交換機將符合匹配要求的數據包都轉發給控制器,以下圖所示。
步驟1 選擇控制器1,打開命令行終端,登陸RYU控制器,執行sudo wireshark命令,啓動Wireshark。
步驟2 在控制器中再打開一個Terminal,輸入如下命令獲取交換機DPID,以下圖所示。
$ curl http://localhost:8080/stats/switches
步驟3 添加流表項,執行如下命令,具體命令以下所示。
$ curl -X POST -d '{"dpid": 1, "cookie": 1, "cookie_mask": 1,"table_id": 1,"idle_timeout": 300,"hard_timeout": 300,"priority": 35,"flags": 1,"match":{"in_port":1},"actions":[{"type":"OUTPUT","port": 2}]}' http://localhost:8080/stats/flowentry/add
dpid的值就是上面獲取到交換機的DPID
,priority
是流表項的優先級,默認值是32767
,最大值也是32767。本例中,能夠理解爲「將交換機port1端口接收到的數據包都從port2轉發出去」。
步驟5 執行如下命令,修改流表項1的優先級和action。
$ curl -X POST -d '{"dpid": 1, "cookie": 1, "cookie_mask": 1, "table_id": 1, "idle_timeout": 300, "hard_timeout": 300, "priority": 30, "flags": 1, "match":{"in_port":1},"actions":[]}' http://localhost:8080/stats/flowentry/modify_strict
步驟6 查看對應的flow_mod消息,Commond是MODIFY_STRICT,MODIFY_STRICT類型息用來修改某一條指定的流表項。從消息能夠看出被修改的流表項的priority是30,匹配條件是in_port爲1,以下圖所示。
步驟7 執行如下命令,刪除流表項1。
$ curl -X POST -d '{"dpid": 1, "cookie": 1, "cookie_mask": 1, "table_id": 1, "idle_timeout": 300, "hard_timeout": 300, "priority": 30, "flags": 1, "match":{"in_port":1},"actions":[]}' http://localhost:8080/stats/flowentry/delete_strict
步驟8 查看對應的flow_mod消息,Commend是DELETE_STRICT,DELETE_STRICT類型消息表示刪除某一條指定的流表項。該消息代表刪除的流表項的priority是30,匹配條件是in_port爲2,以下圖所示。