img.png

Когда-то давно общался с коллегой на тему всякого разного и в ходе беседы, он как-то вскользь сказал, “А в линуксе же кроме дефолтного STP ничего не поддерживается, ну вот я и…”.
Дальше уже ничего слышно не было. Как это не поддерживается? GENEVE мы умеем, а MST нет?… на что получил положительный ответ и примечание, что по крайней мере такое было в какой-то относительно свежей версии Debian.

Короче, решил покопаться сам, почему-то мне казалось, что это де-факто стандарт и такое должно там быть.

Ну и покопался, вот мои копания в виде статейки. Добро пожаловать под кат.


Справка. Что такое MST.

MST (или multiple spanning tree protocol) - это вариант привычного всеми spanning tree, только чуть поинтереснее. Можно собирать более сложную конструкцию, к тому же это открытый стандарт, поддерживается многими.

Вот тут ещё можно что-то почитать - xgu.ru

Ну и как вариант, посмотреть видосы Иннокентия, там норм - https://www.networkeducation.ru/video/view/cisco-switch-2-1/mst

В общем такая штука, которая позволяет нам избежать петель внутри никому не нужного L2. Удобная и иногда всё-таки нужная.


Первый взгляд на проблему.

Сначала пошёл гуглить. Просто искать STP в Linux.
Выяснилось следующее, в Linux действительное долгое время не было никакой поддержки ничего, кроме ванильного STP 802.1d.

Хм, прикол конечно. На всяких NOS есть же MST, а там ведь Linux…
Оказалось, что все они используют какие-то опенсорсные проекты.

Вот что я нашёл в порядке очередности:

  1. https://github.com/mstpd/mstpd - именно она фигурирует в различных популярных сетевых штуках, типа OcNOS, Cumulus Linux и т.д.
  2. https://github.com/adigostin/mstp-lib - ещё одна самописная библиотека для поддержки MST, где применяется не нашёл, но и не искал особо.

Возможно, есть что-то ещё, но я уже не стал копаться.

На самом деле тут статью можно было бы закончить, т.к. mstpd более чем покрывает все запросы, но нет :)

Так, ну это всё не родное же. Т.е. в ядре по умолчанию не будет. Всё равно ощущения странного не покидает, продолжил поиск…

Не буду расписывать гугления, MST нашёлся.

Вот тут - https://lore.kernel.org/netdev/20220323180738.3978487-1-kuba@kernel.org/.

Поддержку добавили в 2022 году.

Не знаю как вы, а я люто кайфанул. Нашлось же, вот оно, поддерживается. Всего-то надо, чтобы ядро было версии 5.18 и выше.

Думаете на этом всё? Хых. Увы. Идём дальше.


Первые попытки использования MST в Linux

Естественно, когда я узнал что и как, решил сразу идти и пробовать.
Ссылка выше говорит, что MST добавлено в 5.18, т.е. всё что выше будет поддерживать. Плюс, т.к. это модуль внутри пакета iproute2, то нужно чтобы и он был актуальной версии, начиная с 6.1.0.

Скачал последнюю версию Ubuntu, поставил и смотрю…

> root@localhost:~# uname -a  
> Linux localhost.localdomain 6.13.6-200.fc41.x86_64 #1 SMP PREEMPT_DYNAMIC Fri Mar  7 21:33:48 UTC 2025 x86_64 GNU/Linux  
> root@localhost:~#  
> root@localhost:~# ip -V 
> ip utility, iproute2-6.13.0   
> root@localhost:~# 

Все версии выше требуемых, должно работать. Однако, если ввести “bridge mst”, то вот что получаем:

> root@localhost:~# bridge mst  
Object "mst" is unknown, try "bridge help".  
root@localhost:~#   

Не поддерживается в общем.

Странно, вроде всё должно быть, но нет. Ладно, подумал может дело в самой сборке, ну типа Ubuntu не для этого и попробовать нужно что-то более серверное - Debian.

Поставил Debian 12 и смотрю что там. В общем там тоже самое. Uname говорит, что версия ядра 6.1, меньше, чем в Ubuntu, но больше, чем требуется. Плюс для нас важно, чтобы именно пакет iproute2 был актуальной версии, а они что на убунте, что на дебиане правильные.

Интересно, должно же быть, а нет…

Не буду в общем вас мучать. Скажу сразу, правдами и неправдами, дипсиками и дикпиками, но всплыла дефолтная база любого линукса, которая гласит:

“В линукс, вы можете настроить всё что угодно :)

И ВЫ БЛЯТЬ БУДЕТЕ ЭТО НАСТРАИВАТЬ!…

Ну в общем, тут тоже самое…

  • версия kernel актуальная? да, актуальная.
  • iproute2 стоит актуальный? да, актуальный.
  • А mst в нём нет? Нет, в нём mst нет.
  • А если смотреть сорсы, то там есть mst? да, есть.

кажется вы уже поняли что к чему…


Попытка пересобрать ядро с включенным MST…

В общем, добавить то MST добавили, но в сборках ядра его нет. Поэтому первым вариантом в голову пришла попытка пересобрать ядро,

благо чатыгпт и дипсики под рукой, можно ими пытаться что-то делать, хоть и с трудом…

В целом процесс не сложный, опишу его на всякий, больше для себя, чтобы в будущем не забыть..

Ставим нужные пакеты, они понадобятся потом при сборке. Я их сначала не поставил и добирал по мере ошибок, ну сейчас уже не будем это проходить и сразу все поставим:

> apt install git build-essential libncurses-dev bison flex libssl-dev

Дальше берём исходники. В них к слову я на всякий случай проверил и нашёл нужный пакет (https://web.git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/net/bridge/br_mst.c)

>git clone --depth 1 --branch master https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git

После этого, идём в созданную директорию и запускаем процесс сборки:

>cd linux/    
>make menuconfig   

Будет вот такое меню: img.png

Честно говоря, в какой-то момент возникло ощущение, что мне снова 10 лет и я ставлю свой первый red hat… даже ради него стоило это всё пройти…

В общем в меню идём по шагам - Networking support > Networking Options > “ищём что-то на тему 802.1s или MST или Multiple Spanning Tree…”

img.png

Как видите ничего нет.

Было грустно.

Очень грустно. Я уже думал что вот, но нет, не вот.

Ладно, похер. Го дальше.


Попытка установить только MST из сорсов…

На всякий опять опишу все шаги.

Как я уже говорил, MST включен внутрь пакета iproute, так что его и будем клонировать:

>git clone git://git.kernel.org/pub/scm/network/iproute2/iproute2.git  
> cd iproute2

Собираем конфиг:

> ./configure

Ок, Makefile готов, можно продолжать:

> make

Собрали, осталось установить:

> make install

Done.

Проверяем.

> root@debian-1:/usr/src/linux# bridge help  
Usage: bridge [ OPTIONS ] OBJECT { COMMAND | help }  
       bridge [ -force ] -batch filename  
where  OBJECT := { link | fdb | mdb | mst | vlan | vni | monitor }  
       OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] |  
                    -o[neline] | -t[imestamp] | -n[etns] name |  
                    -com[pressvlans] -c[olor] -p[retty] -j[son] }  
root@debian-1:/usr/src/linux# 
root@debian-1:/usr/src/linux# 

Че. MST появился? Да ну нахер.

>root@debian-1:/usr/src/linux# bridge mst show    
>port              msti    
>root@debian-1:/usr/src/linux#     

Правда появился…

img.png

Тут уровень дофамина практически дошёл до пика и я думал, что всё, на этом надо заканчивать. Но противный голос внутри, сказал “так хули ты его только включил, может он не работает… хых”

Ну да, спорить было сложно…


Попытка настройки и проверки MST

Дальше не буду писать всю боль, потому что её было много. Напишу только последовательность действий.

Т.к. речь идёт по spanning tree, то нужен бридж. Делаем:

> ip link add name br0 type bridge  
> ip link set br0 up 

Чтоб удобней сидеть на нём, поднял там IP

> ip addr add 192.168.50.77/24 dev br0

который к слову не работал, пока я не поправил MAC руками на аналогичный тому, который у меня на основном интерфейсе…:

> ip link set dev br0 address 08:00:27:bd:17:b0 

После этого добавил физический интерфейс в наш бридж:

> ip link set enp0s3 master br0

На этом этапе всё поднялось и уже стал доступен br0 через ssh, поэтому IP с основного можно убирать:

> ip addr del 192.168.50.76/24 dev enp0s3

Ну и на последок добавляем дефолт, а вдруг…

> ip route add default via 192.168.50.1 dev br0  

Чистим ARP и проверяем:

>ip neigh flush all    
> ip neig    
192.168.50.1 dev br0 lladdr 08:bf:b8:e7:4c:3c STALE     

Ну ок, бридж готов.

На всякий проверим:

>root@debian-1:/usr/src/linux# bridge link show    
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master br0 state forwarding priority 32 cost 5   

Проверяем статусы STP и MST:

> root@debian-1:~# ip -j -p -d link show br0 | grep -E 'stp|mst'>  
>"stp_state": 0,  
> "mst_enabled": 0,  
root@debian-1:~# 

0 - всё выключено. Ок, не вопрос, включаем:

>root@debian-1:~#  
>root@debian-1:~# ip link set br0 type bridge stp_state 1 
>root@debian-1:~# ip link set br0 type bridge mst_enabled 1 
>root@debian-1:~# 

Проверяем:

>root@debian-1:~#    
>root@debian-1:~# ip -j -p -d link show br0 | grep -E 'stp|mst'   
                "stp_state": 1,   
                "mst_enabled": 1,   
> root@debian-1:~#    

Включилось.

Дальше посмотрим что у нас с настройками MST.

>root@debian-1:/usr/src/linux# bridge mst show  
>port              msti      

ничего не поменялось. Настроим немного..:

> bridge mst set dev enp0s3 msti 0 state forwarding

Проверяем:

>root@debian-1:/usr/src/linux# bridge mst show  
>port              msti       
>enp0s3            0  
>                  state forwarding  
>root@debian-1:~#   

Опа, работает.

Пойдём смотреть что же он там отправляет…

img.png

Мде. не густо. Всё тот же STP…

Ну а может оно просто не работает, когда один интерфейс и то физический?

Ок, пробуем дальше.

Создаём ещё 2 интерфейса, уже сабы к основному, но с тегами:

>ip link add link enp0s3 name enp0s3.10 type vlan id 10     
>ip link add link enp0s3 name enp0s3.20 type vlan id 20   

Не забываем включить:

>ip link set enp0s3.10 up  
>ip link set enp0s3.20 up  

Привязываем к бриджу:

>ip link set enp0s3.10 master br0  
>ip link set enp0s3.20 master br0  

Добавляем их в другие инстансы:

>bridge mst set dev enp0s3.10 msti 1 state forwarding
>bridge mst set dev enp0s3.20 msti 2 state forwarding

Настраиваем новые интерфейсы + влан внутри бриджа:

>bridge vlan add dev enp0s3.10 vid 10 pvid untagged      
>bridge vlan add dev enp0s3.20 vid 20 pvid untagged   
>bridge vlan global set vid 10 dev enp0s3.10 msti 1    
>bridge vlan global set vid 20 dev enp0s3.20 msti 2    

Ну уже почти всё…

Включаем MST на наших новых интерфейсах:

>bridge mst set dev enp0s3.10 msti 1 state forwarding  
>bridge mst set dev enp0s3.20 msti 2 state forwarding 

Вроде всё. Проверяем:

root@debian-1:/usr/src/linux# 
root@debian-1:/usr/src/linux# bridge mst show  
port              msti  
enp0s3          0    
                    state forwarding  
enp0s3.10       1  
                    state forwarding   
enp0s3.20       2  
                    state forwarding   
root@debian-1:/usr/src/linux#   
root@debian-1:/usr/src/linux#   

Отлично, вроде как всё поднято и должно работать. Пошли дампить трафик…

img.png

Из приятного, теги есть и пакетов действительно стало в 3 раза больше.

Но увы, MST нет. Это всё тот же самый, STP, разве что вот с dot1q тегами сверху…


Вместо заключения.

В общем, как вы поняли, не работает MST пока что. То есть что-то есть, да. И оно будто бы лучше, чем простой STP, по крайней мере вон dot1q поддерживает. Но того, что я ожидал, увы, нет. По крайней мере у меня не получилось.

Как я понял, то эта ветка всё ещё находится в разработке и последний комментарий и апдейт был в июле 2024 года - https://lore.kernel.org/netdev/172047843191.22736.1376042190239326743.git-patchwork-notify@kernel.org/, тогда добавили какие-то основные функции, часть из которых я использовал выше. Вполне возможно, в будущем всё это разовьётся до какого-то полноценного состояния. Пока что, смело можете сразу ставить пакеты, которые были указаны в самом начале статьи, а именно mstpd - другого адекватного варианта для Linux на данный момент нет.

Не знаю, возможно когда-то ещё раз вернусь и покопаюсь дальше, но пока что гештальт закрыт и в целом я неплохо провёл время :)

Надеюсь вы тоже :)

Подписывайтесь на канал!