RyuBook1.0案例一:SwitchingHub專案原始碼分析
開發目標
實現一個帶MAC地址學習功能的二層交換機
Openflow交換機與Openflow控制器安全通道建立步驟
- switch and controller建立未加密TCP連線或者加密的TLS連線
- 確定連線通道的Openflow版本
- 握手
- 其他操作
建立連線通道後,二者發生Hello包,進行協商Openflow版本號
完成交換Hello訊息之後建立安全通道,執行握手。Controller發生Features請求,並處理Features響應
接收到Features響應,控制器可以向交換機傳送SET_CONFIG
或者GET_CONFIG
請求訊息,進行設定交換機預設配置或者查詢交換機配置。
之後,可以進行OpenFlow的其他操作
Flow-Mod訊息
Flow-Mod(Modify Flow Entry Message)由控制器向交換機下發的設定流表項的資訊
其中 ofp_match結構體為資料包匹配部分。
程式分析
設定想要向交換機協商的OpenFlow版本號
OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
下發Table-miss流表項
設定完成該項引數配置,控制器自動執行第一步操作,即交換Hello包,協商版本號。協商完成之後,自動執行交換Features包,進行握手。
握手完成後,使用set_ev_cls函式處理Features響應包
@set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
第二項引數詳情如下:
Defination | Explanation |
---|---|
HANDSHAKE_DISPATCHER | 交換HELLO訊息 |
CONFIG_DISPATCHER | 等待接收SwitchFeatures訊息 |
MAIN_DISPATCHER | 正常狀態 |
DEAD_DISPATCHER | 連線斷開 |
定義處理函式,並解析返回包的欄位
def switch_features_handler(self, ev):
datapath = ev.msg.data
ofproto = datapath.ofproto
parser = datapath.ofproto_parser
安裝table-miss entry
match = parser.OFPMatch()
table-miss:
OpenFlow1.3版本為處理table miss事件專門引入的條目。並規定每一個flow table必須要支援table-miss flow entry去處理table miss情況。table-miss flow entry具備最低的優先順序(0);必須至少能夠支援使用CONTROLLER保留埠傳送包,使用Clear-Actions指令丟包;table-miss flow entry和其他flow entry具有相同的特性:預設不存在,控制器可以隨時新增或丟棄該條目,也可以到期;如果使用CONTROLLER保留埠發生資料包,Packet-In傳送原因必須標明table-miss。
actions = [parser.OFPActionOutput(ofproto.OFPP_CONTROLLER,
ofproto.OFPCML_NO_BUFFER)]
OFPActionOutput() :使用一個packet_out 訊息去指定你想從交換機的哪個埠傳送出資料包。在該應用中,按照標準指定通過CONTROLLER保留埠發生,所以選擇了OFPP_CONTROLLER埠。第二個引數OFPCML_NO_BUFFER,指明:訊息中必須包含完整的包,而不會被緩衝。
指定完成actions,使用類的add_flow向控制器新增流表項
self.add_flow(self, datapath, 0, match, actions)
接下來分析add_flow的具體實現過程:
構建OpenFlow流表訊息
inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS, actions)]
mod = parser.OFPFlowMod(datapath=datapath, priority=priority,
match=match, instructions=inst)
OpenFlow目前主流版本為Openflow1.0,1.1,1.3。相比1.0版本,1.3版本流表項結構變化很大,在這裡我們用到的Instruction可以說是1.0版本中Actions的擴充。Instruction主要負責將流錶轉發到其他Table,流水線,或者進行其他轉發操作。
- OFPIT_APPLY_ACTIONS: 立即應用actions操作到交換機
函式OFPFlowMod()負責構建Flow-Mod訊息
使用send()函式傳送flow-mod訊息
datapath.send(mod)
以上步驟完成下發配置table-miss流表項
MAC地址學習功能實現
MAC地址學習功能,主要要處理接收到的Packet-In資料包,所以重寫set_cls_ev函式
@set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
- ofp_event.EventOFPPacketIn: 指處理PacketIn訊息
- MAIN_DISPATCHER: ???
解析資料包
def _package_in_handler(self, ev):
msg = ev.msg
datapath = msg.datapath
ofproto = datapath.ofproto
parser = datapath.ofproto_parser
獲取datapath.id
dpid = datapath.id
datapath是交換機的唯一標識,即dpid
新增dpid: {}到mac地址、port字典中
self.mac_to_port.setdefault(dpid, {})
從datapath中解析dst,src
pkt = packet.Packet(msg.data)
eth_pkt = pkt.get_protocol(ethernet.ethernet)
dst = eth_pkt.dst
src = eth_pkt.src
從datapath中匹配出in_port
in_port = msg.match[`in_port`]
儲存in_port和mac
self.mac_to_port[dpid][src] = in_port
檢查,如果已經儲存過port和mac,如果存在,則配置out_port為指定埠;如果不存在,則使用OFPP_FLOOD埠,向全部埠進行泛洪。
if dst in self.mac_to_port[dpid]:
out_port = self.mac_to_port[dpid][dst]
else:
out_port = ofproto.OFPP_FLOOD
構建Actions
actions = [parser.OFPActionOutput(out_port)]
如果out_port非Flood埠,則下發流表到交換機
if out_port != ofproto.OFPP_FLOOD:
match = parser.OFPMatch(in_port=in_port, eth_dst=dst)
self.add_flow(datapath, 1, match, actions)
構建Packet_Out訊息,併傳送到交換機
out = parser.OFPPacketOut(datapath=datapath,
buffer_id=ofproto.OFP_NO_BUFFER,
in_port=in_port, actions=actions,
data=msg.data)
datapath.send_msg(out)
相關文章
- RyuBook1.0案例三:REST LinkageREST
- 開源專案Running Life 原始碼分析(一)原始碼
- EOS原始碼分析(3)案例分析原始碼
- Android 原始碼分析(一)專案構建過程Android原始碼
- Android 7.0 原始碼分析專案一期竣工啦Android原始碼
- jetty啟動web專案原始碼分析JettyWeb原始碼
- Spring事務原始碼分析專題(一)JdbcTemplate使用及原始碼分析Spring原始碼JDBC
- 走進開源專案 - urlcat 原始碼分析原始碼
- Android 開源專案PhotoView原始碼分析AndroidView原始碼
- 專案中常用的 .env 檔案原理原始碼分析原始碼
- python專案例項原始碼-32個Python爬蟲實戰專案,滿足你的專案慌(帶原始碼)Python原始碼爬蟲
- ThinkPHP3.1.3原始碼分析(一) 入口檔案分析PHP原始碼
- Egg.js 原始碼分析-專案啟動JS原始碼
- 社交app開發|原始碼出售|案例詳情|專案測試APP原始碼
- 分散式服務框架Dubbo入門案例和專案原始碼分散式框架原始碼
- 超讚!推薦一個專注於Java後端原始碼分析的Github專案!Java後端原始碼Github
- 使用 functrace 輔助進行 Go 專案原始碼分析Go原始碼
- 深度 Mybatis 3 原始碼分析(一)SqlSessionFactoryBuilder原始碼分析MyBatis原始碼SQLSessionUI
- 原始碼|jdk原始碼之HashMap分析(一)原始碼JDKHashMap
- MyBatis原始碼分析(一)MyBatis原始碼
- preact原始碼分析(一)React原始碼
- Redux原始碼分析(一)Redux原始碼
- RecyclerView 原始碼分析(一)View原始碼
- AFL原始碼分析(一)原始碼
- 原始碼分析一:EventBus原始碼
- Backbone原始碼分析(一)原始碼
- Cobar 原始碼分析(一)原始碼
- YYCache 原始碼分析(一)原始碼
- Spring原始碼學習一_下載Spring專案原始碼並編譯為Eclipse專案Spring原始碼編譯Eclipse
- Android 開源專案原始碼解析 -->Android Universal Image Loader 原始碼分析(十四)Android原始碼
- javaee7案例原始碼下載Java原始碼
- 完整的python專案例項-Python例項練手專案彙總(附原始碼)Python原始碼
- LinkedList原始碼分析(一)原始碼
- DelayQueue系列(一):原始碼分析原始碼
- Swift原始碼專案編譯Swift原始碼編譯
- 專案管理-原始碼管理薦專案管理原始碼
- 34套Java專案教程+原始碼包含Java swing專案 Java web專案 Java控制檯專案(視訊教程+原始碼)Java原始碼Web
- Myth原始碼解析系列之一-專案簡介原始碼