Два LTE модема на одном linux'е

May 27, 2021 13:24

Столкнулся с неожиданной сложностью (проблемой называть язык не поворачивается). Понадобилось в офисный гейт на Ubuntu воткнуть два LTE модема HUAWEI E3372 (HILINK-прошивка). В компе они представляются как виртуальные ethernet'ы и, по умолчанию, ubuntu их не может различить. В результате, первый (после отработки modewsitch опознается как eth..., а второй как девайс со звучным назвнием rename1...7. Просмотрев тему посвященную этим модемам на 4PDA (по диагонали, конечно), с удивлением  понял, что на вопросы такого сорта есть два ответа: "...в чем проблема, у меня все работает" и "...это невозможно, перешивайте в STICK".
Т.к. поиск решения занял некоторое время, решил записать. Может кому еще пригодится.

Итак, дано:
  • Гейт на Ubuntu 18.04.5 ( то же самое и на 20-ке). Смотрит обычными ethernet'ами в локалку и в провайдера.
  • Два "мегафоноских" модема (Huawei E3372h-153) с прошивкой HILINK.
  • Обычно компы из локалки ходят в основного провайдера, но в определенных ситуациях должны заворачиваться в определенный модем.

Вопрос превращения mass-storage девайса, которым модем исходно прикидывается для системы, в cdc_ether оставляю за скобками. В кратце. Когда udev видит этот девайс (например, idVendor=12d1, idProduct=1f01) он, в соответствии с правилами из /lib/udev/rules.d/40-usb_modeswitch.rules запускает usb_modeswitch, который переключает его композицию в idVendor=12d1, idProduct=14dc. Подробности деятельности modeswitch легко гуглятся. Например, тут.

Вообще, в зависимости от того, что записано в NVRAM девайса, он может подсвечивать на usb разные end-point'ы. На слэнге PDA'шников это называется "композиция". Эта тема хорошо раскрыта на 4ЗВФ, например, здесь. С поправкой на то, что там написано, как это делать через АТ-команды. Если модем уже в cdc режиме, то можно зайти на него телнетом и давать эти команды с помощью програмки аtc, которая сейчас уже входит в состав hilink-прошивок. Соответственно, можно и залочить удобную композицию. Я собираюсь залочить в cdc + компандный tty. Сделаю, опишу здесь досконально.

Дальше, на usb появляется новый девайс, который, обычно, обрабатывается тем же udev. Уже не помню откуда у меня в /etc/udev/rules.d/70-persistent-net.rules взялось правило:

SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="0c:5b:8f:27:9a:64", ATTR{dev_id}=="0x0",ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"

Давно я подключал первый модем. Это очень распространенный в инете совет на вопрос: "как дать модему нормальное имя?", но он цепляется за MAC=0c:5b:8f:27:9a:64 и, т.к. этот псевдо-мас у всех модемов будет одинаковым, то udev и не понимает как ему назвать второй модем и мягко намекает, что его хорошо бы переименовать.

Однако, откуда-то, у меня в подкорке, сидело воспоминание, что в правилах udev можно использовать не только атрибуты данного конкретного девайса, но и атрибуты его парентов. Соответственно, решил попробовать использовать номер порта usb. Опять же, не буду вдаваться в хорошо описанные подробности. Хороший русскоязычный текст есть тут . С поправкой, что в ubuntu надо писать не "udevinfo", а "udevadm info ..." . Например:

udevadm info -a -p /sys/bus/usb/devices/2-1:1.0
Пошарившись т.о. по шине, я определил как выглядят номера отдельных портов usb моего гейта. Наверное, можно было просто заглянуть в dmesg, но мне было интересно. Соответственно, породил два новых правила, которые легли в /etc/udev/rules.d/70-persistent-net.rules :

SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="0c:5b:8f:27:9a:64", ATTR{dev_id}=="0x0",ATTR{type}=="1", KERNEL=="eth*", SUBSYSTEMS=="usb", KERNELS=="1-2:1.0", NAME="eth4"
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="0c:5b:8f:27:9a:64", ATTR{dev_id}=="0x0",ATTR{type}=="1", KERNEL=="eth*", SUBSYSTEMS=="usb", KERNELS=="2-1:1.0", NAME="eth5"

Старое закомментил.

#SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="0c:5b:8f:27:9a:64", ATTR{dev_id}=="0x0",ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"
В принципе, его можно и оставить. Только ставить его надо (наверное) не в конце, а в начале файла, т.к. udev это не iptables и правила выполняет все. Этот ляп стоил мне немного головной боли потому, что даже при двух новых правилах девайс все равно назывался eth0. Кстати, еще немного седых волос добавилось по очень простой причине. Один и тот же usb-hub не тянул оба модема на марше. Один из них отрубался. Пришлось переткунть.

Еще немного головной боли было со сменой ip-шника модема. Он по дефолту - 192.168.8.1 . Причем маску сети у него через web-морду не поменять. Наверное, можно было залезть в его nvram, но мне стало лень. Соответственно, сменил его на первый попавшийся - 192.168.18.1. WEB-морда при этом жалостно кричит, что модем сейчас будет сломан. Почему она так думает - фиг знает.
Ну и немного о роутинге.
В данном случае - простейший вариант это source-роутинг. Два конкретных компа выводятся каждый в свой свисток. Понятно, что ради этого не надо было мучить гейт, но это демка. В /etc/network/interfaces прописал:

auto eth4
allow-hotplug eth4
iface eth4 inet static
address 192.168.8.2
netmask 255.255.255.0
network 192.168.8.0
broadcast 192.168.8.255
post-up /sbin/ip ro add default via 192.168.8.1 dev eth4 table mega
post-up /sbin/ip ru add from 192.168.33.43/32 table mega

auto eth5
allow-hotplug eth5
iface eth5 inet static
address 192.168.18.2
netmask 255.255.255.0
network 192.168.18.0
broadcast 192.168.18.255
post-up /sbin/ip ro add default via 192.168.18.1 dev eth5 table mega2
post-up /sbin/ip ru add from 192.168.33.159/32 table mega2

Соответственно, стал выглядеть и /etc/iproute2/rt_tables:

# reserved values
255 local
254 main
253 default
0 unspec
#
# local
#
100 mega
101 mega2

Ну и, естественно, /etc/iptables/rules.v4

-A POSTROUTING -s 192.168.33.0/24 -o eth4 -j SNAT --to-source 192.168.8.2
-A POSTROUTING -s 192.168.33.0/24 -o eth5 -j SNAT --to-source 192.168.18.2

linux

Previous post Next post
Up