Linux實(shí)現(xiàn)的IEEE 802.1Q VLAN
VLAN是一種將局域網(wǎng)設(shè)備從邏輯上劃分成一個(gè)個(gè)網(wǎng)段,從而實(shí)現(xiàn)虛擬工作組的新興數(shù)據(jù)交換技術(shù)。IEEE802.1q協(xié)議也就是“VirtualBridgedLocalAreaNetworks”(虛擬橋接局域網(wǎng),簡稱“虛擬局域網(wǎng)”)協(xié)議,主要規(guī)定了VLAN的實(shí)現(xiàn)方法。本博文將重新解讀該協(xié)議,并演示Vlan間通信的原理及配置。
VLAN的核心概念
說起IEEE 802.1q,都知道是VLAN,說起VLAN,基本上也沒有盲區(qū),網(wǎng)絡(luò)基礎(chǔ)。然而說到配置,基本所有人都能順口溜一樣說出Cisco或者H3C設(shè)備的配置命令,對(duì)于Linux的VLAN配置卻存在大量的疑問。這些疑問之所以存在我覺得有兩點(diǎn)原因:
1.對(duì)VLAN的本質(zhì)還是沒有理解。
不管你的Cisco/H3C命令敲得再熟練,如果看不懂Linux的vconfig,那么也將無法掩飾你對(duì)概念理解的淺顯;
2.對(duì)Linux實(shí)現(xiàn)虛擬網(wǎng)絡(luò)設(shè)備風(fēng)格不熟悉
可能你已經(jīng)十分理解802.1q了,也許還看過了IEEE的文檔,然而卻對(duì)Linux的Bridge,tap,bond等虛擬設(shè)備不是很理解,那么也將無法順利配置VLAN。
對(duì)于VLAN概念的理解,有幾點(diǎn)要強(qiáng)調(diào):
1.VLAN分離了廣播域;
2.單獨(dú)的一個(gè)VLAN模擬了一個(gè)常規(guī)的交換以太網(wǎng),因此VLAN將一個(gè)物理交換機(jī)分割成了一個(gè)或多個(gè)邏輯交換機(jī);
3.不同VLAN之間通信需要三層參與;
4.當(dāng)多臺(tái)交換機(jī)級(jí)聯(lián)時(shí),VLAN通過VID來識(shí)別,該ID插入到標(biāo)準(zhǔn)的以太幀中,被稱作tag;
5.大多數(shù)的tag都不是端到端的,一般在上行路上***個(gè)VLAN交換機(jī)打tag,下行鏈路的***一個(gè)VLAN交換機(jī)去除tag;
6.只有在一個(gè)數(shù)據(jù)幀不打tag就不能區(qū)分屬于哪個(gè)VLAN時(shí)才會(huì)打上tag,能去掉時(shí)盡早要去掉tag;
7.最終,IEEE 802.1q解決了VLAN的tag問題。除了IEEE 802.1q,其余的都是和實(shí)現(xiàn)相關(guān)的,雖然Cisco和H3C的實(shí)現(xiàn)很類似,Linux可以和它們有大不同。
關(guān)鍵看***3點(diǎn),也就是3,4,5。這是VLAN最難理解的部分,不過一旦理解了,VLAN也就不剩下什么了。為了使得敘述上以及配置上更加的方便,Cisco以及其他的廠商定義了很多的細(xì)節(jié),而這些細(xì)節(jié)在IEEE 802.1q標(biāo)準(zhǔn)中并沒有被定義,這些細(xì)節(jié)包括但不局限于以下幾點(diǎn):
1.每一個(gè)VLAN交換機(jī)端口需要綁定一個(gè)VLAN id;
2.每一個(gè)VLAN交換機(jī)端口處于下面三類中的一類:access,trunk,hybrid。
2.1.access端口:從此類端口收到的數(shù)據(jù)幀是不打tag的,從此類端口發(fā)出的數(shù)據(jù)幀是不打tag的;
2.2.trunck端口:從此類端口收到的數(shù)據(jù)幀打著tag,從此類端口發(fā)出的數(shù)據(jù)幀需要打tag(不考慮缺省VLAN的情況);
2.3.hybrid端口:略
我們實(shí)則沒有必要去深究Cisco/H3C的命令以及到底那三類端口類型有何區(qū)別,之所以有三類端口類型完全是為了將VLAN的概念(最終的IEEE 802.1q標(biāo)準(zhǔn))很方便的用起來。說白了,trunk端口的存在是因?yàn)椴坏靡?,因?yàn)橛袑儆诙鄠€(gè)VLAN的數(shù)據(jù)幀要通過單一的物理鏈路,不打tag是無法區(qū)分各自屬于哪個(gè)VLAN的,于是就有了IEEE 802.1q這個(gè)標(biāo)準(zhǔn),定義了一個(gè)tag插入到以太幀中,為了使這個(gè)理論性的東西被使用起來,廠商便定義了一系列的概念性的東西,比如和tag相關(guān)的鏈路就是trunk鏈路之類。
于是乎,我們可以完全拋開任何的配置命令,拋開任何廠商定義的東西,完全按照IEEE 802.1q標(biāo)準(zhǔn)以及我們的需求來理解VLAN,這樣下來之后,你絕對(duì)可以在Linux上***實(shí)現(xiàn)任何VLAN配置了。首先我們定義一下我們的需求以及滿足該需求的網(wǎng)絡(luò)拓?fù)?,關(guān)鍵看如何接線。
1.情況一.同一VLAN內(nèi)部通信
1.1.同一交換機(jī)同一VLAN的不同端口進(jìn)行通信
1.2.不同交換機(jī)的不同端口進(jìn)行通信
2.情況二.不同VLAN之間通信
2.1.同一交換機(jī)不同VLAN之間進(jìn)行通信
2.2.不同交換機(jī)的不同VLAN進(jìn)行通信
從上述1.2可以看出,為了節(jié)省線纜和避免環(huán)路,兩個(gè)VLAN交換機(jī)的兩個(gè)端口之間的同一條鏈路需要承載不同的VLAN數(shù)據(jù)幀,為了使彼此能夠識(shí)別每個(gè)數(shù)據(jù)幀到底屬于哪個(gè)VLAN,十分顯然的辦法就是為數(shù)據(jù)幀打上tag,因此上述1.2中的端口J和端口K之間的鏈路上的數(shù)據(jù)幀需要打tag,端口J和端口K都同屬于兩個(gè)VLAN,分別為VLAN m和VLAN n。換句話說,只要一個(gè)端口需要傳輸和接收屬于多個(gè)VLAN的數(shù)據(jù)幀,那么從該端口發(fā)出的數(shù)據(jù)幀就要打上tag,從該端口接收的數(shù)據(jù)幀可以通過tag來識(shí)別它屬于哪個(gè)VLAN,用Cisco/H3C等廠商的術(shù)語來講,它就是trunk端口,兩個(gè)trunck端口之間的鏈路屬于trunk鏈路。
我們知道,一般而言,我們的PC機(jī)直接連接在常規(guī)二層交換機(jī)或者支持VLAN的交換機(jī)端口上,而我們的PC機(jī)發(fā)出的一般都是常規(guī)的以太網(wǎng)數(shù)據(jù)幀,這些數(shù)據(jù)幀是沒有tag的,它們可能根本不知道802.1q為何物,然而VLAN存在的目的就是把一些PC機(jī)劃在一個(gè)VLAN中,而把另一些PC機(jī)劃在另一個(gè)VLAN中從而實(shí)現(xiàn)隔離,那么很顯然的一種辦法就是將支持VLAN的交換機(jī)的某些端口劃在一個(gè)VLAN,而另一些端口劃在另一個(gè)VLAN中,一個(gè)VLAN的所有端口其實(shí)就形成了一個(gè)邏輯上的二層常規(guī)交換機(jī),同屬于一個(gè)VLAN的PC機(jī)連接在劃在同一個(gè)VLAN的端口上,為了擴(kuò)展VLAN,鑒于單臺(tái)交換機(jī)端口數(shù)量的限制,需要級(jí)聯(lián)交換機(jī),那么級(jí)聯(lián)鏈路上則同時(shí)承載著不同VLAN流量,因此級(jí)聯(lián)鏈路則成為trunk鏈路,所有不是級(jí)聯(lián)鏈路的鏈路都是直接鏈路,用廠商術(shù)語來講就是access鏈路(注意,這里暫且不談hybrid),自然而然的,access鏈路兩端的端口都是和tag無關(guān)的,只需要做到“沒有tag直通,有tag去掉即可”,因此它可以連接PC機(jī)或者常規(guī)交換機(jī)以及VLAN交換機(jī)的非trunk端口。
VLAN的內(nèi)容基本也就是以上那些了,分為三部分:
1.設(shè)計(jì)目的
隔離廣播域,節(jié)省物理設(shè)備,隔離安全策略域
2.IEEE 802.1q
為擴(kuò)展VLAN的級(jí)聯(lián)方案提供了一個(gè)標(biāo)準(zhǔn)的協(xié)議
3.如何使用VLAN
將某些端口劃為一個(gè)VLAN,基于MAC地址什么的...
其實(shí),至于怎么劃分VLAN,標(biāo)準(zhǔn)中并沒有給出什么硬性的規(guī)定,只要能夠保證屬于同一VLAN的端口完全否則IEEE 802系列的標(biāo)準(zhǔn)即可,換句話說就是屬于同一VLAN的所有交換機(jī)的所有同一VLAN的端口完全就是一個(gè)以太網(wǎng)即可,透?jìng)饕蕴珟?/p>
到此為止,我們基本上已經(jīng)忘了配置trunk,access,基于端口劃VLAN的命令了,腦子里面留下的只是VLAN的核心概念,使用這些核心的概念,我們就可以在Linux上配置完整的VLAN方案了,如果你去硬套Cisco的配置,那么結(jié)果只是悲哀。比如如果你問:如何在Linux上配置端口為access,如何在Linux上將某些網(wǎng)卡劃到一個(gè)VLAN...
理解Linux Bridge的都知道,Linux本身就可以實(shí)現(xiàn)多個(gè)Bridge設(shè)備,因?yàn)長inux的Bridge是軟的,所以一個(gè)Linux Box可以配置多個(gè)邏輯意義的Bridge,而多個(gè)Bridge設(shè)備之間必須通過第三層進(jìn)行通信,加之第三層正是以太網(wǎng)的邊界,因此一個(gè)Linux Box也就可以模擬多個(gè)以太網(wǎng)了,不同的Bridge設(shè)備就可以代表不同的VLAN。
#p#
Linux上的VLAN
Linux上的VLANLinux上的VLAN和Cisco/H3C上的VLAN不同,后者的VLAN是現(xiàn)有了LAN,再有V,也就是說是先有一個(gè)大的LAN,再劃分為不同的VLAN,而Linux則正好相反,由于Linux的Bridge設(shè)備是被創(chuàng)建出來的邏輯設(shè)備,因此Linux需要先創(chuàng)建VLAN,再創(chuàng)建一個(gè)Bridge關(guān)聯(lián)到該VLAN,創(chuàng)建VLAN很簡單:
ifconfig eth0 0.0.0.0 up
vconfig eth0 10
ifconfig eth0.10 up
當(dāng)使用vconfig創(chuàng)建了eth0.10之后,它就是一個(gè)“真實(shí)意義”的虛擬網(wǎng)卡設(shè)備了,類似br0,tap0,bond0之類的,在這個(gè)虛擬網(wǎng)卡之下綁定的是一個(gè)真實(shí)網(wǎng)卡eth0,也就是數(shù)據(jù)從eth0這塊真實(shí)網(wǎng)卡發(fā)出,eth0.10中的“.10”表示它可以承載VLAN 10的數(shù)據(jù)幀,并且在通過eth0發(fā)出之前要打上tag。那么打tag這件事自然而然就是通過eth0.10這個(gè)虛擬設(shè)備的hard_xmit來完成的,在這個(gè)hard_xmit中,打上相應(yīng)的tag后,再調(diào)用eth0的hard_xmit將數(shù)據(jù)真正發(fā)出,如下圖所示:
因此一個(gè)真實(shí)的物理網(wǎng)卡比如ethx,它可以承載多個(gè)VLAN的數(shù)據(jù)幀,因此它就是trunk端口了,如下所示:
Linux的VLAN工具vconfig采用ethx.y的方式以ethx為trunk端口加入VLAN id為y的VLAN中。類比Cisco/H3C,我們已經(jīng)創(chuàng)建了trunk,總結(jié)一下:使用vconfig創(chuàng)建一個(gè)ethx.y的虛擬設(shè)備,就創(chuàng)建了一個(gè)trunk,其中ethx就是trunk口,而y代表該trunk口連接的trunk鏈路可以承載的VLAN數(shù)據(jù)幀的id,我們創(chuàng)建ethx.a,ethx.b,ethx.c,ethx.d,就說明ethx可以承載VLAN a,VLAN b,VLAN c,VLAN d的數(shù)據(jù)幀。
接下來,我們看一下如何創(chuàng)建access端口。首先注意,由于Linux的Bridge是虛擬的,邏輯意義的,因此可以先創(chuàng)建了VLAN之后,再根據(jù)這個(gè)VLAN動(dòng)態(tài)的創(chuàng)建Bridge,而不是“為每一個(gè)端口配置VLAN id”,我們需要做的很簡單:
創(chuàng)建VLAN:
ifconfig eth0 0.0.0.0 up
vconfig eth0 10
ifconfig eth0.10 up
為該VLAN創(chuàng)建Bridge:
brctl addbr brvlan10
brctl addif brvlan10 eth0.10
為該VLAN添加網(wǎng)卡:
ifconfig eth1 0.0.0.0 up
brctl addif brvlan10 eth1
ifconfig eth2 0.0.0.0 up
brctl addif brvlan10 eth2
...
這就完了。從此,eth1和eth2就是VLAN 10的access端口了,而eth0則是一個(gè)trunk端口,級(jí)聯(lián)VLAN的時(shí)候要用到,如果不需要級(jí)聯(lián)VLAN,而僅僅需要擴(kuò)展VLAN 10,那么你大可將eth1連接在一個(gè)二層常規(guī)交換機(jī)或者h(yuǎn)ub上...同樣的,你可以再創(chuàng)建一個(gè)VLAN,同樣通過eth0來級(jí)聯(lián)上游VLAN交換機(jī):
ifconfig eth0 0.0.0.0 up
vconfig eth0 20
ifconfig eth0.20 up
brctl addbr brvlan20
brctl addif brvlan20 eth0.20
ifconfig eth5 0.0.0.0 up
brctl addif brvlan20 eth5
如下圖所示:
這下基本就搞定了Linux上VLAN的配置,接下來還有一個(gè)內(nèi)容,那就是VLAN之間的通信。這個(gè)知識(shí)點(diǎn)最簡單了,那就是使用路由,為此很多人把支持VLAN的三層交換機(jī)和路由器等同起來。既然使用路由就需要一個(gè)IP地址作為網(wǎng)關(guān),那么如何能尋址到這個(gè)IP地址自然就是一個(gè)不可回避的問題,我們要把這個(gè)IP配置在哪里呢?可以肯定的是,必須配置在當(dāng)前VLAN的某處,于是我們有多個(gè)地方可以配置這個(gè)IP:
1.同屬于一個(gè)VLAN的路由器接口上,且該路由器有到達(dá)目的VLAN的路由(該路由器接口為trunk口)。
2.同屬于一個(gè)VLAN的ethx.y似的虛擬接口上,且該Linux Box擁有到指定VLAN a的路由(最顯然的,擁有ethx'.a虛擬接口)。
3.同屬于一個(gè)VLAN的Bridge設(shè)備上(Linux的Bridge默認(rèn)帶有一個(gè)本地接口,可以配置IP地址),且該Linux Box擁有到指定VLAN a的路由(最顯然的,擁有ethx'.a虛擬接口或者目標(biāo)VLAN的Bridge設(shè)備)。
其中的1和2實(shí)際上沒有什么差別,本質(zhì)上就是找一個(gè)能配置IP地址的地方,大多數(shù)情況下使用2,但是如果出現(xiàn)同一個(gè)VLAN在同一個(gè)Linux Box配置了兩個(gè)trunk端口,那么就要使用Bridge的地址了,比如下面的配置:
brctl addbr brvlan10
brctl addif brvlan10 eth0.10
brctl addif brvlan10 eth1.10
ifconfig brvlan10 up
此時(shí)有兩個(gè)ethx.y型的虛擬接口,為了不使路由沖突,只能配置一個(gè)IP,那么此IP地址就只能配置在brvlan10上了。不管配置在Bridge上還是配置在ethx.y上,都是要走IP路由的,只要MAC地址指向了本地的任意的一個(gè)接口,在netif_receive_skb調(diào)用handle_bridge的時(shí)候都會(huì)將數(shù)據(jù)幀導(dǎo)向本地的IP路由來處理。Linux作為一個(gè)軟件,其并沒有原生實(shí)現(xiàn)硬件cache轉(zhuǎn)發(fā),因此對(duì)于Linux而言,所謂的三層交換其實(shí)就是路由。
我們看一下一個(gè)被打上tag的數(shù)據(jù)幀什么時(shí)候脫去這個(gè)tag,在定義上,它是從access端口發(fā)出時(shí)脫去的,然而在語義上,只要能保證access端口發(fā)出的數(shù)據(jù)幀不帶有tag即可,因此對(duì)于何時(shí)脫去tag并沒有什么嚴(yán)格的要求。在Linux的VLAN實(shí)現(xiàn)上,packet_type的func作為一個(gè)第三層的處理函數(shù)來單獨(dú)處理802.1q數(shù)據(jù)幀,802.1q此時(shí)和IP協(xié)議處于一個(gè)同等的位置,VLAN的func函數(shù)vlan_skb_recv正如IP的處理函數(shù)ip_rcv一樣。在Linux實(shí)現(xiàn)的VLAN中,只有當(dāng)一個(gè)端口收到了一個(gè)數(shù)據(jù)幀,并且該數(shù)據(jù)幀是發(fā)往本地的時(shí)候,才會(huì)到達(dá)第三層的packet_type的func處理,否則只會(huì)被第二層處理,也就是Bridge邏輯處理,Linux的原生Bridge實(shí)現(xiàn)并不能處理802.1q數(shù)據(jù)幀,甚至都不能識(shí)別它。整個(gè)trunk口收發(fā)數(shù)據(jù)幀,IEEE 802.1q幀處理,以及VLAN間通信的示意圖如下:
到此為止,Linux的VLAN要點(diǎn)基本已經(jīng)說完了,有了這些理解,我想設(shè)計(jì)一個(gè)單臂Linux Box就不是什么難事了,單臂設(shè)備***的優(yōu)勢(shì)就是節(jié)省物理設(shè)備,同時(shí)還能實(shí)現(xiàn)隔離。這個(gè)配置不復(fù)雜,如果不想用VLAN實(shí)現(xiàn)的話也可以用ip addr add dev ...增加虛擬IP的方式來實(shí)現(xiàn),然而用VLAN實(shí)現(xiàn)的好處在于可以和既有的三層交換機(jī)進(jìn)行聯(lián)動(dòng),也可以直接插在支持標(biāo)準(zhǔn)的IEEE 802.1q的設(shè)備的trunk口上。
機(jī)制搭臺(tái),策略唱戲。既然VLAN的實(shí)現(xiàn)機(jī)制已經(jīng)了然于胸了,那么它的缺點(diǎn)估計(jì)你也看到了,如何去克服呢?PVLAN說實(shí)在的是一個(gè)VLAN的替代方案。解決了VLAN間的IP網(wǎng)段隔離問題,我們?cè)贚inux上如何實(shí)現(xiàn)它呢?這倒也不難,無非就是在LAN上添加一些訪問控制策略罷了,完全可以用純軟件的方式來實(shí)現(xiàn),甚至都可以用ebtables/arptables/iptables來實(shí)現(xiàn)一個(gè)PVLAN。如果說VLAN是一個(gè)硬實(shí)現(xiàn)的VLAN的話,那么PVLAN純粹是一個(gè)軟實(shí)現(xiàn)的VLAN,甚至都不需要?jiǎng)澐质裁碫LAN,大家都處于一個(gè)IP網(wǎng)段,只需要配置好訪問控制策略即可,使得同一IP子網(wǎng)的Host只能和默認(rèn)網(wǎng)關(guān)通信,而之間不能通信,所以說,即使你不知道“隔離VLAN”,“團(tuán)體VLAN”之類的術(shù)語,實(shí)際上你已經(jīng)實(shí)現(xiàn)了一個(gè)PVLAN了。
幾點(diǎn)總結(jié)
1.你需要首先規(guī)劃出你的網(wǎng)絡(luò)拓?fù)涠皇窍热パ芯縑LAN在Linux上如何配置以及如何實(shí)現(xiàn);
2.你需要深入理解VLAN設(shè)計(jì)的初衷,該配置哪些東西;
3.你需要知道對(duì)于VLAN哪些概念是核心,哪些概念并不是必須的。
4.不管基于什么平臺(tái)配置VLAN,只有兩點(diǎn)是必須的:a.哪些端口屬于哪個(gè)VLAN;b.哪個(gè)端口是級(jí)聯(lián)端口,屬于多個(gè)VLAN。
5.其它的都不用去死記硬背,都是浮云...
原文鏈接:http://blog.csdn.net/dog250/article/details/7354590