Сучасні віртуальні приватні мережі, розгорнуті на магістральних каналах 10 Гбіт/с та 100 Гбіт/с, стикаються з невідворотним фізичним бар'єром: лімітом тактової частоти окремого процесорного ядра. Хоча сучасні мережеві карти без зусиль приймають мільйони пакетів за секунду через апаратні черги, симетричне шифрування кожного байта корисного навантаження вимагає значних обчислювальних ресурсів. На типових серверах одне процесорне ядро під час виконання алгоритмів ChaCha20-Poly1305 або AES-GCM сягає насичення на рівні 1,5–2,5 Гбіт/с.

Традиційні реалізації VPN у просторі користувача (як-от класичний OpenVPN через віртуальні інтерфейси TUN) лише поглиблюють цей бар'єр: постійне перемикання контексту між ядром та користувацьким простором, багаторазове копіювання буферів пам'яті та конкуренція за блокування в однопотокових циклах подій суттєво знижують загальну пропускну здатність.

WireGuard вирішує це завдання безпосередньо всередині ядра Linux. Замість прив'язки криптографічних розрахунків до єдиного потоку віртуального інтерфейсу, протокол використовує підсистему padata (Parallel Execution and Serialization Architecture) разом із безблокувальними кільцевими буферами. Ця архітектура розподіляє обчислення між усіма доступними ядрами процесора, гарантуючи суворе збереження хронологічного порядку передавання пакетів (FIFO).

Проблема багатоядерного масштабування в мережевих тунелях

Коли застосунок надсилає дані через віртуальний мережевий пристрій (tun або wg), пакет потрапляє у функцію передавання ядра (ndo_start_xmit). За відсутності механізмів координації просте розподілення завдань між ядрами призводить до критичного дефекту: порушення послідовності пакетів (packet reordering).

Ризик нескоординованої паралельної обробки:
Ядро 0: Шифрує пакет 1 (1420 байтів) ======> Завершено при t = 12мкс -> Виходить другим (Збій порядку!)
Ядро 1: Шифрує пакет 2 (64 байти)    ===> Завершено при t = 3мкс  -> Виходить першим (Збій порядку!)

Порушення порядку пакетів завдає відчутного удару по транспортних протоколах:

  • Падіння ефективності TCP: Отримання сегментів не за порядком провокує потік дубльованих підтверджень (duplicate ACK), через що алгоритми керування перевантаженням помилково діагностують втрату та зменшують вікно вдвічі.
  • Дестабілізація таймерів QUIC: Протокол QUIC сприймає значне перемішування пакетів як ознаку мережевого затору, що порушує роботу алгоритмів виявлення втрат.
  • Відхилення захистом від повторів: Ковзне вікно WireGuard (розміром 2048 пакетів) відкидає пакети, що надходять із затримкою поза межами встановленого діапазону.

Саме тому паралельна криптографія вимагає детермінованого низьконакладного механізму повторної серіалізації перед виходом пакетів у фізичну мережу.

Архітектура Linux padata та серіалізація пакетів у ядрі

У ядрі Linux реалізовано спеціалізований механізм для організації паралельних обчислень із відновленням порядку: padata. WireGuard вибудовує свої конвеєри передавання та приймання навколо паралельних черг завдань (workqueues), з'єднаних із чергами впорядкування для кожного ядра.

Схема багатоядерного паралельного шифрування у WireGuard:

[Вхідний пакет через інтерфейс TUN]
         |
         v
+-------------------------------------------------------+
| Координатор: Присвоєння порядкового номера (Seq ID)   |
+-------------------------------------------------------+
         |
         +-------------------+-------------------+
         |                   |                   |
         v                   v                   v
    [Ядро CPU 0]        [Ядро CPU 1]        [Ядро CPU N]
 ChaCha20-Poly1305   ChaCha20-Poly1305   ChaCha20-Poly1305
 Паралельний розрахунок Паралельний розрахунок Паралельний розрахунок
         |                   |                   |
         +-------------------+-------------------+
         |
         v
+-------------------------------------------------------+
| Кільцевий буфер padata: Сортування суворо за Seq ID   |
+-------------------------------------------------------+
         |
         v
[Послідовне надсилання у вихідний UDP-сокет (NAPI / qdisc)]

Процес обробки поділяється на чотири скоординовані етапи:

  1. Присвоєння порядкового номера: Під час входження пакета в тунель ядро закріплює за ним 64-бітний монотонно зростаючий індекс у контексті черги відповідного піра.
  2. Паралельний розподіл: Буфер пакета (sk_buff) передається у чергу завдань ядра для виконання шифрування ChaCha20 та генерації імітовставки Poly1305 вільним процесорним ядром.
  3. Буфер упорядкування: Після завершення розрахунків пакет потрапляє у чергу padata. Навіть якщо Ядро 1 (обробляючи короткий службовий пакет 64 байти) завершило роботу раніше Ядра 0 (повний кадр 1420 байтів), пакет 2 утримується до появи пакета 1.
  4. Послідовне передавання: Пакети вивільняються з буфера суворо за первинним розкладом і надсилаються у мережевий стек через стандартні виклики UDP (udp_tunnel_xmit).

Цей механізм дозволяє серверам із 64 ядрами лінійно нарощувати криптографічну потужність, досягаючи пропускної здатності 40–80 Гбіт/с без виникнення дефектів пересортування.

Кільцеві буфери без блокувань та вирівнювання ліній кешу

За інтенсивності трафіку у мільйони пакетів за секунду основним фактором затримки стають спін-блокування (spinlocks). Конкуренція кількох ядер за покажчики спільної черги призводить до перевантаження системної шини операціями інвалідації кешу.

WireGuard мінімізує блокування за допомогою оптимізованих структур:

  • Окремі черги для кожного піра та ядра: Кожне робоче ядро має власні сегменти пам'яті, що унеможливлює конкуренцію між різними процесорами.
  • Обмін покажчиками без копіювання пам'яті: Замість фізичного переміщення даних пакета ядро передає лише покажчики на структури sk_buff усередині кільцевих буферів.
  • Вирівнювання за лініями кешу (Cache-Line Alignment): Ключові змінні вирівняно за 64-байтними межами ліній кешу L1 (____cacheline_aligned), що усуває ефект хибного спільного використання (false sharing).
Параметр архітектури OpenVPN (Простір користувача) IPsec (Підсистема xfrm ядра) WireGuard (Ядро Linux + padata)
Контекст виконання Процес у просторі користувача Мережева підсистема ядра Легковажний модуль ядра
Копіювання пам'яті на пакет 2–4 рази через TUN 1–2 рази Передавання покажчиків zero-copy
Багатоядерне масштабування Обмежено одним потоком Через багаторівневий Crypto API Вбудоване масштабування padata
Упорядкування пакетів Не потрібне (один потік) Складні черги тасклетів Детерміноване сортування
Споживання ресурсів Високе (динамічна пам'ять) Помірне Мінімальне (статичні буфери)

Налаштування мережевого стека Linux для багатоядерних тунелів

Щоб перетворити обчислювальний потенціал на реальну пропускну здатність, апаратні параметри мережевого адаптера (NIC), обробку переривань та маршрутизацію слід узгодити з паралельними конвеєрами WireGuard.

Маршрутизація вхідного трафіку (RSS та RPS)

Сучасні мережеві адаптери підтримують апаратне розбиття вхідних потоків Receive Side Scaling (RSS):

# Перевірка кількості апаратних каналів
ethtool -l eth0

# Прив'язка апаратних переривань до конкретних ядер CPU
systemctl stop irqbalance
set_irq_affinity -x 0-7 eth0

У хмарних віртуальних середовищах без апаратного RSS аналогічну функцію виконує механізм RPS (Receive Packet Steering):

# Розподіл обробки черги rx-0 на перші 8 ядер CPU (маска 0xff)
echo "ff" > /sys/class/net/eth0/queues/rx-0/rps_cpus

Маршрутизація вихідного трафіку (XPS)

Технологія XPS закріплює черги передавання за відповідними ядрами процесора, усуваючи конфлікти блокувань сокетів:

# Закріплення черги tx-0 за ядрами 0-3 (маска 0x0f)
echo "0f" > /sys/class/net/eth0/queues/tx-0/xps_cpus

Налаштування глибини системних буферів

Для запобігання втратам пакетів під час короткочасних сплесків трафіку:

# Збільшення розміру черги вхідних пакетів мережевих пристроїв
sysctl -w net.core.netdev_max_backlog=10000

# Розширення буферів приймання та надсилання сокетів UDP
sysctl -w net.core.rmem_max=67108864
sysctl -w net.core.wmem_max=67108864

Керування багатоядерними потоками в інфраструктурі RiceGuard

У навантажених корпоративних мережах стабільність пропускної здатності та передбачуваність затримок є вирішальними. Нерівномірне навантаження на ядра може спричиняти локальні затримки та коливання джитера.

VPNRice впроваджує архітектурні принципи паралельної серіалізації безпосередньо в рушій RiceGuard:

  • Урахування топології NUMA: Під час запуску RiceGuard автоматично визначає конфігурацію ядер і локальної пам'яті. Обчислювальні потоки закріплюються за локальними процесорними сокетами, усуваючи затримки міжсокетових шин.
  • Адаптивна пакетна обробка: За помірного навантаження пакети надсилаються негайно для підтримки мінімального пінгу. При зростанні трафіку вмикається векторна обробка SIMD із використанням інструкцій AVX-512 для лінійного шифрування.
  • Динамічні буфери захисту від втрат: Місткість кільцевих черг адаптується до поточних коливань часу розрахунку між ядрами, гарантуючи збереження порядку пакетів без втрат даних.

Завдяки узгодженому використанню багатоядерних можливостей ядра Linux, технологія RiceGuard забезпечує високу пропускну здатність та стабільне з'єднання для вимогливих мережевих завдань.

Завантажити VPNRice.\n