Как кадр находит нужный компьютер внутри одной сети
Почти все проводные локальные сети — Ethernet, и Wi-Fi устроен похоже. Данные по ним передаются кадрами:
┌──────────────┬──────────────┬──────────┬───────────────────────┬─────┐
│ MAC получат. │ MAC отправ. │ тип │ данные (IP-пакет) │ FCS │
│ 6 байт │ 6 байт │ 2 байта │ 46–1500 байт │ 4 │
└──────────────┴──────────────┴──────────┴───────────────────────┴─────┘
0x0800 — IPv4, 0x86DD — IPv6, 0x0806 — ARP
Поле «тип» говорит, что лежит внутри. FCS — контрольная сумма: получатель пересчитывает её и молча выбрасывает испорченный кадр. Повторную отправку Ethernet не делает — это задача TCP (модуль 05).
MAC-адрес — 48-битный адрес сетевого интерфейса, записывается шестью байтами в шестнадцатеричном виде. Первые три байта — код производителя (OUI), остальные — номер устройства.
$ ip link show ens18
2: ens18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
link/ether bc:24:11:b2:13:af brd ff:ff:ff:ff:ff:ff
| Что видно | Значение |
|---|---|
bc:24:11:b2:13:af | MAC-адрес интерфейса; bc:24:11 — код, выданный производителю (здесь — виртуальной платформе Proxmox) |
brd ff:ff:ff:ff:ff:ff | Широковещательный адрес: кадр получат все узлы сети |
UP,LOWER_UP | Интерфейс включён, и есть физическое соединение («линк») |
mtu 1500 | Максимальный размер данных в кадре (раздел 07) |
MAC-адрес действует только внутри одной локальной сети: маршрутизатор, пересылая пакет дальше, создаёт новый кадр со своими MAC-адресами. Поэтому сервер в интернете никогда не видит MAC-адрес вашего компьютера. Телефоны и ноутбуки при подключении к Wi-Fi часто используют случайный MAC — чтобы их нельзя было отследить по сетям.
Коммутатор запоминает, с какого порта пришёл кадр с каким MAC-адресом отправителя, и строит таблицу коммутации. Кадр для известного адреса уходит только в нужный порт; для неизвестного — во все порты, кроме входящего («наводнение»). Широковещательные кадры тоже уходят во все порты.
Соберём коммутатор сами: в Linux его роль играет мост (bridge). В лаборатории курса мост br0 и три «компьютера» h1–h3 живут в отдельных сетевых пространствах имён одной ВМ — у каждого свои интерфейсы, адреса и таблицы маршрутов, как у отдельной машины. Как их создать — в задании на портале.
h1 10.0.0.1 h2 10.0.0.2 h3 10.0.0.3
│ │ │
veth-h1 veth-h2 veth-h3
└────────────[ br0 — коммутатор ]─┘
$ sudo ip netns exec h1 ping -c 2 10.0.0.2
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.677 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=0.067 ms
$ sudo bridge -n sw fdb show br br0 | grep -v permanent
be:cb:ca:1e:3c:b0 dev veth-h1 master br0
66:fc:fd:b9:a6:9a dev veth-h2 master br0
72:18:38:91:22:f9 dev veth-h3 master br0
Мост выучил MAC-адреса всех трёх хостов и порты, за которыми они находятся. Записи устаревают через несколько минут без трафика — так коммутатор узнаёт о переставленных кабелях.
Все узлы, до которых доходит широковещательный кадр, образуют широковещательный домен. Коммутатор его не делит — делит маршрутизатор или VLAN. Чем больше домен, тем больше «шума»: сотни компьютеров в одной сети постоянно отправляют широковещательные запросы, которые получает каждый.
Программы знают IP-адрес соседа, а для кадра нужен MAC-адрес. Связь находит протокол ARP: компьютер отправляет широковещательный запрос «у кого адрес 10.0.0.2? ответьте 10.0.0.1», владелец отвечает лично. Ответ кэшируется в таблице соседей.
$ sudo ip netns exec h1 ip neigh # до обмена — пусто
$ sudo ip netns exec h1 ping -c 2 10.0.0.2
$ sudo ip netns exec h1 ip neigh
10.0.0.2 dev eth0 lladdr 66:fc:fd:b9:a6:9a REACHABLE
Запрос ARP видят все узлы сети. Захват на h3, который в разговоре не участвует:
$ sudo ip netns exec h3 tcpdump -i eth0 -nn -e arp
be:cb:ca:1e:3c:b0 > ff:ff:ff:ff:ff:ff, ethertype ARP (0x0806), length 42: Request who-has 10.0.0.2 tell 10.0.0.1, length 28
Запрос — на ff:ff:ff:ff:ff:ff, поэтому дошёл до h3. Ответ h2 — адресный, h3 его не получил: коммутатор отправил его только в порт h1. На своей машине таблица соседей — ip neigh; в ней обычно есть шлюз.
VLAN (виртуальная локальная сеть) делит один физический коммутатор на несколько изолированных. Порты бухгалтерии — в VLAN 10, гостевой Wi-Fi — в VLAN 30: кадры между ними не проходят, как если бы это были разные коммутаторы. Каждая VLAN — свой широковещательный домен и, как правило, своя IP-подсеть. Связь между VLAN — только через маршрутизатор, где её можно ограничить правилами.
Включим в лабораторном мосте фильтрацию VLAN и переведём порт h3 в VLAN 20:
$ sudo bridge -n sw vlan show
port vlan-id
br0 1 PVID Egress Untagged
veth-h1 1 PVID Egress Untagged
veth-h2 1 PVID Egress Untagged
veth-h3 20 PVID Egress Untagged
$ sudo ip netns exec h1 ping -c 2 -W 1 10.0.0.3
--- 10.0.0.3 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1026ms
$ sudo ip netns exec h1 ping -c 1 -W 1 10.0.0.2
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=0.047 ms
Адреса прежние, кабели те же, но h1 больше не видит h3: они в разных VLAN.
| Порт | Кадры | Куда подключают |
|---|---|---|
| Access (в выводе — PVID, Untagged) | Без тега; коммутатор сам относит их к VLAN порта | Компьютеры, принтеры, телефоны |
| Trunk (тегированный) | С тегом 802.1Q — номером VLAN; по одному кабелю идут несколько VLAN | Между коммутаторами, к маршрутизатору, к серверу виртуализации |
Тег 802.1Q — 4 байта, вставленные в кадр после MAC-адресов; 12 бит из них — номер VLAN, отсюда диапазон 1–4094. Linux умеет принимать тегированный трафик через VLAN-интерфейс:
$ sudo ip link add link eth0 name eth0.20 type vlan id 20
$ ip -d link show eth0.20
3: eth0.20@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 ...
vlan protocol 802.1Q id 20 <REORDER_HDR> ...
| Среда | Скорость | Расстояние | Где |
|---|---|---|---|
| Витая пара Cat 5e | 1 Гбит/с | 100 м | Рабочие места |
| Витая пара Cat 6A | 10 Гбит/с | 100 м | Серверные, новые здания |
| Многомодовое оптоволокно | 10–100 Гбит/с | сотни метров | Между этажами, в ЦОД |
| Одномодовое оптоволокно | до 400 Гбит/с | километры | Между зданиями, у провайдеров |
| Wi-Fi 6 (802.11ax) | сотни Мбит/с на клиента | десятки метров | Ноутбуки, телефоны |
Скорость порта и дуплекс в Linux: ethtool ens18. Порт, согласовавшийся на 100 Мбит/с вместо 1 Гбит/с, — частая причина «медленной сети» и признак плохого кабеля.
MTU (Maximum Transmission Unit) — наибольший размер данных, которые помещаются в один кадр. Для Ethernet — 1500 байт. IP-пакет больше MTU придётся дробить или он не пройдёт. Проверить, проходит ли пакет заданного размера без дробления: ping -M do (запретить фрагментацию) и -s — размер данных ICMP. К ним добавятся 28 байт заголовков IP и ICMP:
$ ping -c 1 -M do -s 1472 192.168.116.1
PING 192.168.116.1 (192.168.116.1) 1472(1500) bytes of data.
1480 bytes from 192.168.116.1: icmp_seq=1 ttl=64 time=0.182 ms
$ ping -c 1 -M do -s 1473 192.168.116.1
PING 192.168.116.1 (192.168.116.1) 1473(1501) bytes of data.
ping: sendmsg: Сообщение слишком длинное
1472 + 28 = 1500 — проходит, на байт больше — нет. Туннели (VPN, PPPoE у некоторых провайдеров) добавляют свои заголовки и уменьшают полезный MTU; когда это не учтено, мелкие запросы работают, а большие страницы и файлы «зависают». Разбор такого случая — в модуле 08.
ff:ff:ff:ff:ff:ff — всемip neighping -M do -s 1472