自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Ryu拓?fù)浒l(fā)現(xiàn)原理分析

網(wǎng)絡(luò)
Ryu拓?fù)浒l(fā)現(xiàn)的核心模塊是ryu/topology目錄下的switches.py,拓?fù)浒l(fā)現(xiàn)的應(yīng)用是同目錄下的dumper.py。在dumper.py中,會(huì)利用_CONTEXTS來(lái)實(shí)例化switches.py中的Switches類,然后將拓?fù)浒l(fā)現(xiàn)的相關(guān)信息通過日志方式(LOG.debug)顯示。

Ryu拓?fù)浒l(fā)現(xiàn)的核心模塊是ryu/topology目錄下的switches.py,拓?fù)浒l(fā)現(xiàn)的應(yīng)用是同目錄下的dumper.py。在dumper.py中,會(huì)利用_CONTEXTS來(lái)實(shí)例化switches.py中的Switches類,然后將拓?fù)浒l(fā)現(xiàn)的相關(guān)信息通過日志方式(LOG.debug)顯示。啟動(dòng)命令如下所示:

ryu-manager –verbose –observe-links ryu.topology.dumper 

或者

ryu-manager –verbose –observe-links ./ryu/topology/dumper.py

其中–verbose參數(shù)用于顯示LOG.debug信息,–observe-links用于指明拓?fù)浒l(fā)現(xiàn)。

[[150264]]

接下來(lái)對(duì)拓?fù)浒l(fā)現(xiàn)的核心模塊switches.py進(jìn)行分析。

1. Port類

存儲(chǔ)端口相關(guān)信息,數(shù)據(jù)成員有:

self.dpid = dpid
self._ofproto = ofproto
self._config = ofpport.config
self._state = ofpport.state
self.port_no = ofpport.port_no
self.hw_addr = ofpport.hw_addr
self.name = ofpport.name

其中要特別注意的是dpid和port_no,即交換機(jī)ID和端口號(hào),這兩個(gè)信息在下發(fā)流表項(xiàng)時(shí)很重要。

2. Switch類

存儲(chǔ)交換機(jī)相關(guān)信息,數(shù)據(jù)成員有:

self.dp = dp
self.ports = []

其中dp是Datapath類的實(shí)例,該類定義在在ryu/controller/controller.py,主要屬性有:

self.socket = socket
self.address = address
self.is_active = True
self.id = None # datapath_id is unknown yet
self.ports = None

ports是一個(gè)由Port類實(shí)例組成的列表,存儲(chǔ)該交換機(jī)的端口。

3. Link類

保存的是源端口和目的端口(都是Port類實(shí)例),數(shù)據(jù)成員有:

self.src = src
self.dst = dst

4. PortState類

該類繼承自dict,保存了從port_no(int型)到port(OFPPort類實(shí)例)的映射。該類主要用作self.port_state字典的值(鍵是dpid),用于存儲(chǔ)dpid對(duì)應(yīng)的交換機(jī)的所有端口情況。

OFPPort類定義在ryu/ofproto目錄下對(duì)應(yīng)的ofproto_v1_X_parser.py中(X代表版本號(hào)),繼承自一個(gè)namedtuple,保存有port_no等信息。

5. PortData類

保存每個(gè)端口與對(duì)應(yīng)的LLDP報(bào)文數(shù)據(jù),數(shù)據(jù)成員有:

self.is_down = is_down
self.lldp_data = lldp_data(這是LLDP報(bào)文的數(shù)據(jù))
self.timestamp = None
self.sent = 0

每調(diào)用一次lldp_sent函數(shù),便會(huì)把self.timestamp置為當(dāng)前的時(shí)間(time.time()),并將self.sent加1;每調(diào)用一次lldp_received函數(shù),便會(huì)把self.sent置為0。

6.PortDataState類

繼承自dict類,保存從Port類到PortData類的映射。該類維護(hù)了一個(gè)類似雙向循環(huán)鏈表的數(shù)據(jù)結(jié)構(gòu),并重寫了__iter__(),使得遍歷該類的實(shí)例(self.ports)時(shí),會(huì)按照該雙向循環(huán)鏈表從哨兵節(jié)點(diǎn)(self._root)后一個(gè)節(jié)點(diǎn)開始遍歷。

包含一個(gè)add_port函數(shù),傳入port和lldp_data,port作鍵,構(gòu)建的PortData類實(shí)例作為值。

包含一個(gè)lldp_sent(self,port)函數(shù),根據(jù)傳入的port(Port類實(shí)例)獲得對(duì)應(yīng)的PortData類實(shí)例port_data,然后調(diào)用port_data.lldp_sent()(該函數(shù)會(huì)設(shè)置時(shí)間戳),再調(diào)用self._move_last_key(port),把該port移到類似雙向循環(huán)鏈表的數(shù)據(jù)結(jié)構(gòu)中哨兵節(jié)點(diǎn)的前面(相當(dāng)于下次遍歷的末尾);***返回port_data。

7. LinkState類

繼承自dict,保存從Link類到時(shí)間戳的映射。數(shù)據(jù)成員self._map字典用于存儲(chǔ)Link兩端互相映射的關(guān)系。

8. LLDPPacket類

靜態(tài)方法lldp_packet(dpid,port_no,dl_addr,ttl)用于構(gòu)造LLDP報(bào)文,靜態(tài)方法lldp_parse(data)用于解析LLDP包,并返回源DPID和源端口號(hào)。

9. Switches類

該類是Ryu拓?fù)浒l(fā)現(xiàn)的核心所在。Switches類是app_manager.RyuApp類的子類,當(dāng)運(yùn)行switches應(yīng)用時(shí)會(huì)被實(shí)例化,其__init__函數(shù)主要包括:

self.name = ‘switches’
self.dps = {} # datapath_id => Datapath class
self.port_state = {} # datapath_id => ports
self.ports = PortDataState() # Port class -> PortData class
self.links = LinkState() # Link class -> timestamp
self.is_active = True

self.dps字典用于保存dpid到Datapath類實(shí)例的映射,會(huì)在_register函數(shù)中添加新成員,_unregister函數(shù)中刪除成員。遍歷該字典可以得到連接的所有交換機(jī)。

self.port_state字典中鍵為dpid,值為PortState類型。遍歷該字典可以得到所有交換機(jī)對(duì)應(yīng)的端口情況。當(dāng)交換機(jī)連接時(shí),會(huì)檢查交換機(jī)的id是否在self.port_state中,不在則創(chuàng)建PortState類實(shí)例,把交換機(jī)的所有端口號(hào)和端口存儲(chǔ)到該實(shí)例中;交換機(jī)斷開時(shí),會(huì)從self.port_state中刪除。

self.ports是PortDataState類的實(shí)例,保存每個(gè)端口(Port類型)對(duì)應(yīng)的LLDP報(bào)文數(shù)據(jù)(保存在PortData類實(shí)例中),遍歷self.ports用于發(fā)送LLDP報(bào)文。

self.links是LinkState類的實(shí)例,保存所有連接(Link類型)到時(shí)間戳的映射。遍歷self.links的鍵即可得到所有交換機(jī)之間的連接情況。

如果ryu-manager啟動(dòng)時(shí)加了–observe-links參數(shù),則下面的self.link_discovery將為真,從而執(zhí)行if下面的語(yǔ)句:

self.link_discovery = self.CONF.observe_links
if self.link_discovery:
self.install_flow = self.CONF.install_lldp_flow
self.explicit_drop = self.CONF.explicit_drop
self.lldp_event = hub.Event()
self.link_event = hub.Event()
self.threads.append(hub.spawn(self.lldp_loop))
self.threads.append(hub.spawn(self.link_loop))

綜上所述,該初始化函數(shù)__init__()主要是創(chuàng)建用于存儲(chǔ)相關(guān)信息的數(shù)據(jù)結(jié)構(gòu),創(chuàng)建兩個(gè)事件,然后調(diào)用hub.spawn創(chuàng)建兩個(gè)新線程執(zhí)行self.lldp_loop和self.link_loop兩個(gè)函數(shù)。

#p#

9.1 lldp_loop函數(shù)

lldp_loop函數(shù)里是一個(gè)while循環(huán),只要self.is_active為真,就一直循環(huán)執(zhí)行。(close函數(shù)會(huì)把self.is_active置為False,該函數(shù)在離開模塊時(shí)自動(dòng)被調(diào)用)。

(1)執(zhí)行self.lldp_event.clear(),將Event類實(shí)例lldp_event的_cond屬性設(shè)為False,用于線程間同步。

提到線程同步,常用的函數(shù)有:

Event.wait()

Event對(duì)象的wait的方法只有內(nèi)部信號(hào)為真的時(shí)候才會(huì)很快的執(zhí)行并完成返回。當(dāng)Event對(duì)象的內(nèi)部信號(hào)標(biāo)識(shí)為假時(shí),則wait方法一直等待其為真時(shí)才返回。同時(shí)可以對(duì)wait設(shè)置timeout,當(dāng)達(dá)到timeout設(shè)置的時(shí)間的時(shí)候就可以完成返回或執(zhí)行。

Event.set()

將標(biāo)識(shí)位設(shè)為Ture

Event.clear()

將標(biāo)識(shí)伴設(shè)為False。

Event.isSet()

判斷標(biāo)識(shí)位是否為Ture。

(2)創(chuàng)建ports_now和ports兩個(gè)列表,分別存儲(chǔ)尚未發(fā)送過LLDP報(bào)文的端口和已發(fā)送過LLDP報(bào)文并且超時(shí)的端口。

(3)遍歷self.ports(PortDataState類的實(shí)例),獲得key(Port類實(shí)例)和data(PortData類實(shí)例),如果data.timestamp為None(該端口還沒發(fā)送過LLDP報(bào)文),則將key(端口)加入ports_now列表;否則,計(jì)算下次應(yīng)該發(fā)送LLDP報(bào)文的時(shí)間expire,如果已經(jīng)超時(shí),則放到ports列表,否則就是還沒到發(fā)送時(shí)間,停止遍歷(發(fā)送LLDP報(bào)文時(shí)是按序發(fā)的,找到***個(gè)未超時(shí)的端口,后面的端口肯定更沒有超時(shí),因?yàn)楹竺娑丝谏洗伟l(fā)送LLDP是在前一端口之后,前一個(gè)都沒超時(shí)后面的自然也沒超時(shí))。

(4)遍歷ports_now列表,對(duì)每個(gè)端口調(diào)用self.send_lldp_packet(port),發(fā)送LLDP報(bào)文。

send_lldp_packet函數(shù)執(zhí)行過程如下:

a. 調(diào)用PortDataState類的lldp_sent函數(shù),該函數(shù)會(huì)設(shè)置時(shí)間戳,移動(dòng)相應(yīng)端口在雙向循環(huán)鏈表中的位置,***返回PortData類實(shí)例port_data;

b. 如果該端口已經(jīng)down掉,直接返回,否則執(zhí)行下一步;

c. 根據(jù)port.dpid得到對(duì)應(yīng)的Datapath類實(shí)例dp,如果不存在,則直接返回,否則執(zhí)行下一步;

d. 發(fā)送LLDP報(bào)文。具體地:(1)生成actions:從port.port_no端口發(fā)出消息;(2)生成PacketOut消息:datapath指定為上一步得到的dp,actions為前面的,data為步驟a中返回的port_data的lldp_data;

(5)遍歷ports列表,對(duì)每個(gè)端口調(diào)用self.send_lldp_packet(port),發(fā)送LLDP報(bào)文。

9.2 link_loop函數(shù)

link_loop函數(shù)也是一個(gè)while循環(huán),只要self.is_active為真,就一直循環(huán)執(zhí)行;

(1)執(zhí)行self.link_event.clear(),將Event類實(shí)例link_event的_cond屬性設(shè)為False,用于線程間同步;

(2)創(chuàng)建deleted列表;

(3)遍歷self.links(LinkState類實(shí)例),獲得link(Link類實(shí)例)和timestamp時(shí)間戳。如果已經(jīng)超時(shí),且該link對(duì)應(yīng)的源端口是否在self.ports中,并且發(fā)送LLDP次數(shù)已超過self.LINK_LLDP_DROP,則添加到deleted列表中;

(4)遍歷deleted列表,執(zhí)行:

a. 對(duì)其中的每條需要?jiǎng)h除的link調(diào)用link_down函數(shù)(該函數(shù)會(huì)刪除self.links中l(wèi)ink對(duì)應(yīng)的項(xiàng)目,并刪除self.links._map中l(wèi)ink對(duì)應(yīng)的項(xiàng)目),并觸發(fā)EventLinkDelete事件。

b. 得到link對(duì)應(yīng)的反向link,如果反向link不在deleted列表中,則將self.links中反向link的時(shí)間戳置為超時(shí)的事件,并將對(duì)端端口從self.ports的雙向循環(huán)鏈表中移動(dòng)到哨兵節(jié)點(diǎn)的后面(下次檢查的開頭),以便盡早檢查反向link是否也斷開了。

9.3 state_change_handler

該函數(shù)用于處理EventOFPStateChange事件,當(dāng)交換機(jī)連接或者斷開時(shí)會(huì)觸發(fā)該事件。

如果狀態(tài)是MAIN_DISPATCHER:

(1)從ev.datapath獲得Datapath類實(shí)例dp,如果該dp的dpid已經(jīng)在self.dps里有,則報(bào)出重復(fù)鏈接的警告。

(2)調(diào)用_register(),將dp.id和dp添加到self.dps中;如果該dp.id不在self.port_state中,則創(chuàng)建該dp.id對(duì)應(yīng)的PortState實(shí)例,并遍歷dp.ports.values,將所有port(OFPPort類型)添加到該P(yáng)ortState實(shí)例中。

(3)調(diào)用_get_switch(),如果dp.id在self.dps中,則創(chuàng)建一個(gè)Switch類實(shí)例,并把self.port_state中對(duì)應(yīng)的端口都添加到該實(shí)例中,最終返回該實(shí)例。

(4)如果交換機(jī)沒有重復(fù)連接,觸發(fā)EventSwitchEnter事件。

(5)如果沒設(shè)置self.link_discovery,返回;否則執(zhí)行下一步。

(6)如果設(shè)置了self.install_flow,則根據(jù)OpenFlow版本生成相應(yīng)流表項(xiàng),使得收到的LLDP報(bào)文(根據(jù)目的MAC地址匹配)上報(bào)給控制器。

(7)如果交換機(jī)沒有重復(fù)連接,則遍歷(3)中得到的switch.ports的所有端口,如果端口port不是被保留的,則調(diào)用self._port_added(port),該函數(shù)會(huì)調(diào)用LLDPPacket.lldp_packet()函數(shù)生成LLDP報(bào)文數(shù)據(jù)lldp_data(用于和“port.is_down()”一起構(gòu)造PortData類實(shí)例),然后調(diào)用PortDataState類的add_port(port,lldp_data)。

add_port()函數(shù)會(huì)檢查port是否在self.ports中,不在則將該port添加到雙向循環(huán)鏈表中哨兵節(jié)點(diǎn)的后面(下次檢查的開頭),并把port和對(duì)應(yīng)的PortData類實(shí)例(該端口對(duì)應(yīng)的LLDP報(bào)文數(shù)據(jù))添加到self.ports中。

(8)調(diào)用self.lldp_event.set()

如果狀態(tài)是DEAD_DISPATCHER:

(1)如果dp.id為None,即握手之前交換機(jī)就斷開連接了,則直接返回;否則執(zhí)行下一步。

(2)調(diào)用_get_switch()獲得Switch實(shí)例;

(3)調(diào)用_unregister(),從self.dps和self.port_state中刪除該dpid對(duì)應(yīng)的數(shù)據(jù);

(4)觸發(fā)EventSwitchLeave事件。

(5)如果沒有設(shè)置link_discovery,返回;否則執(zhí)行下一步。

(6)遍歷switch.ports中的每個(gè)端口port,如果不是保留端口,則調(diào)用PortDataState類的del_port(),將self.ports中port對(duì)應(yīng)的數(shù)據(jù)刪除;調(diào)用Switches類的_link_down()。_link_down函數(shù)執(zhí)行如下操作:

a. 調(diào)用LinkState類的port_deleted函數(shù)。在port_deleted函數(shù)里,首先調(diào)用get_peer()獲得對(duì)端端口,然后生成兩個(gè)Link對(duì)象(src->dst和dst->src),并將這兩個(gè)對(duì)象從self.links中刪除(反向Link可能不存在);刪除src->dst和dst->src之間的映射(存儲(chǔ)在_map字典中)。***返回傳入的port對(duì)應(yīng)的對(duì)端port和傳入的port本身。

b. 根據(jù)返回的“傳入的port對(duì)應(yīng)的對(duì)端port和傳入的port本身”,創(chuàng)建Link對(duì)象,觸發(fā)EventLinkDelete事件(如果反向連接也存在,會(huì)觸發(fā)兩次EventLinkDelete事件)。

c. 調(diào)用self.ports.move_front(dst),該函數(shù)會(huì)從self.ports中得到dst對(duì)應(yīng)的PortData類實(shí)例port_data,如果port_data不為None,則調(diào)用clear_timestamp函數(shù)將其timestamp屬性置為None,并將dst移動(dòng)到雙向循環(huán)鏈表中哨兵節(jié)點(diǎn)的后面(下次檢查的開頭)。

(7)調(diào)用self.lldp_event.set()。

#p#

9.4 port_status_handler

該函數(shù)用于處理EventOFPPortStatus事件,該事件是交換機(jī)主動(dòng)發(fā)給控制器的。

如果原因?yàn)?ldquo;添加”:

(1)在self.port_state里dp.id對(duì)應(yīng)的PortState實(shí)例中添加該端口,并觸發(fā)EventPortAdd事件。

(2)如果沒有設(shè)置self.link_discovery,則返回;否則執(zhí)行下一步。

(3)調(diào)用_get_port函數(shù),該函數(shù)首先根據(jù)傳入的dpid得到Switch實(shí)例,然后遍歷實(shí)例的ports列表,找到并返回傳入的端口號(hào)對(duì)應(yīng)的端口(Port類實(shí)例)。如果找到了端口并且端口不是保留的,則調(diào)用_port_added(),該函數(shù)會(huì)獲得LLDP相關(guān)的數(shù)據(jù)部分(用于構(gòu)造PortData類實(shí)例),然后調(diào)用PortDataState類的add_port(),該函數(shù)會(huì)將Port和對(duì)應(yīng)的PortData映射關(guān)系存儲(chǔ)到self.ports中;調(diào)用self.lldp_event.set()。

如果原因?yàn)?ldquo;刪除”:

(1)在self.port_state里該dpid對(duì)應(yīng)的PortState實(shí)例中刪除該端口,并觸發(fā)EventPortDelete事件。

(2)如果沒有設(shè)置self.link_discovery,則返回;否則執(zhí)行下一步。

(3)調(diào)用_get_port函數(shù),該函數(shù)首先根據(jù)傳入的dpid得到Switch實(shí)例,然后遍歷實(shí)例的ports列表,找到并返回傳入的端口號(hào)對(duì)應(yīng)的端口(Port類實(shí)例)。如果找到了端口并且端口不是保留的,則:

a. 調(diào)用del_port(),將該端口及對(duì)應(yīng)的PortData從self.ports刪除;

b. 調(diào)用_link_down(),該函數(shù)會(huì)調(diào)用LinkState類的port_deleted函數(shù),并返回傳入的port對(duì)應(yīng)的對(duì)端port和傳入的port本身。在port_deleted函數(shù)里,首先調(diào)用get_peer()獲得對(duì)端端口,然后生成兩個(gè)Link對(duì)象(src->dst和dst->src),并將這兩個(gè)對(duì)象從self.links中刪除(反向Link可能不存在);刪除src->dst和dst->src之間的映射(存儲(chǔ)在_map字典中)。根據(jù)返回的“傳入的port對(duì)應(yīng)的對(duì)端port和傳入的port本身”,創(chuàng)建Link對(duì)象,觸發(fā)EventLinkDelete事件(如果反向連接也存在,會(huì)觸發(fā)兩次EventLinkDelete事件)。調(diào)用self.ports.move_front();

c. 調(diào)用self.lldp_event.set()。如果原因?yàn)?ldquo;修改”:

(1)修改self.port_state里該dpid對(duì)應(yīng)的PortState實(shí)例值,并觸發(fā)EventPortModify事件。

(2)如果沒有設(shè)置self.link_discovery,則返回;否則執(zhí)行下一步。

(3)調(diào)用_get_port函數(shù),該函數(shù)首先根據(jù)傳入的dpid得到Switch實(shí)例,然后遍歷實(shí)例的ports列表,找到并返回傳入的端口號(hào)對(duì)應(yīng)的端口(Port類實(shí)例)。如果找到了端口并且端口不是保留的:

a. 調(diào)用PortDataState類的set_down(),該函數(shù)會(huì)調(diào)用Port類的is_down(),檢測(cè)端口是否已關(guān)閉;獲得Port對(duì)應(yīng)的PortData實(shí)例,調(diào)用PortData的set_down函數(shù),將對(duì)應(yīng)的is_down修改為當(dāng)前狀態(tài)(布爾值);調(diào)用PortData的clear_timestamp(),將對(duì)應(yīng)的timestamp修改為None。如果檢測(cè)端口沒有關(guān)閉,調(diào)用_move_front_key()。set_down函數(shù)返回是否已關(guān)閉的檢測(cè)結(jié)果。如果檢測(cè)結(jié)果是已關(guān)閉,則調(diào)用_link_down()。

b. 調(diào)用self.lldp_event.set()。

9.5 packet_in_handler

該函數(shù)用于處理EventOFPPacketIn事件。

(1)如果沒有設(shè)置self.link_discovery,直接返回;否則執(zhí)行下一步。

(2)嘗試調(diào)用LLDPPacket.lldp_parse(msg.data)來(lái)按照LLDP報(bào)文格式解碼收到的報(bào)文,獲得源交換機(jī)dpid和源端口號(hào)(該LLDP報(bào)文從哪臺(tái)交換機(jī)的哪個(gè)端口發(fā)出的)。如果不是LLDP報(bào)文格式,返回;否則執(zhí)行下一步。

(3)獲得目的交換機(jī)的dpid和目的端口(上報(bào)Packet_In消息的交換機(jī)dpid和接收到LLDP報(bào)文的端口號(hào))。

(4)調(diào)用_get_port函數(shù),得到源端口對(duì)應(yīng)的Port類實(shí)例。如果不存在或者該實(shí)例的dpid跟目的dpid相同,則直接返回;否則執(zhí)行下一步。

(5)調(diào)用PortDataState類的lldp_received函數(shù),該函數(shù)會(huì)再調(diào)用PortData類的lldp_received函數(shù),將對(duì)應(yīng)的self.sent值置為0。

(6)調(diào)用_get_port函數(shù),得到目的端口對(duì)應(yīng)的Port類實(shí)例。如果不存在該實(shí)例,則返回;否則執(zhí)行下一步。

(7)調(diào)用LinkState類的get_peer函數(shù),得到源端口原先對(duì)應(yīng)的目的端口。如果該目的端口存在,且與現(xiàn)在解析得到的目的端口不同,則說明原先的鏈路已斷開,觸發(fā)EventLinkDelete事件。

(8)根據(jù)源端口和目的端口構(gòu)造Link類實(shí)例,如果該實(shí)例不存在于self.links,則說明是新鏈路,觸發(fā)EventLinkAdd事件。

(9)調(diào)用LinkState類的update_link函數(shù),該函數(shù)會(huì)將上一步構(gòu)造的Link類實(shí)例加上時(shí)間戳存儲(chǔ)到self.links中,并構(gòu)造逆向鏈路,返回逆向鏈路是否在self.links中的布爾值。如果逆向鏈路還不存在,那很有可能會(huì)馬上存在,因此調(diào)用PortDataState類的move_front函數(shù),將目的端口移動(dòng)到雙向循環(huán)鏈表中哨兵節(jié)點(diǎn)的后面(下次檢查的頭部),盡早檢查;調(diào)用self.lldp_event.set()。

(10)如果設(shè)置了self.explicit_drop,則調(diào)用_drop_packet函數(shù)。

10. 拓?fù)浒l(fā)現(xiàn)概述

Switches類的初始化函數(shù)__init__()創(chuàng)建用于存儲(chǔ)相關(guān)信息的數(shù)據(jù)結(jié)構(gòu)(self.dps、self.port_state、self.ports和self.links),創(chuàng)建兩個(gè)事件(self.lldp_event 和self.link_event),然后調(diào)用hub.spawn創(chuàng)建兩個(gè)新線程執(zhí)行self.lldp_loop和self.link_loop兩個(gè)函數(shù)。其他工作就交給事件觸發(fā)和事件處理函數(shù)了。

交換機(jī)連接時(shí)觸發(fā)EventOFPStateChange事件,在對(duì)應(yīng)的處理函數(shù)state_change_handler中會(huì)把連接上的交換機(jī)存儲(chǔ)到self.dps中,并把交換機(jī)的端口情況存儲(chǔ)到self.port_state中,并生成相應(yīng)的LLDP報(bào)文數(shù)據(jù),存儲(chǔ)在self.ports中(鍵為Port類型,值為PortData類型,PortData類的數(shù)據(jù)成員lldp_data存儲(chǔ)LLDP報(bào)文數(shù)據(jù))。

lldp_loop函數(shù)會(huì)不停遍歷self.ports,并在需要的時(shí)候由send_lldp_packet函數(shù)執(zhí)行發(fā)送LLDP報(bào)文的操作。

當(dāng)LLDP報(bào)文被送回到控制器時(shí),觸發(fā)EventOFPPacketIn事件,對(duì)應(yīng)的處理函數(shù)packet_in_handler會(huì)解析LLDP報(bào)文,得到交換機(jī)之間的連接信息(Link類),存儲(chǔ)到self.links中。

link_loop函數(shù)會(huì)遍歷self.links,及時(shí)檢查鏈路是否還是活的。

后記:

實(shí)際使用Ryu獲取拓?fù)湫畔r(shí),更好的方式是使用Ryu提供的REST API,具體方法將在下文中介紹。但分析switches.py的過程對(duì)了解Ryu的工作機(jī)制和應(yīng)用編寫方法還是蠻有用的。

責(zé)任編輯:何妍 來(lái)源: 劍客
相關(guān)推薦

2015-07-27 14:57:32

OpenFlow協(xié)議Ryu

2015-12-30 13:21:33

SDN控制器拓?fù)?/a>

2015-09-11 09:15:32

RyuSDN

2023-11-29 16:21:30

Kubernetes服務(wù)注冊(cè)

2009-07-27 11:37:04

網(wǎng)絡(luò)拓?fù)?/a>摩卡

2017-07-07 14:30:27

Flink架構(gòu)拓?fù)?/a>

2021-08-02 07:57:03

注冊(cè)Nacos源碼

2018-12-19 14:00:07

MySQL主從復(fù)制數(shù)據(jù)庫(kù)

2014-12-08 11:17:51

SDNDocker部署Docker

2010-08-12 16:18:17

網(wǎng)絡(luò)拓?fù)?/a>運(yùn)維管理摩卡軟件

2017-01-23 13:34:44

2009-01-11 22:32:53

電子發(fā)現(xiàn)法規(guī)遵從數(shù)據(jù)管理

2022-04-13 08:23:31

Golang并發(fā)

2021-10-12 17:19:17

Random局限性變量

2020-10-13 07:35:22

JUC - Count

2023-04-26 08:39:41

Bitmap元素存儲(chǔ)

2013-01-21 10:55:52

大數(shù)據(jù)Ayasdi拓?fù)鋽?shù)據(jù)

2021-08-10 07:00:00

Nacos Clien服務(wù)分析

2009-06-29 14:30:42

網(wǎng)絡(luò)拓?fù)?/a>KoolPoint摩卡

2012-12-03 16:57:37

HDFS
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)