С wpa_supplicant из GIT теперь можно настроить в Linux прозрачную миграцию, позволяющую переключиться на другую точку доступа без разрыва соединений приложений, в том числе продолжается вещание мультикастовоего IPTV, а выполнение iperf в большинстве случаев не умирает, а лишь деградирует по скорости в момент миграции. При этом даже корректно отрабатывает вариант с несколькими AP в разных поддиапазонах 5ГГц.Для настройки роуминга потребуется (на примере Mageia Linux 5):
1) wpa_supplicant из git. Можно взять подготовленный автором src.rpm
wget http://wive-ng.sf.net/downloads/wpa_supplicant-2.6-1.mga5.sr...
и собрать командой
rpmbuild --rebuild wpa_supplicant-2.6-1.mga5.src.rpm
2) переключить его на использование nl80211 вместо wext, драйвер вашего wifi-модуля должен полностью поддерживать nl80211 (при использовании wext всегда будут долгие периоды реконнекта с потерей соединений пользовательских приложений) так как требуется, чтобы SME был на уровне wpa_supplicant.
Большинство дистрибутивов по умолчанию использует WEXT, т.е. до сих пор далеко не все драйверы wifi, даже входящие в состав ядра, умеют nl80211 (iwlwifi точно умеют, ath*k тоже должны, в rt28xxx по факту даже сканирование не работает). Проверить, что используется на данный момент, можно, посмотрев, с какими опциями запущен supplicant
ps ax | grep wpa_supplicant
должен выдать что-то типа
25201 ? Ss 0:01 /usr/sbin/wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant.conf -D nl80211 -f /var/log/wpa_supplicant.log
Для этого редактируем /etc/sysconfig/network-scripts/ifcfg-имя_интерфейса
Важно установить:
WIRELESS_WPA_DRIVER=nl80211
WIRELESS_WPA_REASSOCIATE=no
MII_NOT_SUPPORTED=yes
USERCTL=yes
В /etc/wpa_supplicant.conf везде отключаем рандомизацию MAC. Включаем фоновое сканирование:
bgscan="simple:30:-60:200"
Т.е. при уровне ниже -60 будем начинать время от времени "щупать эфир" на предмет наличия кандидатов для миграции и по возможности мигрировать. Вместо фонового сканирования можно было бы использовать данные из RRM, но этой логики в wpa_supplicant пока нет.
Также следует обратить внимание на используемый DHCP-клиент. Важно, чтобы он не сбрасывал адрес на интерфейсе (иначе сбросится состояние соединений приложений) по сигналу от ifplugd. Я использую штатный "
"Internet Systems Consortium DHCP Client 4.3.3-P1". Ну и естественно, точки доступа и опорная сеть должны нормально отрабатывать ситуацию с перемещением клиентов.
В прошивке Wive-NG для этого сделано абсолютно всё, что возможно. Больше ничего не требуется. Проверено на адаптерах Intel I3160/I7260. Выпинывать их принудительно не надо - оно само инициирует переход без всяких проблем. Под Windows эти карты ведут себя аналогично, т.е. без проблем мигрируют с сохранением пользовательских соединений, достаточно лишь в настройках драйвера увеличить агрессивность роуминга.
++ Настройка миграции Android-устройств с беспроводными чипами от Atheros/Qualcomm.
Достаточно давно atheros/qualcomm добавили в свои драйверы вполне внятную логику handover (миграции внутри плоской L2 сети, с точки зрения клиента, с множественными AP, на которых установлен один SSID). Собственно, тот самый роуминг, да ещё и бесшовный (ну если используемые AP не совсем плохи и умеют моментально передавать в опорную сеть критичные данные, например, ARP-ы для обновления ARP-таблиц на устройствах в сети + ещё ряд условий на тему кривости).
Теперь о проблеме. Handover есть, сеть с нормальными AP есть, но чтобы клиент мигрировал, по-прежнему требуется пинок, иначе висит до последнего... Что делать и кто виноват?
Для продолжения нужно само устройство, обязательно рутованное, обязательно использующее радио на чипе qualcomm (например yota phone 2).
Перемонтируем разделы в RW, идём в /system/etc/wifi, видим там файл WCNSS_qcom_cfg.ini - собственно, это основной конфигурационный файл, читаемый драйвером wifi.
Драйверы QCA сами реализуют слои SME/MLME, не экспортируя эти функции на плечи wpa_supplicant. И вся логика управления подключениями и миграцией возложена на них. Wpa_supplicant в Android собран с NO_ROAMING, а значит можно ожидать, что это сделано так же у всех абсолютно чипмэйкеров для Android (файлы конфигурации, естественно, разные, или же, как у Broadcom, интересующие нас параметры к исправлению задаются при компиляции, и изменить их на лету невозможно).
Первая настройка, которая нас будет интересовать в файле конфигурации, это:
# default value of this parameter is zero to enable dynamic threshold allocation
# to set static roming threshold uncomment below parameter and set vaule
gNeighborLookupThreshold=78
Эта настройка напрямую отвечает за то, когда клиент начнёт пытаться искать кандидата (форсирует сканирование, или запросит список ближайших AP по RRM и проведёт короткую процедуру скана для подтверждения). И значение у нас выставлено -78дБ...
И вроде бы всё хорошо, но... Мы как обычно забыли, что то, что слышит клиент и то, что слышит AP, может отличаться по уровню на десятки дБ. Обычно в android-клиентах передатчик в 20МГц полосе может выдать 16дБм, в 40МГц в лучшем случае 14дБм. Тогда как со стороны AP обычно имеем как минимум 20дБм дури даже в 40МГц полосе (обычно определяется законодательными ограничениями конкретной страны, для РФ 20дБм в 2.4ГГц и 23дБм в 5ГГц независимо от ширины, хоть в 80МГц эти 23дБм, хоть в 20МГц). Из опыта, при таком раскладе в среднем перекос по уровням в прямой видимости уже в 10 метрах будет составлять около 10-15 Дб, а если есть преграды, то запросто перевалит и за 30 Дб.
Но возьмём 10дБ для простоты. Т.е. когда клиент видит AP с уровнем в -78дБ, AP видит клиента уже с уровнем около -88дБ. Стоит говорить, что нормальной работы при таком раскладе уже не будет (особенно в 2.4ГГц в зашумленном эфире офиса)? TCP, требующий подтверждения доставки, просто встанет колом, голос начнёт квакать и т.д.
Что бы этого избежать (плюс приземлить побольше клиентов, ведь для этого надо заставить всех работать на самой ближней AP, желательно с максимальными рэйтами и без повторов передачи), админ в сети наверняка на AP настроил handoff с уровнем эдак в -75дБ. Т.е. при -75дБ RSSI handoff со стороны AP застрелит такого клиента (при этом на клиенте уровень от AP будет аж -65дБ, т.е. далеко до заветных -78дБ, когда он решит подумать мигрировать). Т.е. будет link beat, сброс стэйтов и обрыв соединений на пользовательской стороне.
Ещё пример - когда AP видит клиента с уровнем в -75дБ, клиент видит AP с уровнем -65дБ!! Или, когда на клиенте видим -78дБ, то со стороны AP клиент будет слышен лишь с уровнем -88дБ.
Т.е. что бы обеспечить нормальный сервис, мы должны отстреливать клиента сильно раньше, чем он сам подумает мигрировать (имеется в виду, с вышеозначенными умолчаниями в драйвере).
Или же нам придётся снижать мощность на AP что бы "уравнять" шансы, что в условиях грязного эфира может привести к катастрофическому падению SNR и как следствие бульканью, хрипам и прочему.
А вот чтобы этого не происходило, достаточно выше обозначенную переменную поправить, выставив значение в диапазоне -65 ~ -70дБ.
Побочный эффект - чуть упадёт скорость у клиента, так как чаще будет выполняться фоновые сканирования, плюс незначительно вырастет энергопотребление. Зато у него "будет повод" начать смотреть, кто есть вокруг, и попытаться мигрировать, не дожидаясь, пока его выпнет точка доступа.
Следующий блок:
# CCX Support and fast transition
CcxEnabled=0
FastTransitionEnabled=1
CcxEnabled - это поддержка rrm ccx location-measurement, т.е. определения местоположения. Зачастую бесполезна и лишь будет расходовать аккумулятор.
FastTransitionEnabled - поддержка 802.11R, однако в старых драйверах не полная, но хотя бы умеет учитывать MDIE при миграции (работает всегда, если переменная в значении 1). Заметим, что FT, а именно ускорение фазы аутентификации просто при взводе значения переменной в 1 работать не начнёт, так как требуется ещё пропатчить Supplicant и обвязку андроидную (как это делает, например, Samsung в своих топовых моделях). Однако, учёт MDIE - уже польза. Включаем.
Не забываем также отключить 802.11d, иначе встретим много чудес в 5ГГц с DFS каналами. Пусть использование или не использование оных лежит на совести админа сети.
# 802.11d support
g11dSupportEnabled=0
Далее блок:
# Legacy (non-CCX, non-802.11r) Fast Roaming Support
# To enable, set FastRoamEnabled=1
# To disable, set FastRoamEnabled=0
FastRoamEnabled=1
Включает возможность миграции в любых сетях. Иначе, логика handover будет активироваться, только если клиент видит, что AP вещает поддержку 802.11R в IECAP. И/или используется WPA*-Enterprise.
В новых драйверах, поставляемых в SDK для Android 6.0.1, добавлена ещё одна прекрасная опция:
# Handoff Enable(1) Disable(0)
gEnableHandoff=0
Эта опция (если выставить в 1) позволяет обрабатывать handoff с пинком со стороны AP как сигнал к миграции, т.е. банально не генерируется LinkBeat при kickout со стороны AP, а сразу выполняется попытка перескочить на следующую подходящую выбранную сканом AP, и только если не получилось сгенерировать Link Beat системе (т.е. о том, что его выпнули, знает только драйвер, и сразу пытается мигрировать, если не получается, то тогда уже сообщает системе, что всё, связи с этой сетью больше нет, надо выбрать другой SSID из тех, которые знает Android).
Пользовательские соединения при этом останутся целыми (ну разве что iperf пострадает, но мессенджеры и голос останутся работать, правда в случае голоса будет квак).
Это слегка нарушает "стандарт" 802.11, но в случае миграции очень полезная штука. После её включения, устройство прозрачно (с точки зрения запущенных приложений) сможет мигрировать даже в сетях, где весь роуминг построен исключительно на отстрелах клиента по уровню.
А вот ещё одна крайне полезная настройка:
#Check if the AP to which we are roaming is better than current AP in terms of RSSI.
#Checking is disabled if set to Zero.Otherwise it will use this value as to how better
#the RSSI of the new/roamable AP should be for roaming
RoamRssiDiff=5
Дельта уровней между AP для выбора кандидата при миграции. Больше значение - меньше вероятность прилететь назад на ту же AP, но более отложенный старт миграции. Установленных по умолчанию 5дБ маловато. Нужно иметь дельту около 8-10дБ. Для начала выставим 8.
RoamRssiDiff=8
Ещё интересная штука:
#Beacon Early Termination (1 = enable the BET feature, 0 = disable)
enableBeaconEarlyTermination=1
beaconEarlyTerminationWakeInterval=11
Эта опция откидывает все маяки, если в этих фрэймах не взведён бит TIM, а клиент спит. Т.е. во сне клиент не может вести пассивный сбор данных о соседних AP. Хорошо для аккумулятора - вероятно, плохо для миграции (надо глубже копать драйвер).
gActiveMaxChannelTime=60
gActiveMinChannelTime=30
gActiveMaxChannelTimeConc=60
gActiveMinChannelTimeConc=30
Настройки времени прослушивания эфира при активном сканировании поканально, в мс. Больше значения - больше времени уйдёт на сканирование всего диапазона. Меньше время - быстрее просканируем, но можем половину не услышать.
RRM включается так:
# 802.11K support
gRrmEnable=1
gRrmOperChanMax=8
gRrmNonOperChanMax=8
gRrmRandIntvl=100
Правда, я на доступных мне железках (в смысле, на тех, в которых было выключено и включил, на SGS A5 2017 запросы есть, но там и так всё с миграцией более-менее) так и не дождался ни одного запроса с использованием RRM от Yota Phone. Видимо, отключена поддержка при сборке драйвера.
Это основное, что касается миграции.
Да и ещё:
# 1: Enable standby, 2: Enable Deep sleep, 3: Enable Mcast/Bcast Filter
gEnableSuspend=3
По умолчанию обычно 0. В таком режиме клиент при переходе в режим сна (часто просто при выключении экрана) полностью тушит RF часть, временно просыпаясь только для того, чтобы AP его по таймауту не выпнула. При этом, реализация такова, что и роумингу зачастую становится плохо. Следует установить его в 3, т.е. фильтровать броадкасты и мультикасты во сне, и только.
В файле конфигурации ещё много интересных параметов. Например, куча настроек для энергосбережения, если поотключать которые, миграция становиться более весёлой и точной, но батарея...
Ну и на закуску:
#Channel Bonding
gChannelBondingMode24GHz=1
gChannelBondingMode5GHz=1
gShortGI20Mhz=1
gShortGI40Mhz=1
Поддержка широких каналов (>20МГц) + поддержка SGI. Зачастую для 2.4ГГц поддержка 40МГц отключена, т.е. gChannelBondingMode24GHz установлен в 0. Что, во-первых, не позволяет работать на максимальных рэйтах (150Мбит/с для 1T1R в 2.4ГГц при 40МГц, будет только 72). Увы, проблема в том, что видимо для первого соединения значение перекрывается откуда-то ещё, и даже выставив gChannelBondingMode24GHz=1, сразу мы 150Мбит/с не видит. Но после первой же миграции драйвер плюёт на всех и взлетает в 40МГц полосе.
Также установка gChannelBondingMode24GHz решает проблему совместимости с некоторыми 2.4ГГц AP на Xiaomi и One+ (как обычно, намутили с анонсами в зависимости от региона, в итоге AP и клиент не могут договориться, в какой полосе разговаривать).
Не забываем после правки сохранить, перемонтировать назад системный раздел в RO и перезагрузиться.
URL: https://wi-cat.ru/2018/02/17/besshovnaya-migraciya-rouming-w.../ https://wi-cat.ru/2018/02/17/besshovnaya-migraciya-rouming-w.../
Обсуждается: http://www.opennet.dev/tips/info/3051.shtml