3.8 KiB
EIM NAT (Endpoint-Independent Mapping NAT)
1. Назначение
Трансляция сетевых адресов с endpoint-independent поведением: для каждого кортежа (внутренний IP, внутренний порт, протокол) выделяется уникальный внешний порт на шлюзе, не зависящий от внешнего адресата. Поддерживает TCP, UDP и ICMP Echo. Инкрементальный пересчёт контрольных сумм.
2. Как пользоваться
struct eim_nat_ctx nat;
eim_nat_init_ctx(&nat, &global_cfg); // таблица 64K записей
eim_nat_egress(&nat, pkt, len, node_id, conn); // src IP/port -> внешние
eim_nat_ingress(&nat, pkt, len, &entry); // dst IP/port -> внутренние
eim_nat_add_forward(&nat, proto, ip, port, ext_port); // статический проброс
eim_nat_destroy_ctx(&nat);
Таблица: 64K записей, индексируется по внешнему порту (внешний порт == индекс в таблице).
eim_nat_egress: выделяет внешний порт (аллоцирует из циклического пула next_port), заменяет src IP на шлюзовой и src порт на внешний, корректирует IP- и транспортную контрольные суммы. Фрагментированные пакеты пропускаются без обработки.
eim_nat_ingress: ищет запись по внешнему dst-порту в таблице, заменяет dst IP на внутренний и dst порт на внутренний, корректирует контрольные суммы. Возвращает out_entry — указатель на запись (содержит src_node_id и src_conn для маршрутизации ответа).
eim_nat_add_forward: добавляет статическую запись (EIM_NAT_ENTRY_STATIC), которая не вытесняется динамическими.
Контрольные суммы: пересчитываются инкрементально через csum_update_n() — старые значения вычитаются из ~csum, новые прибавляются. Это работает для TCP pseudo-header checksum и UDP.
Конфиг:
[nat]
enabled = 1
tun_ip = 10.0.0.1
port_start = 10000
port_end = 20000
[nat_forward]
rule = tcp 192.168.1.2:80 :8080
3. API
| Функция/Структура | Описание |
|---|---|
struct eim_nat_entry |
Запись: internal_ip, internal_port, proto, state (FREE/ACTIVE/STATIC), src_node_id, src_conn, last_seen |
struct eim_nat_ctx |
Контекст: gateway_ip, port_start/end, next_port (циклический аллокатор), table[64K], initialized |
eim_nat_init_ctx(ctx, cfg) |
Инициализация таблицы, загрузка статических пробросов из конфига |
eim_nat_destroy_ctx(ctx) |
Освобождение таблицы, обнуление |
eim_nat_egress(ctx, ip_data, ip_len, src_node_id, src_conn) |
Трансляция исходящего пакета: src IP/port → шлюзовые. Создаёт динамическую запись при первом проходе |
eim_nat_ingress(ctx, ip_data, ip_len, out_entry) |
Обратная трансляция входящего пакета: dst IP/port → внутренние. Заполняет out_entry для маршрутизации |
eim_nat_add_forward(ctx, proto, ip_host, port_net, ext_port) |
Добавление статического проброса (runtime API) |