# route_lib – библиотека таблицы IPv4-маршрутизации ## 1. Назначение Ведёт таблицу IPv4-маршрутов в памяти: динамический массив `ROUTE_ENTRY`, отсортированный по network-адресу с поддержкой вставки/удаления и LPM-поиска (Longest Prefix Match). Используется модулем `routing` для принятия решения, куда слать пакет — какому узлу через ETCP или локально в TUN. Таблица не содержит логики синхронизации — наполнение маршрутами идёт через BGP (`topo_node`). ## 2. Как пользоваться ```c struct ROUTE_TABLE* rt = route_table_create(); // Вставка подсетей узла (из BGP): route_insert(rt, topo_nodeq); // Поиск маршрута (LPM): struct ROUTE_ENTRY* e = route_lookup(rt, dest_ip); if (e && e->v_node_info && e->v_node_info->hop_count > 0) { // Отправить через ETCP узлу e->v_node_info->node->node_id } else { // Локальный маршрут — отдать в TUN } // Удаление маршрутов узла: route_delete(rt, topo_nodeq); route_table_destroy(rt); ``` **Ключевые нюансы:** - Адреса в `ROUTE_ENTRY.network` хранятся в **big-endian** (сетевой порядок) - Записи отсортированы по `network` ASC, при равенстве — по `prefix_length` DESC (более специфичные раньше) - Алгоритм LPM: бинарный поиск с fallback-проверкой соседней записи - `v_node_info == NULL` или `hop_count == 0` означает **локальный маршрут** - Пересечение маршрутов запрещено — `route_insert` проверяет `check_route_overlap_in_table` - Ёмкость массива динамически расширяется (×2) при переполнении ## 3. API ### Структуры | Структура | Поля | Описание | |-----------|------|----------| | `ROUTE_ENTRY` | `network` (uint32_t, BE), `prefix_length` (uint8_t), `v_node_info` (TOPO_GROUP_NODE*) | Запись маршрута. `v_node_info==NULL` → локальный | | `ROUTE_TABLE` | `entries`, `count`, `capacity`, `dynamic_subnets`, `local_subnets`, `stats` | Таблица маршрутизации. Динамический массив + статистика | ### Функции | Функция | Описание | |---------|----------| | `route_table_create()` | Выделяет `ROUTE_TABLE`, `entries` на `INITIAL_CAPACITY=100`, счётчики в 0 | | `route_table_destroy(table)` | Освобождает `entries`, `dynamic_subnets`, `local_subnets`, саму таблицу | | `route_insert(table, node)` | Вставляет все v4-подсети узла (`TOPO_GROUP_NODE`) с сортировкой. Проверяет overlap. Расширяет capacity при необходимости | | `route_delete(table, node)` | Удаляет все записи, где `v_node_info == node`, со сдвигом массива | | `route_lookup(table, dest_ip)` | LPM-поиск. Возвращает `ROUTE_ENTRY*` или NULL. Инкрементит `stats` (hits/misses) | | `route_table_print(table)` | Печатает содержимое таблицы в лог | | `parse_subnet(str, network, prefix_length)` | Парсит `"a.b.c.d/n"` → network (BE) + prefix_length. Возвращает 0/-1 | | `is_local_subnet(ip)` | Проверяет, является ли IP локальным/мультикастовым/зарезервированным (0=true). RFC1918 + 0.0.0.0/8 + 127.0.0.0/8 + АPIPA + multicast + broadcast + CGNAT (100.64.0.0/10) | | `route_add_local_subnet(table, network, prefix_length)` | **Объявлена в .h, но не реализована** | ### Внутренние функции | Функция | Описание | |---------|----------| | `prefix_to_mask(prefix)` | Преобразует длину префикса в маску: `/24` → `0xFFFFFF00` | | `routes_overlap(n1, p1, n2, p2)` | Проверяет, совпадают ли две подсети (одинаковые network+prefix) | | `check_route_overlap_in_table(net, pre, entries, count)` | Проверяет overlap со всеми существующими записями | | `binary_search_insert_pos(entries, count, net, pre)` | Находит позицию для вставки с сохранением сортировки | | `binary_search_lpm(table, dest_ip)` | Бинарный LPM-поиск с fallback на соседнюю запись |