Что такое bridge
Bridge ведёт себя как L2-свитч - принимает [[ethernet-frame|Ethernet фреймы]] на одном порту, смотрит dst-MAC, ищет в FDB (forwarding DB) и отправляет на нужный порт. Если MAC не известен - flood'ит во все порты кроме источника.
В отличие от роутинга (L3) - bridge не меняет адреса в пакете, не смотрит IP. Это прозрачный L2-форвардинг.
Зачем нужен в Linux
- Docker - сетевой драйвер
bridgeсоздаётdocker0и подключает контейнеры через [[veth-pair|veth-пары]] - KVM/libvirt - VM имеют tap-интерфейсы, подключённые в bridge
- VLAN-aware bridge - заменяет полноценный управляемый свитч в программных дата-центрах
- Container labs (containerlab, mininet) - изолированные топологии
- Network namespaces - связь между netns делается через bridge + veth
Создание bridge
# Создать
ip link add br0 type bridge
ip link set br0 up
# Добавить интерфейсы
ip link set eth0 master br0
ip link set eth1 master br0
# IP на самом bridge (для управления)
ip addr add 192.168.1.1/24 dev br0
После этого eth0 и eth1 становятся slave-портами: их
собственные IP-адреса теряют смысл, всё работает через br0.
FDB - forwarding database
Bridge учит MAC-адреса по тому же принципу, что физический свитч:
$ bridge fdb show
aa:bb:cc:11:22:33 dev eth0 master br0
aa:bb:cc:44:55:66 dev eth1 master br0
33:33:00:00:00:01 dev br0 self permanent
Записи бывают:
- dynamic - выученные из проходящего трафика, протухают через
300с (
bridge_fdb_aging) - static - добавленные руками или приложением, не протухают
- permanent - системные (multicast, локальный MAC)
VLAN-aware bridge
Старый bridge - один [[broadcast-domain|broadcast-домен]]. Новый
с vlan_filtering=1 ведёт себя как управляемый свитч с
[[vlan-and-trunk|VLAN]]:
# Включить VLAN
ip link set br0 type bridge vlan_filtering 1
# eth0 - access port в VLAN 10
bridge vlan add dev eth0 vid 10 pvid untagged
bridge vlan del dev eth0 vid 1
# eth1 - trunk с VLAN 10 и 20
bridge vlan add dev eth1 vid 10 tagged
bridge vlan add dev eth1 vid 20 tagged
# Проверить
bridge vlan show
Один bridge = много VLAN'ов и портов разного типа.
STP - Spanning Tree Protocol
Если bridge замкнётся в петлю (два bridge соединены в обе стороны) - broadcast'ы будут циркулировать вечно, сеть умрёт. STP (802.1D) обнаруживает петли и блокирует один из портов:
ip link set br0 type bridge stp_state 1
По дефолту в Linux STP выключен - не нужен в Docker/KVM где топология известна. На границе с физической сетью включать обязательно.
Multicast и IGMP-snooping
Bridge по дефолту flood'ит multicast во все порты (как broadcast). С IGMP-snooping видит подписки клиентов и шлёт только тем, кто хочет:
ip link set br0 type bridge mcast_snooping 1
Полезно когда в bridge много портов и multicast-трафика (видеостриминг, Avahi, Bonjour).
Docker bridge - под капотом
Что делает Docker при docker run:
- Создаёт пару
veth0a(в host netns) иveth0b(в container netns) veth0bпереименовывается вeth0внутри контейнераveth0aподключается в bridgedocker0- На контейнере поднимается IP из подсети
docker0 - На host'е iptables-правило для NAT исходящего трафика
Это даёт контейнерам L2-связность между собой (через docker0) и
L3-связность наружу (через NAT).
OVS - альтернатива
Open vSwitch - продвинутая замена Linux-bridge: OpenFlow,
per-port QoS, более тонкий VLAN-контроль. Ставится отдельно
(apt install openvswitch-switch). На простых задачах vanilla bridge
дешевле и проще.
Когда что-то пошло не так
- Контейнеры не пингуют друг друга - проверь что оба интерфейса
master br0, иbridge fdbвидит их MAC - Slow performance - убедись что MTU одинаков на bridge и slave'ах
- Multicast тормозит - включи
mcast_snooping - Сеть полегла после connect двух bridge - петля, включи STP
- VLAN не работает - забыл
vlan_filtering=1на bridge или PVID не совпадает на портах net.bridge.bridge-nf-call-iptables=1нагружает CPU - bridge проксирует трафик в iptables; для контейнерных сетей часто отключают