一、 掌握OpenFlow交換機發送Packet-in消息過程及其消息格式。
二、 掌握OpenFlow控制器發送Packet-out消息過程及其消息格式。緩存
使用Packet-In消息的目的是爲了將到達OpenFlow交換機的數據包發送至OpenFlow控制器。如下2種狀況便可發送Packet-In消息。cookie
不存在與流表項一致的項目時(Table-miss),OFPR_NO_MATCH
匹配的流表項中記載的行動爲「發送至OpenFlow控制器」時,OFPR_ACTION網絡
發送Packet-In消息時OpenFlow交換機分爲兩種狀況,一種是緩存數據包,一種是不緩存數據包。若是不經過OpenFlow交換機緩存數據包,那麼Packet-In消息的buffer_id字段設置爲-1,將整個數據包發送至OpenFlow控制器。
若是經過OpenFlow交換機緩存數據包,那麼以經過SET_CONFIG消息設置的miss_send_len爲最大值的數據包數據將發送至OpenFlow控制器。
miss_send_len的默認值爲128。未實施SET_CONFIG消息的交換時,使用該默認值。app
字段 | 比特數 | 內容 |
buffer_id | 32 | 表示OpenFlow交換機中保存的數據包的緩存id |
Total_len | 16 | 幀的長度 |
in_port | 16 | 接受幀的端口 |
reason | 8 | 發送Packet-in消息的緣由 |
pad | 8 | 用於調整對齊的填充 |
data | 任意 | 包含以太網幀的數據時使用的字段。 |
Packet-Out消息是從OpenFlow控制器向OpenFlow交換機發送的消息,是包含數據包發送命令的消息」。
若OpenFlow交換機的緩存中已存在數據包,而OpenFlow控制器發出「發送該數據包」的命令時,該消息指定了表示相應數據包的buffer_id。使用Packet-Out消息還可將OpenFlow控制器建立的數據包發送至OpenFlow交換機。此時,buffer_id置爲-1,在Packet-Out消息的最後添加數據包數據。3d
字段 | 比特數 | 內容 |
buffer_id | 32 | 表示OpenFlow交換機中保存的數據包的緩存id |
in_port | 16 | 數據包的輸入端口 |
actions_len | 16 | 行動信息的長度 |
制器與OpenFlow交換機在鏈接創建過程當中會存在拓撲發現的環節,該環節會密集出現Packe-in/out消息,其交互流程以下:rest
一、 SDN控制器經過構造Packet-out消息,向交換機s1的三個端口分別發送上圖所示的LLDP數據包。
二、 控制器向交換機s1下發流表,流表規則爲:將從Controller端口收到的LLDP數據包從規定端口發送出去。
三、 控制器向交換機s2下發流表,流表規則爲:將從非Controller接收到LLDP數據包發送給控制器。
四、 當LLDP數據包到達交換機s2,會觸發Packet-in消息發往控制器。控制器經過解析LLDP數據包,獲得鏈路的源交換機,源接口(s1,port1)。經過收到的Packet-in消息知道目的交換機(s2)。
五、 同理,當SDN控制器向交換機s2發送Packet-out消息時,能夠得知鏈路源交換機,源接口(s2,port3)。經過收到的Packet-in消息知道目的交換機(s1)。如此,控制器便發現了s1與s2之間的完整鏈路。
對於存在多個交換機的網絡,上述分析過程同樣成立。code
登陸控制器,切換至root用戶。輸入以下命令,啓動RYU相關應用。blog
ryu-manager --verbose --observe-links ryu.topology.switches ryu.app.rest_topology ryu.app.ofctl_rest ryu.app.simple_switch_13
接口
再打開新的命令窗口,切換到root用戶。執行wireshark命令啓動Wireshark,抓包enp0s17ip
登陸Mininet所在的主機,切換至root用戶。執行命令mn —controller=remote,ip=30.0.1.3, port=6633 —switch=ovsk,protocols=OpenFlow13 —topo=linear,2
,以下圖所示。
執行命令links
登陸控制器,中止Wireshark,觀察數據包列表,能夠看出控制器與交換機的基本交互流程。
步驟1 登陸Mininet所在的主機,查看交換機s1的流表信息(s2同理):
ovs-ofctl dump-flows -O OpenFlow13 s1 root@mininet:~# ovs-ofctl dump-flows -O OpenFlow13 s1 cookie=0x0, duration=495.916s, table=0, n_packets=552, n_bytes=33120, priority=65535,dl_dst=01:80:c2:00:00:0e,dl_type=0x88cc actions=CONTROLLER:65535 cookie=0x0, duration=495.923s, table=0, n_packets=50, n_bytes=4923, priority=0 actions=CONTROLLER:65535
紅色標記的流表項中:dl_type=0x88cc
表示LLD
P幀,dl_dst=01:80:c2:00:00:0e
表示目的MAC地址爲局域網組播地址,actions=CONTROLLER:65535
表示行動爲發往控制器的65535端口,意味着輸入到交換機中的LLDP組播幀都會發送到控制器。
步驟2 在控制器Wireshark抓取的數據包中,尋找包含LLDP包的Packet-out消息並雙擊,詳細信息展現以下。
能夠看出,該控制器與OpenFlow交換機協商的OpenFlow版本爲1.3版本,消息類型爲Packet-out
。由紅色標記部分信息能夠看出Packet-out消息中包含LLDP幀,動做爲從交換機的端口2發出,以此來檢測網絡拓撲結構。
步驟3 在控制器Wireshark抓取的數據包中,尋找包含LLDP包的Packet-in消息並雙擊,詳細信息展現以下。
當LLDP
幀被髮送至相鄰的交換機後,與事先設置好的流表項進行匹配(紅色標記表示Packet-in
消息觸發緣由爲:匹配的流表項的行動爲「發往控制器」),經過Packet-in
消息封裝LLDP幀,把消息發送到控制器。
步驟4 在控制器中重啓Wireshark,準備抓取Packet-in消息。
步驟5 在Mininet主機中,刪除交換機s1的流表,同時快速進行Ping操做。
$ sh ovs-ofctl del-flows s1 -O OpenFlow13 $ sh ovs-ofctl dump-flows s1 -O OpenFlow13 $ h1 ping h2
步驟6 在控制器中查看Wireshark,添加過濾條件icmp,尋找觸發緣由爲「OFPR_NO_MATCH」的Packet-in消息並雙擊。該消息的詳細狀況以下。
因爲OpenFlow交換機中不存在流表項,故發送到OpenFlow交換機的ICMP
包沒法匹配流表,只好封裝並上傳到控制器。紅色標記代表該Packet-in
消息觸發緣由爲:不存在匹配的流表項(OFPR_NO_MATCH)。