IP-маршрутизация
Обзор
Маршрутизация — это процесс выбора путей по сетям для передачи пакетов от одного хоста к другому.
Как работает маршрутизация
Рассмотрим базовый пример конфигурации, чтобы показать, как маршрутизация используется для пересылки пакетов между двумя локальными сетями и в Интернет.
В этой схеме у нас есть несколько сетей:
- две клиентские сети (192.168.2.0/24 и 192.168.1.0/24);
- одна сеть для подключения роутеров (172.16.1.0/30), обычно называемая магистралью;
- последняя сеть (10.1.1.0/24) соединяет наш шлюзовый роутер (Router1) с Интернетом.
Роутер 2:
/ip address add address=172.16.1.2/30 interface=ether1
/ip address add address=192.168.2.1/24 interface=bridge2
Роутер 1 (шлюз), где ether1 подключён к интернету:
/ip address add address=10.1.1.2/24 interface=ether1
/ip address add address=172.16.1.1/30 interface=ether2
/ip address add address=192.168.1.1/24 interface=bridge1
Если взглянуть, например, на таблицу маршрутизации Router1, можно увидеть, что роутер знает только о напрямую подключённых сетях. Если клиент из LAN1 попытается достучаться до клиента из LAN2 (192.168.2.0/24), пакет будет отброшен на роутере, потому что для этого роутера неизвестен маршрут до назначения:
[admin@MikroTik] > /ip/route> print
Flags: D - dynamic; X - disabled, I - inactive, A - active; C - connect, S - static,
r - rip, b - bgp, o - ospf, d - dhcp, v - vpn
Columns: DST-ADDRESS, GATEWAY, Distance
DST-ADDRESS GATEWAY D
DAC 10.1.1.0/24 ether1 0
DAC 172.16.1.0/30 ether2 0
DAC 192.168.1.0/24 bridge1 0
Для исправления нужно добавить маршрут, который укажет роутеру, какое устройство в сети является следующим для достижения назначения. В нашем примере следующий хоп — Router2, поэтому нужно добавить маршрут с gateway, указывающим на связанный адрес Router2. Такой маршрут называется статическим маршрутом.
[admin@MikroTik] > /ip route add dst-address=192.168.2.0/24 gateway=172.16.1.2
[admin@MikroTik] > /ip/route> print
Flags: D - dynamic; X - disabled, I - inactive, A - active; C - connect, S - static,
r - rip, b - bgp, o - ospf, d - dhcp, v - vpn
Columns: DST-ADDRESS, GATEWAY, Distance
DST-ADDRESS GATEWAY D
DAC 10.1.1.0/24 ether1 0
DAC 172.16.1.0/30 ether2 0
DAC 192.168.1.0/24 bridge1 0
0 AS 192.168.2.0/24 172.16.1.2
Теперь пакеты из LAN1 будут успешно пересылаться в LAN2, но на этом дело не кончается. Router2 не знает, как достучаться до LAN1, поэтому любые пакеты из LAN2 будут отброшены на Router2.
Если снова взглянуть на сетевую схему, видно, что у Router2 есть только одна точка выхода. Безопасно предположить, что все неизвестные сети следует достигать через связь с Router1. Самый простой способ — добавить дефолтный маршрут с адресом назначения 0.0.0.0/0 или оставить поле пустым:
/ip route add gateway=172.16.1.1
Как показано, маршруты делятся на группы по происхождению и свойствам.
Информация о маршрутизации
Информация о маршрутизации в RouterOS состоит из двух основных частей:
- FIB (Forwarding Information Base) — база для принятия решений о пересылке пакетов. Содержит копию необходимой информации о маршрутах.
- RIB (Routing Information Base) — содержит все изученные префиксы из протоколов маршрутизации (connected, static, BGP, RIP, OSPF).
Routing Information Base
RIB — база данных, которая содержит записи о конкретных сетевых назначениях и их gateway (адрес следующего устройства на пути или просто next-hop). Каждая такая запись называется маршрутом.
Хоп — это переход пакета от одного сегмента сети к другому.
По умолчанию все маршруты организованы в одну «главную» таблицу маршрутизации. Можно создать несколько таблиц маршрутизации (об этом далее), но для простоты рассмотрим только одну «главную» таблицу.
RIB содержит полную информацию о маршрутах, включая статические маршруты и правила политической маршрутизации, настройку пользователя, информацию, полученную из динамических протоколов (RIP, OSPF, BGP) и информацию о подключённых сетях.
Его задача не только хранить маршруты, но и фильтровать информацию для выбора лучшего маршрута к каждому префиксу назначения, строить и обновлять FIB и распределять маршруты между протоколами маршрутизации.
Подключённые маршруты
Подключённые маршруты представляют сети, в которых хосты могут быть достигнуты напрямую (прямое подключение к Layer2 широковещательному домену). Эти маршруты создаются автоматически для каждой IP-сети с хотя бы одним включённым интерфейсом (указанном в конфигурации /ip address или /ipv6 address). RIB отслеживает статус подключённых маршрутов, но не изменяет их.
Для каждого подключённого маршрута существует один IP-адрес, такой что:
- часть address в dst-address подключённого маршрута равна сети IP-адреса;
- часть netmask в dst-address равна маске IP-адреса;
- gateway подключённого маршрута равен фактическому интерфейсу IP-адреса (за исключением портов bridge) и указывает интерфейс, где можно найти напрямую подключённые хосты сетевого слоя 3.
Preferred source больше не используется для подключённых маршрутов. FIB выбирает исходный адрес на основе исходящего интерфейса. Это позволяет строить конфигурации, которые в ROS v6 и старых считались недопустимыми.
Дефолтный маршрут
Дефолтный маршрут используется, если нельзя определить адрес назначения каким-либо другим маршрутом. В RouterOS dst-address дефолтного маршрута — 0.0.0.0/0 (IPv4) или ::/0 (IPv6). Если таблица маршрутизации содержит активный дефолтный маршрут, поиск всегда будет успешен.
Обычно в таблице маршрутизации домашнего роутера есть только подключённые сети и один дефолтный маршрут для отправки всего исходящего трафика на шлюз провайдера.
[admin@TempTest] /ip/route> print
Flags: D - dynamic; X - disabled, I - inactive, A - active;
C - connect, S - static, r - rip, b - bgp, o - ospf, d - dhcp, v - vpn
Columns: DST-ADDRESS, GATEWAY, Distance
# DST-ADDRESS GATEWAY D DA
0 0.0.0.0/0 10.155.125.1 1
DAC 10.155.125.0/24 ether12 0
DAC 192.168.1.0/24 vlan2 0
Аппаратно разгруженный маршрут
Устройства с аппаратной разгрузкой:
[admin@MikroTik] > /ip/route print where static
Flags: A - ACTIVE; s - STATIC, y - COPY; H - HW-OFFLOADED
Columns: DST-ADDRESS, GATEWAY, DISTANCE
# DST-ADDRESS GATEWAY D
0 AsH 0.0.0.0/0 172.16.2.1 1
1 AsH 10.0.0.0/8 10.155.121.254 1
2 AsH 192.168.3.0/24 172.16.2.1 1
По умолчанию все маршруты претендуют на аппаратную разгрузку. Чтобы точнее указать, какой трафик разгружать, для каждого статического IP/IPv6 маршрута есть опция включения или отключения suppress-hw-offload.
Например, если большая часть трафика идёт к сети серверов, можно включить разгрузку только для этого направления:
/ip route set [find where static && dst-address!="192.168.3.0/24"] suppress-hw-offload=yes
Теперь только маршрут к 192.168.3.0/24 помечен флагом H, что указывает на его пригодность для аппаратной разгрузки:
[admin@MikroTik] > /ip/route print where static
Flags: A - ACTIVE; s - STATIC, y - COPY; H - HW-OFFLOADED
Columns: DST-ADDRESS, GATEWAY, DISTANCE
# DST-ADDRESS GATEWAY D
0 As 0.0.0.0/0 172.16.2.1 1
1 As 10.0.0.0/8 10.155.121.254 1
2 AsH 192.168.3.0/24 172.16.2.1 1
Флаг H указывает лишь на возможность аппаратной разгрузки, а не на её реальное применение.
Мультипуть (ECMP) маршруты
Для реализации балансировки нагрузки может потребоваться использовать несколько путей до назначения.
ECMP (Equal Cost Multi-Path) маршруты имеют несколько шлюзов (next-hop). Все доступные next-hop копируются в FIB и используются для пересылки пакетов.
Такие маршруты можно создавать вручную или они могут быть динамически добавлены протоколами маршрутизации (OSPF, BGP, RIP). Несколько равнозначных маршрутов автоматически группируются с флагом +.
[admin@TempTest] /ip/route> print
Flags: D - DYNAMIC; I - INACTIVE, A - ACTIVE; C - CONNECT, S - STATIC, m - MODEM; + - ECMP
Columns: DST-ADDRESS, GATEWAY, DISTANCE
# DST-ADDRESS GATEWAY D
0 AS+ 192.168.2.0/24 10.155.125.1 1
1 AS+ 192.168.2.0/24 172.16.1.2 1
По умолчанию ECMP использует хеширование уровня 3, которое учитывает исходный и назначенный IP (для IPv4) или исходный IP, назначенный IP, метку потока и протокол IP (для IPv6).
Можно изменить политику хеширования в настройках /ip/setting и /ipv6/settings на:
- Хеширование уровня 4 (Layer4)
- Хеширование внутреннего уровня 3 (inner Layer3)
| IPv4 | IPv6 |
|---|---|
| L3: srcIPv4, dstIPv4 | srcIPv6, dstIPv6, flow label, IP proto |
| L4: srcIPv4, dstIPv4, srcPort, dstPort, IP proto | srcIPv6, dstIPv6, srcPort, dstPort, IP proto |
| L3-Inner |
Выбор маршрута
Для одного назначения может приходить несколько маршрутов из разных протоколов или статических настроек, но для пересылки пакетов используется только один лучший маршрут. Для выбора лучшего пути RIB запускает алгоритм выбора, который выбирает лучший маршрут среди кандидатов для каждого назначения.
Для участия в выборе маршрут должен:
- не быть отключённым;
- если это unicast маршрут, иметь хотя бы один доступный next-hop (если gateway из связанной сети и связанный маршрут активен, gateway считается доступным);
- не быть синтетическим.
Кандидат с наименьшим расстоянием становится активным маршрутом. При равных расстояниях выбор активного маршрута произвольный.
Поиск следующего хопа (Nexthop Lookup)
Это часть процесса выбора маршрута. Основная задача — найти напрямую доступный адрес шлюза (next-hop). После выбора валидного next-hop роутер знает, какой интерфейс использовать для пересылки пакета.
Поиск next-hop усложняется, если gateway находится в нескольких хопах от роутера (например, iBGP, multihop eBGP). Такие маршруты устанавливаются в FIB после определения напрямую доступного gateway (immediate next-hop).
Нужно ограничить набор маршрутов, используемых для поиска immediate next-hop. Значения next-hop протоколов RIP или OSPF предполагаются напрямую доступными и должны искаться только среди подключённых маршрутов, используя свойства scope и target-scope.
Маршруты со scope больше максимального не участвуют в поиске next-hop. Каждому маршруту присваивается максимальный scope для next-hop в target-scope. По умолчанию разрешен поиск next-hop только через подключённые маршруты, кроме iBGP с расширенным scope, допускающим поиск через IGP и статические маршруты.
В RouterOS v7 произошли изменения в механизме поиска next-hop. Маршруты обрабатываются по возрастанию scope, и изменения в маршрутах с большим scope не влияют на маршруты с меньшим scope.
Пример из v6:
/ip route add dst-address=10.0.1.0/24 gateway=10.0.0.1 scope=50 target-scope=30 comment=A
/ip route add dst-address=10.0.2.0/24 gateway=10.0.0.1 scope=30 target-scope=20 comment=B
/ip route add dst-address=10.0.0.0/24 scope=20 gateway=WHATEVER comment=C
Gateway 10.0.0.1 рекурсивно разрешается через C с самым маленьким использованием scope (20 из маршрута B), оба маршрута активны. При изменении маршрутов A и B одновременно:
/ip route set A target-scope=10
Теперь обновление маршрута A делает шлюз маршрута B неактивным, потому что в v6 на один адрес приходится только один объект шлюза.
v7 хранит несколько объектов шлюзов на адрес, по каждой комбинации scope и проверки шлюза. При изменении target-scope или проверки шлюза маршрута в ROS v7 эти свойства связаны с самим шлюзом, а не маршрутом, поэтому не влияют на другие маршруты.
Некорректные значения scope автоматически исправляются:
- если scope шлюза = 255, меняется на 254;
- если scope маршрута меньше scope шлюза, меняется на scope шлюза + 1;
Актуальные значения scope и target-scope видны в меню /routing/nexthop.
Проверка доступности шлюза расширяется параметром check-gateway. Доступность проверяется посылкой ARP-запросов, ICMP-сообщений или проверкой активных BFD-сессий. Каждые 10 секунд роутер шлёт либо ICMP echo request (ping), либо ARP-запрос (arp). Если 10 секунд ответ не приходит, запрос тайм-аутится. После двух тайм-аутов шлюз считают недоступным. После получения ответа шлюз считается доступным, а счётчик тайм-аутов сбрасывается.
Хранение маршрутов
Информация о маршрутах хранится с целью минимизации использования памяти. Эти оптимизации имеют худшие случаи, заметные в производительности.
Все маршруты и шлюзы хранятся в единой иерархии по префиксу/адресу.
Каждый "Dst" соответствует уникальному dst-address маршрута или адресу шлюза. Для каждого Dst требуется один или более объектов типа T2Node.
Все маршруты с одним dst-address хранятся в списке в Dst, отсортированном по предпочтению.
Примечание: худший случай — много маршрутов с одинаковым dst-address сильно замедляет обновления, даже если они неактивны, из-за накладных расходов сортировки списка.
Порядок маршрутов меняется только при изменении их атрибутов; при смене активности порядок — нет.
Каждый маршрут имеет три копии атрибутов:
- private — получено от пира, до применения фильтров;
- updated — результат применения фильтров;
- current — атрибуты, используемые маршрутом в данный момент.
Атрибуты периодически пересчитываются при поступлении обновлений или изменении фильтров.
Без фильтров private и updated обычно совпадают и равны current.
Атрибуты хранятся в нескольких группах:
- L1 Data — флаги, список доп. свойств, as-path;
- L2 Data — next-hop, метрики RIP, OSPF, BGP, теги маршрутов, инициаторы и т.д.;
- L3 Data — расстояние, scope, тип ядра, MPLS;
- Дополнительные свойства — communities, originator, aggregator-id, cluster-list и др.
Большое разнообразие комбинаций distance и scope увеличивает расход памяти.
Для ускорения фильтрации matching communities или as-path кешируются. Каждый as-path или community имеет кеш для всех regexp с результатами поиска.
Примечание: изменение атрибутов в in-filter увеличивает память (private и updated расходятся), большое количество regexp замедляет работу и расходует память за счёт кешей.
Подробности по памяти маршрутизации доступны в меню /routing stats memory.
Forwarding Information Base
FIB содержит информацию, необходимую для пересылки пакетов:
- все активные маршруты;
- правила политической маршрутизации.
Каждый маршрут имеет свойство dst-address, указывающее назначения, для которых он применим. Если несколько маршрутов подходят под конкретный IP, выбирается наиболее специфичный (с самой большой маской). Эта операция называется поиском в таблице маршрутизации.
Для пересылки используется только один лучший маршрут. Если несколько маршрутов равнозначны, они объединяются в ECMP маршрут. Лучший маршрут устанавливается в FIB как активный.
Если решение о маршрутизации учитывает дополнительные данные (например, исходный адрес пакета), это называется политической маршрутизацией. Она реализована через список правил политики, которые выбирают таблицы маршрутизации по адресу назначения, исходному адресу, исходному интерфейсу и метке маршрутизации (routing mark), которая может изменяться через firewall mangle.
Поиск в таблице маршрутизации
FIB использует для определения назначения пакета:
- исходный адрес;
- адрес назначения;
- исходный интерфейс;
- маркировку маршрутизации.
Возможные решения:
- принять пакет локально;
- отбросить пакет (молча или с ICMP сообщением отправителю);
- отправить пакет на конкретный IP на определённом интерфейсе.
Последовательность принятия решения:
- проверка, должен ли пакет быть доставлен локально (адрес назначения совпадает с адресом роутера);
- применение неявных правил политики маршрутизации;
- применение пользовательских правил политики маршрутизации;
- неявное правило, выполняющее поиск назначения в "главной" таблице маршрутизации;
- если ничего не найдено — возвращается "сеть недоступна".
Результатом может быть:
- адрес next-hop + интерфейс;
- point-to-point интерфейс;
- локальная доставка;
- отбрасывание;
- ICMP запрещено;
- ICMP хост недоступен;
- ICMP сеть недоступна.
Правила, не совпадающие с пакетом, игнорируются. Если действие:
- drop или unreachable — возвращается как результат;
- lookup — ищет адрес назначения в таблице, указанной в правиле. При неудаче ищется следующее правило;
- lookup-only — аналогично lookup, но при отсутствии совпадения поиск завершается неудачей.
В противном случае:
- если маршрут — blackhole, prohibit или unreachable — возвращается соответствующее действие;
- если маршрут подключён или имеет интерфейс в качестве gateway — возвращается интерфейс и адрес назначения;
- если gateway — IP адрес — возвращается адрес и интерфейс;
- если несколько next-hop — выбирается один по кругу.
Установка интерфейса как gateway для статических маршрутов в целом не рекомендуется. Это полезно только в двух случаях:
- point-to-point интерфейсы;
- интерфейсы с напрямую подключённым адресом назначения.
Если интерфейс назначен как gateway, при маршрутизации на широковещательной сети роутер пытается определить destination адрес, отправляя ARP-запросы. Если никому из хостов сети не принадлежит IP, пересылка не состоится. Такие gateway не подходят для маршрутизации пакетов с несколькими хопами.
Gateway, установленный на не point-to-point интерфейсе, не может использоваться для пересылки пакетов с дестинацией, удалённой на несколько хопов.
Параметр check-gateway также не применяется для таких gateway по очевидным причинам — нет известного IP назначения.
Просмотр маршрутов
В RouterOS есть три меню, отображающие состояние маршрутов в таблице:
/ip route— список IPv4 маршрутов с основными свойствами;/ipv6 route— список IPv6 маршрутов с основными свойствами;/routing route— список всех маршрутов с расширенными свойствами.
Меню /routing route только для чтения. Добавлять или удалять маршруты нужно через меню /ip или /ipv6 route.
Пример вывода
[admin@MikroTik] /ip/route> print
Flags: D - dynamic; X - disabled, I - inactive, A - active; C - connect, S - static,
r - rip, b - bgp, o - ospf, d - dhcp, v - vpn
Columns: DST-ADDRESS, GATEWAY, Distance
# DST-ADDRESS GATEWAY DI
0 XS 10.155.101.0/24 1.1.1.10 1
1 XS 11.11.11.10 D d
2 AS 0.0.0.0/0 10.155.101.1 10
3 AS 0.0.0.0/0 10.155.101.1 1
4 AS+ 1.1.1.0/24 10.155.101.1 10
5 AS+ 1.1.1.0/24 10.155.101.2 10
6 AS 8.8.8.8 2.2.2.2 1
DAC 10.155.101.0/24 ether12 0
Вывод команды /routing route похож на /ip route, но показывает маршруты всех семейств адресов в одном меню и отображает отфильтрованные маршруты.
[admin@MikroTik] /routing/route> print
Flags: X - disabled, I - inactive, F - filtered, U - unreachable, A - active;
c - connect, s - static, r - rip, b - bgp, o - ospf, d - dhcp, v - vpn,
a - ldp-address, l - ldp-mapping
Columns: DST-ADDRESS, GATEWAY, DISTANCE, SCOPE, TARGET-SCOPE, IMMEDIATE-GW
DST-ADDRESS GATEWAY DIS SCO TAR IMMEDIATE-GW
Xs 10.155.101.0/24 Xs d 0.0.0.0/0 10.155.101.1 10 30 10 10.155.101.1%ether12
As 0.0.0.0/0 10.155.101.1 1 30 10 10.155.101.1%ether12
As 1.1.1.0/24 10.155.101.1 10 30 10 10.155.101.1%ether12
As 8.8.8.8 2.2.2.2 1 254 254 10.155.101.1%ether12
Ac 10.155.101.0/24 ether12 0 10 ether12
Ic 2001:db8:2::/64 ether2 0 10
Io 2001:db8:3::/64 ether12 110 20 10
Ic fe80::%ether2/64 ether2 0 10
Ac fe80::%ether12/64 ether12 0 10 ether12
Ac fe80::%bridge-main/64 bridge-main 0 10 bridge-main
A ether12 0 250
A bridge-main 0 250
Команда /routing route print detail показывает расширенную информацию, полезную для отладки:
[admin@MikroTik] /routing route> print detail
Flags: X - disabled, I - inactive, F - filtered, U - unreachable, A - active;
c - connect, s - static, r - rip, b - bgp, o - ospf, d - dhcp, v - vpn,
a - ldp-address, l - ldp-mapping; + - ecmp
Xs dst-address=10.155.101.0/24
Xs d afi=ip4 contribution=best-candidate
dst-address=0.0.0.0/0 gateway=10.155.101.1 immediate-gw=10.155.101.1%ether12
distance=10 scope=30 target-scope=10 belongs-to="DHCP route"
mpls.in-label=0 .out-label=0 debug.fwp-ptr=0x201C2000
As afi=ip4 contribution=active dst-address=0.0.0.0/0 gateway=10.155.101.1
immediate-gw=10.155.101.1%ether12 distance=1 scope=30 target-scope=10 belongs-to="Static route"
mpls.in-label=0 .out-label=0 debug.fwp-ptr=0x201C2000