# Linux bridge - программный свитч _Сеть: L2 / L3 · LinuxLab Knowledge Base_ **TL;DR:** Bridge - программный L2-свитч в ядре Linux. Учит MAC в FDB, форвардит фреймы между интерфейсами. Основа Docker default network, KVM bridge, libvirt. С vlan_filtering эмулирует управляемый свитч. ## Что такое 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 ```bash # Создать 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-адреса по тому же принципу, что физический свитч: ```bash $ 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]]: ```bash # Включить 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) обнаруживает петли и блокирует один из портов: ```bash ip link set br0 type bridge stp_state 1 ``` По дефолту в Linux **STP выключен** - не нужен в Docker/KVM где топология известна. На границе с физической сетью включать обязательно. ## Multicast и IGMP-snooping Bridge по дефолту flood'ит multicast во все порты (как broadcast). С IGMP-snooping видит подписки клиентов и шлёт только тем, кто хочет: ```bash ip link set br0 type bridge mcast_snooping 1 ``` Полезно когда в bridge много портов и multicast-трафика (видеостриминг, Avahi, Bonjour). ## Docker bridge - под капотом Что делает Docker при `docker run`: 1. Создаёт пару `veth0a` (в host netns) и `veth0b` (в container netns) 2. `veth0b` переименовывается в `eth0` внутри контейнера 3. `veth0a` подключается в bridge `docker0` 4. На контейнере поднимается IP из подсети `docker0` 5. На 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; для контейнерных сетей часто отключают ## Команды ```bash ip link add br0 type bridge ``` Создать bridge. Современная замена устаревшему 'brctl addbr' ```bash ip link set eth0 master br0 ``` Подключить eth0 как slave-port в br0 ```bash bridge link show ``` Все порты во всех bridge'ах со state (forwarding/blocking) ```bash bridge fdb show br br0 ``` FDB-таблица: какие MAC учены и за каким портом ```bash bridge vlan show ``` VLAN-маркировка на портах vlan-aware bridge'а ```bash ip -d link show br0 ``` -d показывает bridge-параметры: stp_state, vlan_filtering, ageing_time ## См. также - [veth pair](/kb/veth-pair.md) - [MAC address](/kb/mac-address.md) - [VLAN и trunk - 802.1Q](/kb/vlan-and-trunk.md) - [VXLAN - L2 overlay поверх L3-сети](/kb/vxlan-overlay.md) - [eBPF XDP - kernel data-plane](/kb/ebpf-xdp.md) - [CNI plugins - сеть Kubernetes (calico, cilium, flannel)](/kb/cni-plugins.md)