一:什么是流表
流(liu)表(biao)類似于交換機的MAC地(di)址表(biao),路(lu)由器(qi)的路(lu)由表(biao),是(shi) OpenvSwitch 指揮流(liu)量轉發的表(biao)。
Openflow是有多個(ge)版本(ben)的 ovs-ofctl僅啟用OpenFlow 1.0.,當使用其他版本(ben)OpenFlow時
需(xu)要(yao)使用(yong)ovs-ofctl -O來(lai)指定詳細的(de)版本,在一體機項目中。我們(men)使用(yong)的(de)openflow13 版本,因(yin)此查(cha)看流表的(de)命令(ling)為(wei)
ovs-ofctl -Oopenflow13 dump-flows br-int table=0
cookie=0x0, duration=1541435.636s, table=0, n_packets=4337289, n_bytes=660210111, priority=100 actions=goto_table:10
二:常見的流表字段分類
從上面的輸出結果能(neng)看出一個常見的流(liu)表可以分(fen)為三類(lei)(lei)、統計類(lei)(lei)、標識類(lei)(lei)、行為類(lei)(lei)。
統計類:duration 表示該(gai)規則自(zi)創建以來已經(jing)生存的時(shi)間(jian)(單位為秒)。n_packets 和(he) n_bytes 分(fen)別表示匹配(pei)該(gai)規則的數(shu)據包數(shu)和(he)總字節數(shu)。
標識(shi)(shi)類:cookie 用來(lai)標識(shi)(shi)一類規(gui)則(ze),table 標識(shi)(shi)表的(de)編號。默認規(gui)則(ze)都是從(cong)table=0開(kai)始按priority 優先(xian)級(ji)(ji)逐條匹配的(de),數字(zi)越大優先(xian)級(ji)(ji)越高。
行為類:actions對(dui)于匹配(pei)到的包,如何(he)進(jin)行處理。實(shi)際生產的流表中,我們可以看到有多個表項的動作(zuo)為goto_table和(he)set_field。其中,
goto_table用于跳轉到指定(ding)(ding)的表(biao)中繼續匹配和執行,set_field用于設置指定(ding)(ding)字段的值
三: 詳細字段說明
3.1 虛擬機如何獲取IP地址。
cookie=0x0, duration=1542867.268s, table=0, n_packets=4339798, n_bytes=660327009, priority=100 actions=goto_table:10
cookie=0x0, duration=1542867.196s, table=10, n_packets=0, n_bytes=0, priority=300,udp6,tp_dst=547 actions=CONTROLLER:65535
cookie=0x0, duration=1542867.172s, table=10, n_packets=137, n_bytes=47185, priority=300,udp,tp_dst=67 actions=CONTROLLER:65535
一個常見的流表項和安全(quan)組(zu)和防火墻類似,都是匹(pi)配到指定(ding)規則的包(bao),按指定(ding)的行為(action)去處理.
上面(mian)第一條沒有任(ren)何(he)匹配條件,標識所有的包都匹配,go_to_table 表示繼續交給table=10的表去處理。(在實際應(ying)用(yong)中(zhong)我們可(ke)以使用(yong)該命令來查看
指定table的(de)條目,而(er)不是一次(ci)將(jiang)所有的(de)流表都(dou)輸出。)
ovs-ofctl -Oopenflow13 dump-flows br-int table=0 #此時就只看(kan)table=0的(de)表(biao)
上(shang)面條(tiao)是table=10的表項有(you)兩條(tiao),因為優(you)先級都是300,則默認至上(shang)而下的匹(pi)配執行。具體含義表示匹(pi)配UDPv6協議的數據包,
目的端(duan)口為547(DHCPv6協議的默認端(duan)口),如果(guo)匹配成功,將數據包發送到控(kong)制(zhi)器(qi)進行處理(controller:65535)。而第三條(tiao)的含(han)義是
目標(biao)端口(kou)是udp 67的(de)端口(kou)包(bao),交給(gei)控制器(qi)來處理(li)(li)。dhcp服(fu)務默認(ren)端口(kou)就是udp 67.因此從該(gai)規(gui)則(ze)我們看(kan)出,dhcp的(de)請求包(bao)將發送給(gei)控制器(qi)去處理(li)(li),
事實上也確實如此,下面我(wo)們來抓包來分析。
在物理機上抓目標端(duan)(duan)(duan)口(kou)為6633端(duan)(duan)(duan)口(kou)數據(ju)包(6633端(duan)(duan)(duan)口(kou)為控制器(qi)監聽地址(zhi)),OFPT_PACKET_IN 為openflow向(xiang)上發給控制器(qi)的請求報文。
詳細的報文格式如下
打開Openflow 協議的Data 字段可以(yi)看到發送(song)dhcp 請求的mac ,目標mac為廣播報文。下面我們查看虛擬機接口的mac
發(fa)現(xian)該mac 確實是虛擬(ni)機(ji)的(de)接(jie)口的(de)mac ,因此確定(ding)這個(ge)dhcp的(de)請求(qiu)包(bao)為虛擬(ni)機(ji)發(fa)送(song)出來(lai)的(de),其通過openflow協議(yi)發(fa)送(song)給了控制(zhi)器(qi)。
下面是(shi)控制器回復(fu)的響(xiang)應報文(wen) ,包(bao)括了dhcp 的響(xiang)應包(bao),該報文(wen)是(shi)發(fa)送給虛擬(ni)機所(suo)在的物(wu)理機節(jie)點上(shang),到達物(wu)理機后,由物(wu)理機轉發(fa)給對應的虛擬(ni)機。
總結:從上述例子中我們知道在一體機(ji)項目(mu)中通過20號流(liu)表來把(ba)虛擬(ni)機(ji)的dhcp的請求包發送給(gei)了控(kong)制器,如果流(liu)表不正常、控(kong)制器不正常、控(kong)制器6633端口被防火(huo)墻規則所限制等都會造成虛擬(ni)機(ji)拿不到IP地址。
3.2 同網段的虛擬機相互之間通信
原理:相同網絡的(de)虛(xu)擬機(ji)要想通(tong)信需要通(tong)過arp 報文(wen)獲取(qu)對方(fang)的(de)mac地址,接下來(lai)我(wo)們繼續分析流表,看虛(xu)擬機(ji)是(shi)如何發送arp請求和響應的(de)。
cookie=0x0, duration=8729580.116s, table=20, n_packets=25135358, n_bytes=4688159427, priority=200,ip,in_port="tap4432d19a-eb"
actions=load:0x7->NXM_NX_REG5[],load:0x7->NXM_NX_REG6[],set_field:0x23->tun_id,goto_table:21
cookie=0x0, duration=8729580.115s, table=20, n_packets=249587, n_bytes=10482654, priority=200,arp,in_port="tap4432d19a-eb" actions=load:0x7->NXM_NX_REG5[],load:0x7->NXM_NX_REG6[],set_field:0x23->tun_id,goto_table:21
cookie=0x0, duration=7607595.333s, table=20, n_packets=6775179, n_bytes=804658123, priority=200,ip,in_port="tap41e48bdc-5b" actions=load:0x8->NXM_NX_REG5[],load:0x11->NXM_NX_REG6[],set_field:0x47->tun_id,goto_table:21
cookie=0x0, duration=7607595.332s, table=20, n_packets=206073, n_bytes=8655066, priority=200,arp,in_port="tap41e48bdc-5b" actions=load:0x8->NXM_NX_REG5[],load:0x11->NXM_NX_REG6[],set_field:0x47->tun_id,goto_table:21
Ip,in_port=tap4432d19a-eb 表(biao)示其(qi)協議(yi)是(shi)IP協議(yi),流量是(shi)從tap4432d19a-eb 發出來(lai)的,將(jiang)執行(xing)的操作 load:0x7->MXM_NX_REG5[],load:0x->MXM_NX_REG6
Set_field: 0x23->tun_id 。
上(shang)述(shu)的(de)操作(zuo)看上(shang)去復雜,其實就做了一件事打標記(ji),只(zhi)不過其標記(ji)是存放在對應的(de)寄存器中,reg5的(de)標記(ji)表(biao)(biao)示虛(xu)擬機port的(de)來源的(de)標記(ji),reg6標記(ji)則表(biao)(biao)示同一個subnet的(de)標記(ji),而tun_id 從字(zi)面意思上(shang)可以(yi)看出(chu)是隧道標記(ji)。
因為上述環(huan)境為vxlan 網絡,因此每個(ge)不同的vpc 對應(ying)一個(ge)不同的tun_id,通過不同tun_id 來隔離(li)不同vpc的租戶(hu)流量。
同樣的(de)(de)第二條(tiao)也(ye)是打標(biao)(biao)記,只不過其標(biao)(biao)識(shi)的(de)(de)協(xie)議是來自arp協(xie)議的(de)(de)數據包。分(fen)別(bie)對比1 2條(tiao)數據和3 4 條(tiao)數據可以確定tap4432d19a-eb 和tap41e48bdc-5b的(de)(de)兩個port 分(fen)別(bie)輸入(ru)兩個完全不同的(de)(de)subnet 。因(yin)為reg6 標(biao)(biao)記不一樣,待會我們會驗證這一點(dian)。
cookie=0x0, duration=8825531.760s, table=21, n_packets=92159712, n_bytes=12528380058, priority=100 actions=goto_table:22
cookie=0x0, duration=8825531.760s, table=22, n_packets=92159712, n_bytes=12528380058, priority=100 actions=goto_table:30
上述這兩條規則只是做(zuo)跳轉(zhuan),將流量引入了30號(hao)流表。
cookie=0x0, duration=8729580.113s, table=30, n_packets=20, n_bytes=840, priority=300,arp,reg6=0x7,arp_tpa=10.100.255.5,arp_op=1 actions=move:NXM_OF_ETH_SRC[]->NXM_OF_ETH_DST[],set_field:fa:16:3e:31:cc:e5->eth_src,set_field:2->arp_op,move:NXM_NX_ARP_SHA[]->NXM_NX_ARP_THA[],set_field:fa:16:3e:31:cc:e5->arp_sha,move:NXM_OF_ARP_SPA[]->NXM_OF_ARP_TPA[],set_field:10.100.255.5->arp_spa,IN_PORT
上述(shu)流(liu)表(biao)要想看明白(bai)需要對arp 的報文(wen)有一定的了解(jie),因(yin)此我們說下arp報文(wen)的格式(shi)
我們先看華為官網(wang)的例子中arp報文的部分格(ge)式如(ru)下(xia)
從上面看出一個arp 報(bao)文(wen)(wen)有發(fa)送mac地址 發(fa)送者IP地址 和目標mac地址和目標IP地址。 Opcode: 1 表(biao)示是arp 請求的報(bao)文(wen)(wen), 2 則表(biao)示是arp 的響(xiang)應的報(bao)文(wen)(wen)。
了解上述信息后我們(men)在(zai)看報文(wen)就(jiu)豁(huo)然開朗(lang)了,arp_tpa=10.100.255.5,arp_op=1,表示如果是(shi)arp請求的目標IP是(shi)10.100.255.5,則
move:NXM_OF_ETH_SRC[]->NXM_OF_ETH_DST[] set_field:fa:16:3e:31:cc:e5->eth_src ,將源mac修(xiu)改為目標mac ,而(er)將指定的(de)(de)fa:16:3e:31:cc:e5 ,寫(xie)進源mac, 而(er)set_field:2->arp_op,表示將arp 的(de)(de)請求包改為arp 的(de)(de)應答包。
上述是修改了2層以太網的(de)封裝包,而下面則是將arp的(de)封裝包也(ye)進行了修改,ARP_SHA 表示(shi) Ethernet Address of Sender,發送方(fang)的(de)以太網地址,
ARP_THA 表(biao)示(shi) Ethernet Address of Destination 接受方(fang)的以太網地址(zhi),ARP_SPA 表(biao)示(shi) 發送方(fang)的IP地址(zhi) ARP_TPA 則表(biao)示(shi)接受方(fang)的IP 地址(zhi)。
move:NXM_NX_ARP_SHA[]->NXM_NX_ARP_THA[],set_field:fa:16:3e:31:cc:e5->arp_sha,move:NXM_OF_ARP_SPA[]->NXM_OF_ARP_TPA[],set_field:10.100.255.5->arp_spa,IN_PORT
上述的(de)報文就(jiu)是將ARP的(de)發送(song)方的(de)以太網(wang)地(di)址(zhi)(zhi)(zhi)和IP地(di)址(zhi)(zhi)(zhi),都(dou)修改(gai)為(wei)了接(jie)收方的(de)以太網(wang)地(di)址(zhi)(zhi)(zhi)和IP地(di)址(zhi)(zhi)(zhi)。而將發送(song)方的(de)IP修改(gai)為(wei) 10.100.255.5
發送方的mac 修改(gai)為fa:16:3e:31:cc:e5 。下面我們來查詢(xun)該mac對(dui)應(ying)的接口(kou),則(ze)發現(xian)就是之(zhi)前的tap4432d19a-eb 。
virsh domiflist 51
Interface Type Source Model MAC
----------------------------------------------------------------
tap4432d19a-eb bridge br-int virtio fa:16:3e:31:cc:e5
同時將(jiang)2層以太網封(feng)裝的(de)mac 和2層arp報文的(de)封(feng)裝修改后,將(jiang)目標改成源,其整體上(shang)就做了一件事,arp 地址代答,也就是(shi)說 如(ru)果arp 請求查詢10.100.255.5的(de)IP對(dui)應的(de)mac 時,將(jiang)tap4432d19a-eb對(dui)應接口mac 來作為arp的(de)響應的(de)報文發(fa)送出去。此時也驗證了該mac地址對(dui)應的(de)IP是(shi)10.100.255.5.
cookie=0x0, duration=8729580.113s, table=30, n_packets=6292, n_bytes=264264,
priority=200,arp,tun_id=0x23,in_port=vxlan1,arp_tpa=10.100.255.5 actions=output:"tap4432d19a-eb"
此流表表示如果tun_id是(shi) 0x23 流量是(shi)從(cong)(cong)vxlan1 進(jin)入來(lai)的(de) 且arp 的(de)接收的(de)方(fang)IP是(shi)10.100.255.5 從(cong)(cong) tap4432d19a-eb 發送出去(qu)。經過上述幾天流表,無(wu)論(lun)是(shi)相同(tong)(tong)網段(相同(tong)(tong)tun_id )的(de)虛擬機都可以通過arp的(de)報文(wen)來(lai)拿到(dao)通信雙(shuang)方(fang)的(de)mac 地(di)址了。
解決了mac地址的問(wen)題,則同subnet的虛(xu)擬機既可以完成2層(ceng)封裝,如果想要進行IP通(tong)信,還(huan)需要將IP流量引入指定虛(xu)擬機的tap口,接下(xia)來我們具體分析。
cookie=0x0, duration=8729580.112s, table=40, n_packets=23418345, n_bytes=3836008358, priority=200,ip,in_port=vxlan1,dl_dst=fa:16:3e:31:cc:e5 actions=load:0x7->NXM_NX_REG5[],load:0x7->NXM_NX_REG6[],goto_table:81
根據前(qian)面(mian)的(de)理解(jie),這條(tiao)報文的(de)意思(si)是 如果是IP協議,從vxlan1 進來的(de) 目標mac地(di)址(zhi)是 fa:16:3e:31:cc:e5也就是10.100.255.5 其tap口為(wei) tap4432d19a-eb的(de)流(liu)量包(bao),跳轉到81號(hao)流(liu)表(biao)。
cookie=0x0, duration=8728669.421s, table=81, n_packets=158, n_bytes=13828, priority=200,icmp,reg5=0x7 actions=ct(commit,table=83)
cookie=0x0, duration=8728268.791s, table=81, n_packets=3567, n_bytes=499779, priority=200,tcp,reg5=0x7,tp_dst=3389 actions=ct(commit,table=83)
cookie=0x0, duration=7976525.032s, table=81, n_packets=55623, n_bytes=5723897, priority=200,tcp,reg5=0x7,tp_dst=9098 actions=ct(commit,table=83)
上(shang)述三條的意思(si)是如果其reg5=0x7 ,上(shang)述曾說明過(guo)其就代表的tap4432d19a-eb 的tap口(kou),并(bing)且協議是icmp 或 tcp協議目(mu)標(biao)(biao)端口(kou)是3389 或目(mu)標(biao)(biao)端口(kou)是9098的流量(liang),其追蹤(zong)后重(zhong)新提交到83號流表。
cookie=0x0, duration=8825531.759s, table=83, n_packets=38664553, n_bytes=5163764381, priority=100 actions=goto_table:84
cookie=0x0, duration=8825531.758s, table=84, n_packets=38664553, n_bytes=5163764381, priority=100 actions=goto_table:85
cookie=0x0, duration=8729580.111s, table=85, n_packets=23415882, n_bytes=3835853296, priority=200,reg5=0x7 actions=output:"tap4432d19a-eb"
標(biao)記為0x7的tap4432d19a-eb ,經過84 85好(hao)流(liu)表都發送到(dao)了tap4432d19a-eb的接(jie)口,這樣就完(wan)成了與tap4432d19a-eb的流(liu)量的引導。
總結:從arp地址應到、到流量引導,可以看到整個(ge)流量的(de)過程都是在流表中進(jin)行的(de),而流表的(de)下發和(he)更新都是由控制(zhi)器來動態(tai)更新和(he)生成的(de)。