tgoop.com/life_of_network_engineer/154
Create:
Last Update:
Last Update:
Поразбирался с l3mdev.
Продолжение предыдущего поста
L3mdev (Layer 3 Master Device) - это механизм в ядре Linux, который обеспечивает поддержку VRF, т.е. основное назначение l3mdev - это изоляция таблиц маршрутизации.
В контексте l3mdev есть два вида устройств(devices):
1️⃣ Master - это собственно и есть VRF. Пример: создаем VRF ip link add dev vrf-mgmt type vrf table 101, где vrf-mgmt и будет мастер устройством.
2️⃣ Slave - устройство, которое «подчинено» мастеру, т.е. сетевой интерфейс, привязанный к VRF. Пример: ip link set dev eth0 master vrf-mgmt, где eth0 - slave
У каждого сетевого интерфейса есть индекс, который можно посмотреть с помощью команды ip link show.
Вывод сокращен:
1: lo: <LOOPBACK,UP,LOWER_UP>
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> master vrf-mgmt state UP
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> state UP
4: vrf-mgmt: <NOARP,MASTER,UP,LOWER_UP> state UP
[1-4] - это индексы, при этом в зависимости от направления они могут быть:
Задача l3mdev сводится к тому, чтобы перенаправить сетевые интерфейсы на L3 мастер-устройство для маршрутизации через правильную таблицу. То есть он меняет oif или iif со slave-устройства на master-устройство.
На примере нашего конфига netplan это работает так:
Пакет -> eth0(slave) -> 3lmdev делает update iif -> vrf-mgmt(master) -> table 101
Чтобы l3mdev мог заменять iif/oif на master (VRF), используется специальная таблица, которая создается автоматически при создании VRF - [l3mdev-table].
Команда для просмотра правил маршрутизации: ip rule show
Вывод:
0: from all lookup local
1000: from all lookup [l3mdev-table] <— вот она
32765: from 10.10.8.101/23 lookup main proto static
32766: from all lookup main
32767: from all lookup default
Числа слева - это приоритеты, возможный диапазон от 0 до 32767. Чем меньше число, тем выше приоритет. Задача l3mdev-table - динамически указывать на правильную таблицу VRF на основе сетевого интерфейса (iif или oif).
Как это работает:
Приходит пакет
↓
Приоритет 0: lookup local
↓
Приоритет 1000: lookup [l3mdev-table]
Вот тут начинает работать l3mdev
1. Определяет интерфейс (iif/oif) исходя из флоу трафика
2. Проверяет принадлежит ли интерфейс VRF
3. Определяет ID таблицы VRF и перенаправляет в нее
↓
Приоритет 32765: from 10.10.8.101/23 lookup main
↓
Приоритет 32766: lookup main
↓
Приоритет 32767: lookup default
И посмотрим, где l3mdev находится в сетевом стеке(упрощенно):
1️⃣ Пакет из сети попадает на сетевую карточку, далее в драйвер сетевой карты
2️⃣ Ядро создает skb (socket buffer), проверяет пакет на валидность, заголовки и тд.
3️⃣ Любой входящий трафик запускает хук Netfiler - NF_IP_PRE_ROUTING (обрабатывается до принятия решения о том, куда отправлять пакет). Про Netfilter и хуки можно почитать тут. Происходит первый поиск в RIB - проверяется принадлежит ли dst IP локальному интерфейсу.
4️⃣ Хук l3mdev_l3_rcv меняет skb->dev(eth0) на vrf-mgmt
5️⃣ На основе нового skb->dev происходит повторный поиск в RIB в VRF
6️⃣ И если пакет предназначен локальному хосту, вызывается хук NF_INET_LOCAL_IN и передается приложению.
Обработка исходящих пакетов по своей сути похожа, но будут вызываться разные хуки Netfiler и l3mdev.
Стоит отметить, что l3mdev никак не влияет на L2-трафик.
Из необычного, статистика по интерфейсу vrf-mgmt будет выглядеть так:
vrf-mgmt: flags=1217<UP,RUNNING,NOARP,MASTER> mtu 65575
ether 22:20:a7:a8:7f:f8 txqueuelen 1000 (Ethernet)
RX packets 36707747 bytes 26433447694 (26.4 GB)
TX packets 0 bytes 0 (0.0 B)
Счетчик TX на интерфейсе vrf-mgmt всегда равен 0.
Свою версию, почему так происходит, я напишу в следующем посте. Если у вас есть свои идеи или вы считаете, что в моих рассуждениях выше есть неточности, то можем обсудить в комментах.
——————————————
Документ с описанием: What is an L3 Master Device?
Нашел еще доклад + презу