Linux上的物理網(wǎng)卡與虛擬網(wǎng)絡(luò)設(shè)備

物理網(wǎng)卡

物理網(wǎng)卡工作原理

link device type

通過ip link add可以創(chuàng)建多種類型的虛擬網(wǎng)絡(luò)設(shè)備,在man ip link中可以得知有以下類型的device:

bridge - Ethernet Bridge device
can - Controller Area Network interface
dummy - Dummy network interface
ifb - Intermediate Functional Block device
ipoib - IP over Infiniband device
macvlan - Virtual interface base on link layer address (MAC)
vcan - Virtual Local CAN interface
veth - Virtual ethernet interface
vlan - 802.1q tagged virtual LAN interface
vxlan - Virtual eXtended LAN
ip6tnl - Virtual tunnel interface IPv4|IPv6 over IPv6
ipip - Virtual tunnel interface IPv4 over IPv4
sit - Virtual tunnel interface IPv6 over IPv4

VEPA

Virtual Ethernet Port Aggregator。它是HP在虛擬化支持領(lǐng)域?qū)笴isco的VN-Tag的技術(shù)。

解決了虛擬機(jī)之間網(wǎng)絡(luò)通信的問題,特別是位于同一個(gè)宿主機(jī)內(nèi)的虛擬機(jī)之間的網(wǎng)絡(luò)通信問題。

VN-Tag在標(biāo)準(zhǔn)的協(xié)議頭中增加了一個(gè)全新的字段,VEPA則是通過修改網(wǎng)卡驅(qū)動(dòng)和交換機(jī),通過發(fā)夾彎技術(shù)回注報(bào)文。

vepa工作原理

TUN

TUN是Linux系統(tǒng)里的虛擬網(wǎng)絡(luò)設(shè)備,它的原理和使用在Kernel DocWiki做了比較清楚的說明。

TUN設(shè)備模擬網(wǎng)絡(luò)層設(shè)備(network layer),處理三層報(bào)文,IP報(bào)文等,用于將報(bào)文注入到網(wǎng)絡(luò)協(xié)議棧。

TUN設(shè)備工作原理

應(yīng)用程序(app)可以從物理網(wǎng)卡上讀寫報(bào)文,經(jīng)過處理后通過TUN回送,或者從TUN讀取報(bào)文處理后經(jīng)物理網(wǎng)卡送出。

利用TUN實(shí)現(xiàn)VPN

TUN設(shè)備創(chuàng)建

創(chuàng)建:

int tun_alloc(char *dev)
{
    struct ifreq ifr;
    int fd, err;

    if( (fd = open("/dev/net/tun", O_RDWR)) < 0 ){
        printf("open /dev/net/tun fail\n");
        return -1;
    }

    memset(&ifr, 0, sizeof(ifr));

    /* Flags: IFF_TUN   - TUN device (no Ethernet headers) 
     *        IFF_TAP   - TAP device  
     *
     *        IFF_NO_PI - Do not provide packet information  
     */ 
    ifr.ifr_flags = IFF_TUN; 
    if( *dev )
        strncpy(ifr.ifr_name, dev, IFNAMSIZ);

    if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){
        close(fd);
        return err;
    }
    strcpy(dev, ifr.ifr_name);
    return fd;
}              

int fd = tun_alloc("tun-default");

if (fd == -1) {
    printf("create error: %d\n", fd);
    return;
}

while(1){
    sleep(1000);
}

創(chuàng)建之后,使用ip addr就會(huì)看見一個(gè)名為”tun-default”的虛擬網(wǎng)卡

注意:如果程序退出,關(guān)閉了fd,虛擬網(wǎng)卡也會(huì)隨之消失。

$ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 52:54:00:bd:97:1e brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic eth0
       valid_lft 81917sec preferred_lft 81917sec
    inet6 fe80::5054:ff:febd:971e/64 scope link
       valid_lft forever preferred_lft forever
4: tun-default: <POINTOPOINT,MULTICAST,NOARP> mtu 1500 qdisc noop state DOWN qlen 500
    link/none

可以對(duì)tun-default設(shè)置IP:

$sudo ip addr add 1.1.1.1 dev tun-default

$ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 52:54:00:bd:97:1e brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic eth0
       valid_lft 81806sec preferred_lft 81806sec
    inet6 fe80::5054:ff:febd:971e/64 scope link
       valid_lft forever preferred_lft forever
4: tun-default: <POINTOPOINT,MULTICAST,NOARP> mtu 1500 qdisc noop state DOWN qlen 500
    link/none
    inet 1.1.1.1/32 scope global tun-default
       valid_lft forever preferred_lft forever

使用open/write等文件操作函數(shù)從fd中進(jìn)行讀取操作,就是在收取報(bào)文,向fd中寫入數(shù)據(jù),就是在發(fā)送報(bào)文。

TAP

TAP是Linux系統(tǒng)里的虛擬網(wǎng)絡(luò)設(shè)備,它的原理和使用在Kernel DocWiki做了比較清楚的說明。

不同于TUN的是,TAP設(shè)備模擬鏈路層設(shè)備(link layer),處理二層報(bào)文,以太網(wǎng)幀等。

TAP設(shè)備創(chuàng)建

TAP設(shè)備的創(chuàng)建過程和TUN類似,在ioctl設(shè)置的時(shí)候,將類型設(shè)置為IFF_TAP即可。

/* Flags: IFF_TUN   - TUN device (no Ethernet headers) 
 *        IFF_TAP   - TAP device  
 *
 *        IFF_NO_PI - Do not provide packet information  
 */ 
ifr.ifr_flags = IFF_TAP;     //<--- TAP設(shè)備
if( *dev )
    strncpy(ifr.ifr_name, dev, IFNAMSIZ);

if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){
    close(fd);
    return err;
}
strcpy(dev, ifr.ifr_name);
return fd;

TAP設(shè)備與TUN設(shè)備的區(qū)別在于:

TAP虛擬的是一個(gè)二層設(shè)備,具有MAC地址,接收、發(fā)送的是二層包。
TUN虛擬的是一個(gè)三層設(shè)備,沒有MAC地址,接收、發(fā)送的是三層包。

macvlan

有時(shí)我們可能需要一塊物理網(wǎng)卡綁定多個(gè) IP 以及多個(gè) MAC 地址,雖然綁定多個(gè) IP 很容易,但是這些 IP 會(huì)共享物理網(wǎng)卡的 MAC 地址,可能無法滿足我們的設(shè)計(jì)需求,所以有了 MACVLAN 設(shè)備,其工作方式如下:

macvlan工作原理

MACVLAN 會(huì)根據(jù)收到包的目的 MAC 地址判斷這個(gè)包需要交給哪個(gè)虛擬網(wǎng)卡。單獨(dú)使用 MACVLAN 好像毫無意義,但是配合之前介紹的 network namespace 使用,我們可以構(gòu)建這樣的網(wǎng)絡(luò):

macvlan工作原理2
macvlan的工作原理3

采摘

macvlan使用

創(chuàng)建一個(gè)基于eth0的名為macv1的macvlan網(wǎng)卡:

ip link add link eth0 name macv1 type macvlan 

macvlan支持三種模式,bridge、vepa、private,在創(chuàng)建的時(shí)候設(shè)置“mode XXX”:

macvlan brige模式

bridge模式,macvlan網(wǎng)卡和物理網(wǎng)卡直接可以互通,類似于接入到同一個(gè)bridge。

macvlan vepa模式

vepa模式下,兩個(gè)macvlan網(wǎng)卡直接不能直接通信,必須通過外部的支持“發(fā)夾彎”交換機(jī)才能通信。

macvlan vepa模式

private模式下,macvlan發(fā)出的廣播包(arp等)被丟棄,即使接入了支持“發(fā)夾彎”的交換機(jī)也不能發(fā)現(xiàn)其它macvlan網(wǎng)卡,除非手動(dòng)設(shè)置mac。

macvtap

MACVTAP 是對(duì) MACVLAN的改進(jìn),把 MACVLAN 與 TAP 設(shè)備的特點(diǎn)綜合一下,使用 MACVLAN 的方式收發(fā)數(shù)據(jù)包,但是收到的包不交給 network stack 處理,而是生成一個(gè) /dev/tapX 文件,交給這個(gè)文件:

macvtap工作原理

由于 MACVLAN 是工作在 MAC 層的,所以 MACVTAP 也只能工作在 MAC 層,不會(huì)有 MACVTUN 這樣的設(shè)備。

ipvlan

ipvlan和macvlan的區(qū)別在于它在ip層進(jìn)行流量分離而不是基于mac地址,同屬于一塊宿主以太網(wǎng)卡的所有ipvlan虛擬網(wǎng)卡的mac地址都是一樣的。

[圖片上傳失敗...(image-d98b6f-1597455459947)]

ip link add link <master-dev> <slave-dev> type ipvlan mode { l2 | L3 }

veth

veth工作原理

veth設(shè)備是成對(duì)創(chuàng)建的:

$ip link add vethA type veth peer name vethB

創(chuàng)建之后,執(zhí)行ip link就可以看到新創(chuàng)建的veth設(shè)備:

58: vethB@vethA: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
link/ether ee:1b:b0:11:38:eb brd ff:ff:ff:ff:ff:ff
59: vethA@vethB: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000
link/ether a6:f8:50:36:2d:1e brd ff:ff:ff:ff:ff:ff

注意veth設(shè)備前面的ID,58:59:,一對(duì)veth設(shè)備的ID是相差1的,并且系統(tǒng)內(nèi)全局唯一。可以通過ID找到一個(gè)veth設(shè)備的對(duì)端。

veth設(shè)備理解

ifb

Intermediate Functional Block device,連接ifb中做了很詳細(xì)的介紹。

參考

  1. Kernel Doc tuntap.txt
  2. Wiki TUN/TAP
  3. Linux網(wǎng)絡(luò)虛擬化
  4. TUN/TAP MACVLAN MACVTAP
  5. 圖解幾個(gè)與Linux網(wǎng)絡(luò)虛擬化相關(guān)的虛擬網(wǎng)卡
  6. veth設(shè)備理解
  7. ifb
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容