這里,所謂OpenFlow網(wǎng)絡(luò)指的是相互連接的一組OpenFlow交換機(jī)的集合,并且這些交換機(jī)全部置于一個(gè)OpenFlow Controller或一個(gè)OpenFlow Controller的集群的管理之下。OpenFlow網(wǎng)絡(luò)的路由服務(wù)指的是單純地將一個(gè)數(shù)據(jù)包(Packet)從一個(gè)主機(jī)(Host)送到另一個(gè)主機(jī),而不是三層IP路由協(xié)議1:1的實(shí)現(xiàn)。而主機(jī)也即是路由的目的地,可以是物理服務(wù)器或虛擬機(jī)(VM, Virtual Machine)。按照SDN的數(shù)據(jù)平面和控制平面相分離的模式和集中式管理的系統(tǒng)結(jié)構(gòu),OpenFlow網(wǎng)絡(luò)的路由完全是由OpenFlow Controller根據(jù)用戶的路由策略(Policy)生成并安裝到每個(gè)OpenFlow交換機(jī)的Flow Table和Group Table的Flow Entry和Group Entry的集合來(lái)定義的。因此,本文假設(shè)讀者朋友對(duì)OpenFlow交換機(jī)和OpenFlow Controller的基本概念有所了解,可參考ONF(Open Network Foundation)給出的“OpenFlow Switch Specification”相關(guān)章節(jié)。本文的討論也以此文獻(xiàn)給出的定義作為基礎(chǔ)。
總體思路
主機(jī)和OpenFlow網(wǎng)絡(luò)的連接方式直接影響OpenFlow網(wǎng)絡(luò)的路由設(shè)置,本文的討論包括三種最一般的情況:第一,主機(jī)和OpenFlow網(wǎng)絡(luò)的交換機(jī)的端口直接相連,這是最簡(jiǎn)單的情況;第二,主機(jī)通過(guò)二層網(wǎng)絡(luò)接入OpenFlow網(wǎng)絡(luò);第三,主機(jī)途徑多個(gè)IP子網(wǎng)最終通過(guò)路由器和OpenFlow網(wǎng)絡(luò)相連,主機(jī)接入的網(wǎng)絡(luò)以及中間經(jīng)過(guò)的網(wǎng)絡(luò)都是傳統(tǒng)的IP網(wǎng)絡(luò),使用傳統(tǒng)的路由協(xié)議,如OSPF或BGP。為了敘述的方便,第一種連接方式和第二種連接方式下的主機(jī)看做OpenFlow網(wǎng)絡(luò)的內(nèi)部主機(jī),而第三種連接方式下的主機(jī)看做OpenFlow網(wǎng)絡(luò)的外部主機(jī)。所謂“外部”,這是因?yàn)镺penFlow網(wǎng)絡(luò)無(wú)法直接“感知”到主機(jī)的存在。如圖1所示。主機(jī)A與邊緣交換機(jī)(Edge Switch)ES1的端口3連接(第一種方式),主機(jī)B通過(guò)二層鏈路網(wǎng)絡(luò)(1.1.1.0/24)和邊緣交換機(jī)ES2的端口2連接(第二種方式),主機(jī) C連入外部的IP網(wǎng)絡(luò)(3.3.3.0/24),路由器R是OpenFlow內(nèi)部主機(jī)和外部主機(jī)通信的中介(第三種方式),和邊緣交換機(jī)ES3的端口2連接。
實(shí)現(xiàn)OpenFlow路由服務(wù)總的思路是:獲取主機(jī)的信息及其接入OpenFlow網(wǎng)絡(luò)的信息,計(jì)算主機(jī)之間的路徑,對(duì)于路徑上的每個(gè)交換機(jī),通過(guò)下發(fā)的OpenFlow消息,改變它的Flow Table和Group Table來(lái)定義其轉(zhuǎn)發(fā)行為,最終實(shí)現(xiàn)主機(jī)到主機(jī)的路由和通信。這些基本上都是OpenFlow Controller或在它之上的網(wǎng)絡(luò)應(yīng)用的功能。下文的討論將不加區(qū)分的統(tǒng)統(tǒng)視為OpenFlow Controller的功能。
主機(jī)和接入
為了實(shí)現(xiàn)主機(jī)之間的路由與通信,OpenFlow Controller必須首先獲取主機(jī)的相關(guān)信息。對(duì)于OpenFlow網(wǎng)絡(luò)的內(nèi)部主機(jī),需要獲取的信息包括:主機(jī)的IP地址,接入OpenFlow網(wǎng)絡(luò)的邊緣交換機(jī)及端口,以及主機(jī)的MAC地址。除了人工靜態(tài)配置之外,網(wǎng)絡(luò)的Orchestration系統(tǒng)可提供主機(jī)的IP地址和接入到OpenFlow 網(wǎng)絡(luò)的交換機(jī)及其端口,網(wǎng)絡(luò)的Orchestration系統(tǒng)管理服務(wù)器和虛擬機(jī)在網(wǎng)絡(luò)上的部署。比如,在云計(jì)算的數(shù)據(jù)中心,網(wǎng)絡(luò)管理員可以通過(guò) OpenStack這樣的Orchestration系統(tǒng)為客戶定制IP子網(wǎng)。這樣,IP子網(wǎng)中每個(gè)主機(jī)的IP地址和相連接的交換機(jī)及其端口的數(shù)據(jù)通過(guò) OpenStack的插件傳遞給Controller。而主機(jī)的MAC地址就需借助于ARP來(lái)動(dòng)態(tài)獲取。例如,在圖1中,假設(shè)有一個(gè)發(fā)往主機(jī)A的數(shù)據(jù)包,但不知道主機(jī)A的MAC地址。此時(shí),Controller可通過(guò)packet_out消息令邊緣交換機(jī)ES1向端口3發(fā)送一個(gè)ARP請(qǐng)求,交換機(jī)ES1接收到主機(jī)A的回復(fù)報(bào)文后,因?yàn)樗腇low Table中沒(méi)有和ARP報(bào)文匹配的Flow Entry,所以,缺省地,ES1將這個(gè)ARP回復(fù)報(bào)文打包成packet_in消息,發(fā)送給OpenFlow Controller。OpenFlow Controller解析這個(gè)報(bào)文,即可得到主機(jī)A的MAC地址。
對(duì)于OpenFlow網(wǎng)絡(luò)的外部主機(jī),OpenFlow Controller必須知道:和OpenFlow網(wǎng)絡(luò)直接相連的路由器的IP地址和MAC地址,連接路由器的OpenFlow網(wǎng)絡(luò)的邊緣交換機(jī)和端口,外部主機(jī)所在子網(wǎng)的IP地址(Prefix)和掩碼。路由器的IP地址和MAC地址,以及接入OpenFlow網(wǎng)絡(luò)的邊緣交換機(jī)和端口可按照上文描述的方式得到。而獲取外部主機(jī)的IP子網(wǎng)的地址和掩碼的功能則是由虛擬路由器(Virtual Router)來(lái)完成的。如圖1所示,主機(jī)C所在的子網(wǎng)的IP地址和掩碼(3.3.3.0/24)經(jīng)過(guò)傳統(tǒng)的分布式IP路由系統(tǒng)最終傳遞給路由器R。通過(guò) In Band或Out Of Band的方式,R和虛擬路由器事先建立了會(huì)話,如BGP會(huì)話,并交換路由可達(dá)信息。于是,虛擬路由器得到3.3.3.0/24的可達(dá)信息后,最終遞交給 OpenFlow Controller。有一些開源的程序可用來(lái)實(shí)現(xiàn)虛擬路由器,如Xorp、Quagga、ExaBGP等。一般地,虛擬路由器和外部的路由器的會(huì)話使用 BGP協(xié)議。關(guān)于虛擬路由器的細(xì)節(jié)不是本文討論的重點(diǎn)。
拓?fù)浜吐窂?/strong>
控制平面和數(shù)據(jù)平面的分離,形成以O(shè)penFlow Controller為中心的集中的控制平臺(tái)。OpenFlow網(wǎng)絡(luò)中所有的交換機(jī)都在OpenFlow Controller的監(jiān)管之下,于是,OpenFlow Controller就有機(jī)會(huì)掌握全局的網(wǎng)絡(luò)拓?fù)湟晥D以及每個(gè)交換機(jī)的狀態(tài)。這樣,OpenFlow Controller就能夠更聰明地按照用戶的路由策略來(lái)及時(shí)調(diào)整每個(gè)交換機(jī)的轉(zhuǎn)發(fā)行為,從而更容易的實(shí)現(xiàn)如流量工程(Traffic Engineering)和快速故障恢復(fù)(Fail Over)這樣的高級(jí)功能。這也是SDN的優(yōu)勢(shì)之所在。
一般地,OpenFlow Controller借助LLDP(Link Layer Discovery Protocol)協(xié)議發(fā)現(xiàn)OpenFlow交換機(jī)之間的連接狀態(tài)。LLDP協(xié)議廣泛地用于網(wǎng)絡(luò)設(shè)備廣播自己的ID,能力(Capabilities)和鄰居。LLDP具有專用的MAC廣播地址和EtherType,這樣,OpenFlow Controller可以輕而易舉的識(shí)別LLDP報(bào)文。網(wǎng)絡(luò)拓?fù)涞陌l(fā)現(xiàn)由OpenFlow Controller發(fā)起,OpenFlow Controller推送給每個(gè)OpenFlow交換機(jī)一個(gè)packet_out消息,指示交換機(jī)向所有的端口發(fā)出LLDP報(bào)文。與此同時(shí),收到LLDP 報(bào)文的交換機(jī)也會(huì)向它的所有的端口發(fā)送LLDP報(bào)文。然而,收到LLDP報(bào)文的交換機(jī)的Flow Table中沒(méi)有和LLDP報(bào)文匹配的Flow Entry。因此,它就把收到的LLDP報(bào)文封裝為packet_in消息發(fā)送給OpenFlow Controller。OpenFow Controller分析這些LLDP的報(bào)文,就能夠知道交換機(jī)之間誰(shuí)和誰(shuí)通過(guò)哪個(gè)端口連接在一起。最終,OpenFlow Controller得到網(wǎng)絡(luò)的完整的拓?fù)浣Y(jié)構(gòu)。
在OpenFlow網(wǎng)絡(luò)的路由服務(wù)中,發(fā)現(xiàn)拓?fù)涞哪康氖菫榱擞?jì)算從一個(gè)邊緣交換機(jī)到另一個(gè)邊緣交換機(jī)之間的路徑。為了討論的方便,我們假設(shè)路由服務(wù)僅使用最短路徑(Shortest Path)的策略。盡管這是最簡(jiǎn)單的情況,但可以舉一反三地靈活運(yùn)用這里給出的基本的原理和方法,實(shí)現(xiàn)更高級(jí)的更有價(jià)值的網(wǎng)絡(luò)路由策略。網(wǎng)絡(luò)的拓?fù)浔憩F(xiàn)在數(shù)據(jù)結(jié)構(gòu)上,就是一個(gè)圖(Graph)。眾所周知,給定一個(gè)像網(wǎng)絡(luò)拓?fù)涞哪菢拥膱D,計(jì)算兩點(diǎn)之間的最短路徑的算法就是大名鼎鼎的Dijkstra’s Algorithm。對(duì)于圖中一個(gè)源節(jié)點(diǎn),該算法可一次計(jì)算出到達(dá)所有其他節(jié)點(diǎn)的最短路徑。算法的細(xì)節(jié)請(qǐng)參考Wikipedia的文檔:http://en.wikipedia.org/wiki/Dijkstra’s_algorithm。兩點(diǎn)之間的最短路徑也許并非只有一條,可能存在多條,我對(duì)此算法稍作擴(kuò)展,能夠計(jì)算出兩點(diǎn)之間的所有最短路徑。我的另一篇博客給出了這一擴(kuò)展算法的C++實(shí)現(xiàn),可直接編譯運(yùn)行。得到多條最短路徑,就可以實(shí)現(xiàn)類似于ECMP的流量均衡(Traffic Ba lance)的路由策略。
對(duì)應(yīng)于圖1的情況,OpenFlow Controller使用Dijkstra’s Algorithm得到主機(jī)A到主機(jī)B經(jīng)過(guò)OpenFlow網(wǎng)絡(luò)中的路徑如下,其中的數(shù)字代表入端口或出端口。
Path(A, B): (3, ES1, 1) -> (1, ES2, 2)
同樣地,主機(jī)A到主機(jī)C和主機(jī)C到主機(jī)B的路徑如下:
Path(A, C): (3, ES1, 2) -> (2, SW0, 1) -> (1, ES3, 2)
Path(C, B):(2, ES3, 1) -> (1, SW0, 3) -> (3, ES2, 2)
當(dāng)然,相反方向路徑如Path(B, C)、Path(C, A)和Path(B, A)的計(jì)算自然也不在話下。
[page]轉(zhuǎn)發(fā)和路由
有了主機(jī)和接入到邊緣交換機(jī)的信息,也能夠算出邊緣交換機(jī)到邊緣交換機(jī)的路徑。實(shí)現(xiàn)路由服務(wù)的最后一步是OpenFlow Controller向連接主機(jī)或子網(wǎng)的路徑上的每個(gè)OpenFlow交換機(jī)下發(fā)Flow Entries,改變交換機(jī)的轉(zhuǎn)發(fā)行為,以達(dá)到主機(jī)間通信的目的。如對(duì)于連接從主機(jī)A到主機(jī)B的路徑Path(A, B),下發(fā)到ES1和ES2的Flow Entry分別是:
Switch ES1:
match: src_ip = 2.2.2.2/32, dst_ip = 1.1.1.0/24, in_port = 3
action: out_port = 1
Switch ES2:
match: src_ip = 2.2.2.2/32, dst_ip = 1.1.1.0/24, in_port = 1
action: out_port = 2; eth_dst = 00:00:00:00:00:01
這樣,從主機(jī)A發(fā)往主機(jī)B的一個(gè)IP數(shù)據(jù)包就可以依次經(jīng)過(guò)交換機(jī)ES1和ES2到達(dá)網(wǎng)絡(luò)1.1.1.0/24。請(qǐng)注意,下發(fā)給交換機(jī)ES2的Flow Entry的action中,將把匹配到的數(shù)據(jù)包的目的MAC地址eth_dst更新為主機(jī)B的MAC地址。這樣,數(shù)據(jù)包才會(huì)被二層(Ethernet) 網(wǎng)絡(luò)正確地轉(zhuǎn)發(fā)到主機(jī)B。否則,數(shù)據(jù)包將被丟棄。
同樣地,內(nèi)部主機(jī)A到外部主機(jī)C的路由可由下面的Flow Entry來(lái)定義:
Switch ES1:
match: src_ip = 2.2.2.2/32, dst_ip = 3.3.3.0/24, in_port = 3
action: out_port = 2
Switch SW0:
match: src_ip = 2.2.2.2/32, dst_ip = 3.3.3.0/24, in_port = 2
action: out_port = 1
Switch ES3:
match: src_ip = 2.2.2.2/32, dst_ip = 3.3.3.0/24, in_port = 1
action: out_port = 2; eth_dst = 00:00:00:00:00:03
不難發(fā)現(xiàn),OpenFlow網(wǎng)絡(luò)把發(fā)往外部主機(jī)的數(shù)據(jù)包只送到相關(guān)的路由器,如上面例子中的路由器R。剩下的路由就交給外部的網(wǎng)絡(luò)了,因?yàn)橥獠烤W(wǎng)絡(luò)超出了OpenFlow Controller的控制范圍。
最好,再看一個(gè)相反方向的從外部主機(jī)C到內(nèi)部主機(jī)B的路由的實(shí)現(xiàn):
Switch ES3:
match: src_ip = 3.3.3.0/24, dst_ip = 1.1.1.0/24, in_port = 2
action: out_port = 1
Switch SW0:
match: src_ip = 3.3.3.0/24, dst_ip = 1.1.1.0/24, in_port = 1
action: out_port = 3
Switch ES2:
match: src_ip = 3.3.3.0/24, dst_ip = 1.1.1.0/24, in_port = 3
action: out_port = 2; eth_dst = 00:00:00:00:00:01
需要指出的是,上文給出的下發(fā)到OpenFlow交換機(jī)的Flow Entries只是OpenFlow Controller實(shí)現(xiàn)路由服務(wù)的一種可能的方案,這里只是用來(lái)示例。而不同的OpenFlow Controller下發(fā)的Flow Entries會(huì)有所不同,但基本的原理應(yīng)是大同小異。
我想,OpenFlow網(wǎng)絡(luò)的路由服務(wù)的主要優(yōu)點(diǎn)在于實(shí)現(xiàn)的靈活性,可根據(jù)實(shí)際的需求做具體的定制,而不受限于已有的路由協(xié)議標(biāo)準(zhǔn)和硬件基礎(chǔ)設(shè)施的制約。正是有了SDN數(shù)據(jù)平面和管理平面的分隔,這種網(wǎng)絡(luò)可編程的(Programable)靈活性才可能成為現(xiàn)實(shí)。