Ping до іншого кінця вашого тунелю IPv6 не проходить? Перевірте адресу ::
Ідентифікатор інтерфейсу з усіма нулями — це subnet-router anycast, а не вузол. Призначте ::1 і ::2, спрямуйте префікс і перевірте multicast, перш ніж звинувачувати маршрути.
Один кінець вашого тунелю IPv6 пінгує інший, і відповідає завжди лише один напрямок. Інтерфейс піднятий, маршрут виглядає правильно, і ніщо в журналі цього не пояснює. Адреса, яку ви призначили, — це адреса subnet-router anycast, яка взагалі не є адресою вузла, і на з'єднанні з двома кінцями вона має рівно одну ціль доставки: відправника. Жодне значення тайм-ауту це не виправить, бо адреса не робить того, що ви думаєте.
Симптом, що вказує на адресу
Кожен вузол на з'єднанні відповідає, крім того, чий ідентифікатор інтерфейсу — самі нулі. Пакет, адресований такій формі, за визначенням доставляється маршрутизатору в підмережі, тому на тунелі точка-точка він повертається до машини, яка його надіслала. З далекого кінця це читається як недосяжний партнер; з ближнього — як тиша. Замініть ідентифікатор на інший із того самого префікса, і симптом зникає без жодної іншої зміни, і це те підтвердження, яке слід отримати, перш ніж торкатися маршрутів.
Ідентифікатор із самих нулів зарезервовано як anycast
RFC 4291 зберігає ідентифікатор інтерфейсу з самих нулів як адресу subnet-router anycast, тому /64, як-от 2001:db8:4a::/64, не містить жодного придатного вузла на 2001:db8:4a::. Це резервування має сенс: router advertisements і neighbour discovery звертаються до такої форми, а маршрутизатор відповідає за префікс, який обслуговує. Призначення цього значення кінцю тунелю передає роль маршрутизатора листку, і саме тому нічого не повертається. Будь-який інший ідентифікатор у префіксі працює як вузол, тож виправлення зазвичай — одна цифра.
Ставтеся до резервування як до ролі, яку ви не маєте права займати з кінця тунелю, а не як до дивини, яку треба обійти маршрутом.
Призначте адреси вузлів і спрямуйте префікс
Виберіть ::1 і ::2 для двох кінців, додайте один за допомогою ip -6 addr add 2001:db8:4a::2/64 dev tun0, а потім спрямуйте віддалений префікс замість того, щоб намагатися адресувати його. Маршрут для 2001:db8:4a::/64 назовні тунелю робить далекий бік доступним; сама адреса лише налаштовує локальний інтерфейс.
Для повного тунелю є третій крок — маршрут за замовчуванням для глобального unicast через пристрій, що є IPv6-відповідником надсилання всього в тунель. Якщо його пропустити, IPv6 і далі використовує фізичне з'єднання, поки IPv4 подорожує всередині тунелю, тож вузол витікає саме той трафік, який ви вважали покритим. Підтвердьте за допомогою ip -6 route get 2001:4860:4860::8888 і прочитайте, який пристрій він називає, замість того щоб припускати відповідь.
Multicast відхиляється ще до маршрутизації
Android перевіряє адреси й маршрути для VpnService.Builder через LinkAddress, і цей конструктор відхиляє multicast одразу. Дайте йому multicast-префікс як маршрут, і результатом буде помилка bad LinkAddress parameters, а не маршрут, що є відповіддю перевірки, а не мережі. Відмова відповідає середовищу: пристрій tun точка-точка не має link-layer multicast, тож груповий маршрут на ньому не має моделі доставки для встановлення. Групові адреси створюються й споживаються самим стеком, а не налаштовуються вручну.
Адреси IPv6 all-nodes і solicited-node підпадають під те саме правило. Інтерфейс носить їх, бо стек їх туди поклав, а не тому, що їх задумала якась політика.
Що тунель може нести натомість
Перенесення multicast-виявлення через тунель потребує шару, який розуміє членство в групі: TAP-міст, що подає сегмент Ethernet, relay на рівні застосунку або протокол маршрутизації, якому прямо сказано, яким партнерам реплікувати. Нічого з цього немає в моделі VpnService, де застосунок читає й пише пакети і не має виклику, що приєднує групу для тунелю. Або додайте компонент, який розуміє групи, або приберіть вимогу з дизайну.
Unicast, навпаки, не потребує нічого понад наведені адреси й маршрути, тому від тунелів зазвичай очікують, що вони його нестимуть, а потім звинувачують їх, коли протокол виявлення не спрацьовує.
Три перевірки, перш ніж щось призначати
Підтвердьте, що адреса не є формою anycast, підтвердьте, що вона не multicast, і підтвердьте, що префікс спрямовано, а не лише призначено пристрою. Потім надішліть тест на призначення, яке є справжнім вузлом, бо ping, націлений на anycast-адресу, вимірює відправника й нічого не каже про шлях. Запишіть ці три перевірки в журнал змін, щоб наступне розгортання не відкривало їх заново.
Маршрут, який платформа ніколи не встановила, не можна налагодити довшим очікуванням, а адресу, яка ніколи не була вузлом, не можна виправити кращим ping.