作者簡介:Ray(任老板),某知名廠商“傳統(tǒng)網(wǎng)工”,有三年多的ISP網(wǎng)絡(luò)建設(shè)維護(hù)經(jīng)驗,對IPRAN、PTN有一定的了解,目前正在做一個資源池(OpenStack)的項目
本文主要描述了一種將三層路由變成二層交換轉(zhuǎn)發(fā)(以及二層轉(zhuǎn)發(fā)變成三層路由)的實現(xiàn)方式,以應(yīng)對OVS(OpenFlow)跨網(wǎng)段路由復(fù)雜的問題;當(dāng)然技術(shù)本身是客觀的,具體應(yīng)用還要看場景。
隨著SDN技術(shù)不斷“發(fā)展”,玩路由器交換機(jī)的變成了“傳統(tǒng)網(wǎng)工”,搞控制器、轉(zhuǎn)發(fā)器的才算是正常工作,當(dāng)然任何新技術(shù)的掌握都離開對“歷史”了解或者反芻;也許幾年以后當(dāng)有人聽到一條一條的配置ACL、配置路由表是一件很不可思議的事情,因為那時所有的配置都是控制器做好模型生成配置自動下發(fā)的,點點鼠標(biāo)或者寫個py腳本就可以了。
OK,言歸正傳,我們先來了解一下傳統(tǒng)路由、交換的區(qū)別:
交換機(jī)視角:交換機(jī)會接收網(wǎng)段上的所有數(shù)據(jù)幀;利用接收數(shù)據(jù)幀中的源MAC地址來建立MAC地址表(源地址自學(xué)習(xí)),使用地址老化機(jī)制進(jìn)行地址表維護(hù)。MAC地址表中查找數(shù)據(jù)幀中的目的MAC地址,如果找到就將該數(shù)據(jù)幀發(fā)送到相應(yīng)的端口,如果找不到,就向除入端口以外的所有的端口發(fā)送;向所有端口轉(zhuǎn)發(fā)廣播幀和多播幀。
路由:一般指不同網(wǎng)段的數(shù)據(jù)包的轉(zhuǎn)發(fā),轉(zhuǎn)發(fā)依據(jù):IP路由
PC視角:當(dāng)兩臺主機(jī)在不同的網(wǎng)段,PC1需要訪問PC2時,PC1首先會在自己的路由表內(nèi)查詢PC2的IP地址對應(yīng)的下一跳(一般默認(rèn)是網(wǎng)關(guān))地址,然后再去發(fā)送ARP報文,請求該下一跳對應(yīng)的MAC地址;收到響應(yīng)后,PC1會把該MAC地址封裝在數(shù)據(jù)包的目的MAC的位置(注意此時的目的IP仍是PC2的IP地址,而不是下一跳IP),然后將數(shù)據(jù)報文扔給路由器;PC2也會做類似的動作。
路由器視角:當(dāng)路由器收到一個IP數(shù)據(jù)包,路由器就會找出數(shù)據(jù)包的三層包頭中的目的IP地址,然后拿著目的IP地址到自己的路由表中進(jìn)行查詢,找到“最匹配”的路由條目后,將數(shù)據(jù)包根據(jù)路由條目所指示的出接口或者下一跳IP轉(zhuǎn)發(fā)出去,這就是IP路由(當(dāng)然路由器還會做一些額外的工作:將數(shù)據(jù)包的三層包頭的TTL減一,修改數(shù)據(jù)包的二層源MAC地址為自己出接口的MAC,修改數(shù)據(jù)包的二層目的MAC地址為下一跳的MAC);而每一臺路由器都會在本地維護(hù)一個路由表(Routing Table),路由表中裝在著路由器獲知的路由條目,路由條目由路由前綴(路由所關(guān)聯(lián)的目的地址)、路由信息的來源、出接口或者下一跳IP等元素構(gòu)成;路由器通過靜態(tài)配置或者動態(tài)的方式獲取路由條目并維護(hù)自己的路由表。
當(dāng)OpenFlow出現(xiàn)以后,路由器、交換機(jī)統(tǒng)一變成了轉(zhuǎn)發(fā)器,轉(zhuǎn)發(fā)依據(jù):流表
OK,我們先看一下流表長啥樣:
1 2 3 4 5 6 | root@ubuntu:~# ovs-ofctl dump-flows br2 NXST_FLOW reply (xid=0x4): cookie=0x0, duration=16080.313s, table=0, n_packets=1, n_bytes=42, idle_age=15691, priority=200,arp,arp_tpa=2.2.2.0/24 actions=output:100 cookie=0x0, duration=15964.186s, table=0, n_packets=1, n_bytes=42, idle_age=15691, priority=100,arp,arp_tpa=1.1.1.0/24 actions=output:1 cookie=0x0, duration=15985.113s, table=0, n_packets=5, n_bytes=490, idle_age=15692, priority=200,icmp,nw_dst=2.2.2.0/24 actions=output:100 cookie=0x0, duration=15802.910s, table=0, n_packets=5, n_bytes=490, idle_age=15692, priority=100,icmp,nw_dst=1.1.1.0/24 actions=output:1 |
當(dāng)然有人稱流表為ACL,這也可以理解,都有著強(qiáng)大的匹配域以及Action,流表的Pipeline可以算是其特色(性能暫時先不care);到此為止,什么MAC表、路由表在轉(zhuǎn)發(fā)器上面已經(jīng)統(tǒng)統(tǒng)看不到了,你能看到只有上面的流表。
就OVS來說,如果把Bridge配置成Secure模式,默認(rèn)是沒有什么流表的;如果現(xiàn)在我們把OVS配置成一臺普通的傳統(tǒng)二層交換機(jī),只需要增加幾條關(guān)于ARP、ICMP的流表,就可以Ping通了(可以參考以上示例),這還是比較簡單的。當(dāng)然可能有些人說還有更簡單的:只需把Bridge配置Standalone模式或者增加一條默認(rèn)action=NORMAL的流表就可以了。但是如果這樣的話,所有的流量又回到傳統(tǒng)的二層三層轉(zhuǎn)發(fā)去了,作為新時代的OVS,這符合我的個性啊,如果這樣的話,這活還是交給Linux Bridge來干吧。
但是問題來了,如果把OVS配置成一臺有路由器功能的轉(zhuǎn)發(fā)器,這就比較困難了;因為通過上文分析路由轉(zhuǎn)發(fā)過程相對來說還是比較復(fù)雜的,需要做的工作如下:
在OpenFlow的世界所有的網(wǎng)絡(luò)設(shè)備都是轉(zhuǎn)發(fā)器或者稱為交換機(jī),執(zhí)行簡單的轉(zhuǎn)發(fā)轉(zhuǎn)發(fā)動作; OK,那我們能不能將跨網(wǎng)段訪問的路由轉(zhuǎn)發(fā)變換成普通的二層轉(zhuǎn)發(fā)呢?答案是YES!
下面我們通過一個示例來實現(xiàn)這個想法。
首先我們要解決的第一個問題就是網(wǎng)關(guān)的問題:如何取消對網(wǎng)關(guān)的ARP請求?這個在Linux平臺下并不是一件難事,只需一條命令:
1 | ip route add 0.0.0.0/0 dev eth0 scope link |
(同時注意arp_ignore需要是0或1)
Link路由是可以直接arp目標(biāo)地址的,而不是arp下一跳地址。意思就是說,目標(biāo)地址是屬于跟本地直連的二層鏈路上,不跨三層。既然是不跨三層的鏈路,arp就可以暢行無阻,而標(biāo)準(zhǔn)中又沒有規(guī)定arp協(xié)議包的請求源和請求目標(biāo)必須是同一個網(wǎng)段的地址(甚至都沒有掩碼約束),所以說,一個以下的arp請求是有效的:
最后剩下一個問題就是防環(huán)的TTL的問題,這個處理起來也比較簡單一些,我們可以在流表中加入actions=dec_ttl(1), output:100,在每一跳中自動減小TTL。
然后在接收端的PC上面做類似的操作,中間的OVS添加相關(guān)ARP以及業(yè)務(wù)流的流表,就實現(xiàn)了跨網(wǎng)段的“交換”。
通過以上描述,已經(jīng)實現(xiàn)了跨網(wǎng)段的路由向交換的轉(zhuǎn)換,另外也可以實現(xiàn)所謂二層交換向路由的轉(zhuǎn)換,比如10.0.0.100/24 訪問10.0.0.200/24,按照我們的想當(dāng)然是應(yīng)該走二層轉(zhuǎn)發(fā)的,也就是直接請求目的主機(jī)的MAC地址,然后封裝、發(fā)送;
但是由于種種原因,目的主機(jī)10.0.0.200/24可能跟源主機(jī)是跨三層網(wǎng)絡(luò)的,那現(xiàn)在怎么辦呢?OK,可以在源主機(jī)上面增加一條明細(xì)路由把10.0.0.200/24指向默認(rèn)網(wǎng)關(guān),在目的主機(jī)上面增加一條明細(xì)路由把10.0.0.100/24指向默認(rèn)網(wǎng)關(guān),然后再ping一下,有木有看到自己的嘴角上揚(yáng)呢!
本質(zhì)都是一樣的,改變ARP的請求方式!
聯(lián)系客服