不一樣的以太網接入設備,一幀能傳輸的數據量是有差別的。docker
普通的以太網卡,一幀最多可以傳輸 1500 字節的數據;而某些虛擬設備,傳輸能力要打些折扣。此外,鏈路層除了以太網還有其餘協議,這些協議中數據幀傳輸能力也有差別。shell
若是待發送的數據超過幀的最大承載能力,就須要先對數據進行分片,而後再經過若干個幀進行傳輸。編程
下面是一個典型例子,待發送的數據總共 4000 字節,假設以太網設備一幀最多隻能承載 1500 字節。很明顯,數據須要劃分紅 3 片,再經過 3 個幀進行發送:bash
換句話講,咱們須要知道接入設備一幀最多能發送多少數據。這個參數在網絡領域被稱爲 最大傳輸單元 ( maximum transmission unit ),簡稱 MTU 。 MTU 描述鏈路層可以傳輸的最大數據單元。網絡
咱們知道,在 Linux 系統能夠用 ifconfig 或者 ip 這兩個命令來查看網卡信息,其中包括 MTU 。less
接下來,咱們打開 docker 進入 netbox 環境進行演示:tcp
docker run --name netbox --rm -it --privileged --cap-add=NET_ADMIN --cap-add=SYS_ADMIN -v /data -h netbox fasionchan/netbox:0.5 bash /script/netbox.sh
先以 ifconfig 命令爲例:oop
root@netbox [ ~ ] ➜ ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.1.2 netmask 255.255.255.0 broadcast 0.0.0.0 ether 5a:ff:7e:28:81:bc txqueuelen 1000 (Ethernet) RX packets 24 bytes 2165 (2.1 KB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 27 bytes 2164 (2.1 KB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1000 (Local Loopback) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ip 命令也能夠,咱們更推薦使用這個:大數據
root@netbox [ ~ ] ➜ ip link 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ipip 0.0.0.0 brd 0.0.0.0 3: ip6tnl0@NONE: <NOARP> mtu 1452 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/tunnel6 :: brd :: 6: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000 link/ether 5a:ff:7e:28:81:bc brd ff:ff:ff:ff:ff:ff link-netnsid 0
咱們能夠用 ip 命令,來修改 eth0 的 MTU , 以修改 eth0 網卡 MTU 爲例:spa
root@netbox [ ~ ] ➜ ip link set eth0 mtu 68
不一樣的接入設備,支持的 MTU 範圍不同。若是咱們將 MTU 設置得過小,設備將報錯:
root@netbox [ ~ ] ➜ ip link set eth0 mtu 40 Error: mtu less than device minimum.
咱們以兩臺用網線直接相連的主機做爲實驗環境,來觀察網卡 MTU 對發送、接收以太網幀的影響:
實驗環境一樣經過 docker 來啓動:
docker run --name mtu-lab --rm -it --privileged --cap-add=NET_ADMIN --cap-add=SYS_ADMIN -v /data -h mtu-lab fasionchan/netbox:0.5 bash /script/cable-lab.sh
咱們將 ant 主機 eth0 網卡的 MTU 設置成 68 ,發現數據大於 68 字節的以太網幀將沒法發送:
root@ant [ ~ ] ➜ ip link set eth0 mtu 68 root@ant [ ~ ] ➜ sendether -i eth0 -t 32:65:21:d3:01:2f -d 'hello, world!hello, world!hello, world!hello, world!hello, world!hello, world!hello, world!hello, world!hello, world!hello, world!' Fail to send ethernet frame: : Message too long
將 MTU 恢復爲默認值 1500 之後,能夠成功發送:
root@ant [ ~ ] ➜ ip link set eth0 mtu 1500 root@ant [ ~ ] ➜ sendether -i eth0 -t 32:65:21:d3:01:2f -d 'hello, world!hello, world!hello, world!hello, world!hello, world!hello, world!hello, world!hello, world!hello, world!hello, world!'
這就是 MTU 對發送環節的影響:若是數據量大於 MTU ,則沒法經過單個以太網幀發送出去,只能以 MTU 爲單位對數據進行分片,再封裝成若干個幀進行發送。
那麼,_MTU_ 對接收環節有什麼影響呢?
咱們將 bee 主機 eth0 網卡的 MTU 設置成 68 ,並啓動 tcpdump 進行抓包:
root@ant [ ~ ] ➜ ip link set eth0 mtu 68 root@ant [ ~ ] ➜ tcpdump -ni eth0
接着,咱們在主機 ant 上,向主機 bee 發送一個數據大於 68 字節的以太網幀:
root@ant [ ~ ] ➜ sendether -i eth0 -t 32:65:21:d3:01:2f -d 'hello, world!hello, world!hello, world!hello, world!hello, world!hello, world!hello, world!hello, world!hello, world!hello, world!'
然而,主機 ant 上的 tcpdump 程序告訴咱們,_eth0_ 網卡並無收到這個幀!因而可知,以太網幀數據長度一旦大於接收設備 MTU ,將被丟棄。
【小菜學網絡】系列文章首發於公衆號【小菜學編程】,敬請關注: