مسیریابی سیاستی IPv6 وقتی دو لینک بالادست fe80::1 را شریکاند
دو لینک بالادست میتوانند همان پرش بعدی fe80::1 را روی پیوندهای متفاوت نشان دهند. برای هر سیاست یک جدول انتخاب کنید، عمرها را خودتان در دست بگیرید و با جستوجوی مسیر بررسی کنید.
دو لینک بالادست دارید، و ip -6 route show همان پرش بعدی را روی هر دو نشان میدهد: default via fe80::1 dev uplink0 و default via fe80::1 dev uplink1. این تعارض نشانی تکراری نیست، و کپی کردن پرش بعدی خالی fe80::1 به یک جدول سیاستی به هسته نمیگوید کدام پیوند را منظور داشتهاید. پرسش واقعی باریکتر از آن است که نشانه پیشنهاد میکند: جدول دوم یک پیوند لازم دارد یا هر دو، و چه چیزی آن مسیرها را پس از راهاندازی مجدد زنده نگه میدارد. سه شرط، که به ترتیب بررسی میشوند، بیشتر آن را حل میکنند.
همان fe80::1 دو همسایه متفاوت است
نشانیهای link-local به یک پیوند محدودند، پس fe80::1 یک نشانی نیست که دو بار چاپ شده باشد؛ دو همسایه است که تصادفاً یک پسوند مشترک دارند. نمایه ناحیه همان چیزی است که میزبان با آن میگوید کدام را میخواهد، پس fe80::1%uplink0 و fe80::1%uplink1 برای هسته مقصدهای متفاوتی هستند، و آن پسوند هرگز به یک مسیریاب دور نمیرسد. RFC 4007 مدل ناحیهای پشت این را توصیف میکند، و به همین دلیل جدول سیاستی باید با هر پرش بعدی link-local یک دستگاه را همراه داشته باشد.
یک تولیدکننده پیکربندی VPN که شناسه ناحیه عددی را از یک میزبان به یک الگو کپی میکند، زمینه محلی را طوری رفتار میدهد که گویی بخشی از نشانی است، و فایلی که مینویسد روی هر ماشینی که نامها یا نمایههای واسطش متفاوت باشد اشتباه است. جدول سیاستی دو پیوند را هم در یکی ادغام نمیکند: VPN مسیریابیشده بستهها را میان شبکهها عبور میدهد، اما هویت link-local یک همسایه اترنت دوردست را از تونل عبور نمیدهد، پس ترافیک link-local روی پیوند خودش میماند.
دستگاه را بردارید و مسیر غیرقابلنوشتن میشود. ip -6 route add default via fe80::1 table 200 نمیتواند دروازه را تحلیل کند، و iproute2 آن را با Error: Nexthop has invalid gateway. رد میکند؛ dev uplink0 را اضافه کنید و فرمان موفق میشود، چون دستگاه همان چیزی است که پرش بعدی را به یکی از آن دو همسایه سنجاق میکند. چیزی که دستگاه نمیتواند به شما بگوید این است که آیا uplink0 پیوند درست برای این جدول است، و مسیری که از میزبان دیگری کپی شده نامهای واسط آن میزبان را با خود میآورد، و اشتباههای واقعی از همین جا میآیند.
شرط یک: یک پیوند یا دو پیوند در جدول
با این شروع کنید که لینک بالادست دوم برای چه چیزی است. اگر هر دو پیوند همان ترافیک را میبرند و یکی یدکی است، جدول جایگزین باید هر دو دروازه را با متریکهای متفاوت نگه دارد: مقصدهای یکسان، یک مسیر ترجیحی، یک گزینه دوم روشن. اگر لینکهای بالادست وجود دارند چون ترافیک متفاوت باید از ارائهدهندههای متفاوت بیرون برود، یا چون این یک تونل تقسیمشده است که بخشی از ترافیک VPN را دور میزند و بقیه داخل میماند، آن دو پیوند اصلاً به یک جدول تعلق ندارند. آنها به دو جدول تعلق دارند که یک قاعده انتخاب میکند، و قاعده جدول را انتخاب میکند نه تونل را: ترافیکی که دور میزند پیش از مسیریابی علامت میخورد، و همان علامت است که آن را به جدول دوم میفرستد.
در آن حالت دوم قاعده تعیین میکند جدول کِی مشورت شود، و مسیر تعیین میکند بسته پس از آن کجا برود:
ip -6 rule add fwmark 0x2 table 201
ip -6 route add default via fe80::1 dev uplink1 metric 100 table 201
ip -6 route add 2001:db8:100::/48 dev uplink1 metric 100 table 201
ip -6 route show table 201هیچیک از دو شیء جای دیگری را نمیگیرد، و جدولی که تنها یک مسیر پیشفرض دارد باز هم ممکن است در تحلیل دروازهاش شکست بخورد. اگر افزودن رد شود، یا مسیر حاضر اما بلااستفاده باشد، پیشوند متصل آن واسط را در همان جدول بگذارید، یا پرش را onlink علامت بزنید وقتی آن پیشوند جای دیگری مسیریابی میشود. در بلوک بالا 2001:db8:100::/48 همان پیشوند متصل روی uplink1 را نمایندگی میکند، نه یک مقصد دلبخواه. قاعده fwmark فقط علامتی را مصرف میکند که چیز دیگری باید بگذارد، از قاعده nftables یا iptables روی مسیر ارسال یا از SO_MARK روی سوکت، پس بلوکی که بدون منبع علامت کپی شده با هیچ چیز مطابقت ندارد.
شرط دو: متریکها ارائهدهنده مرده را تشخیص نمیدهند
متریک یک ترجیح میان مسیرهایی است که وجود دارند، نه یک بررسی سلامت. وقتی حامل قطع میشود، هسته مسیرهای آن دستگاه را برمیدارد و مسیر پیشفرض دوم جای آن را میگیرد. وقتی کابل وصل میماند و ارائهدهنده پشت آن میمیرد، در جدول هیچ چیز تغییر نمیکند: مسیر ترجیحی نصب شده، همسایه در لایه 2 دسترسپذیر است، و بستهها به یک چاله سیاه بیرون میروند. اگر این تمایز برای پیکربندی شما مهم است، جابهجایی باید از چیزی بیاید که مسیر را کاوش کند و آن را بردارد، چه یک دیمن مسیریابی باشد چه اسکریپت کوچکی که ورودی را پاک و دوباره نصب میکند.
پس از ساخت جدول انتخاب را بررسی کنید، و آن را همانطور بررسی کنید که هسته میبیند. ip -6 route get 2001:db8:100::1 مسیری را چاپ میکند که استفاده میشد، همراه با دستگاه و نشانی مبدأ انتخابشده، و به قواعد سیاست احترام میگذارد. نشانی مبدأیی که به لینک بالادست اشتباه تعلق دارد نشانه معمول این است که قاعدهای زودتر از انتظار شما مطابقت کرده است.
شرط سه: تصمیم بگیرید ماندگاری از کیست
مسیری که با ip -6 route add افزوده شود تا راهاندازی مجدد یا تا وقتی چیزی آن را پاک کند میماند. مسیر پیشفرضی که از اعلانهای مسیریاب آموخته شده عمر دارد و مسیریاب میتواند آن را پس بگیرد، در حالی که مسیر پیشفرض دستیافزوده هرگز خودبهخود منقضی نمیشود. آمیختن این دو در یک جدول همان راهی است که یک مسیر دائمی کهنه بر یک مسیر تازه اعلانشده پیشی میگیرد، مدتهای طولانی پس از آنکه لینک بالادستی که توصیف میکرد دیگر وجود نداشت.
برای هر جدول یک مالک انتخاب کنید. اگر مدیر شبکه یا دیمن مسیریابی از قبل واسط را مدیریت میکند، مسیر سیاستی را همانجا توصیف کنید و هسته را به حال خود بگذارید. اگر با اسکریپت انجام میدهید، اسکریپت را خودتکرارپذیر کنید و برچیدن را همزمان بنویسید، چون در نخستین تغییر بد به آن نیاز خواهید داشت:
ip -6 route flush table 201
ip -6 rule del fwmark 0x2 table 201روی مسیریابی که برای میزبانهای دیگر ارسال میکند، پیش از سرزنش جدول net.ipv6.conf.all.forwarding را بررسی کنید. با ارسال خاموش، بستههای نشانیگرفته به شبکه دیگر انداخته میشوند، هر قدر هم جدول 201 درست باشد.
طراحی را ثبت کنید تا نفر بعدی بتواند آن را حسابرسی کند
سیاههای که فقط fe80::1 را ذخیره کند فیلدهای مهم را دور میریزد. مقصد، پرش بعدی، دستگاه، جدول و متریک را با هم ثبت کنید، بهعلاوه اینکه هر مسیر از کجا آمده است — اعلانشده، تولیدشده توسط مدیر یا ایستا. وقتی بعداً کسی بپرسد آیا لینک بالادست دوم واقعاً ترافیک میبرد، آن ثبت بدون حدس به پرسش پاسخ میدهد.
پیش از آنکه جدول را تمامشده بدانید، همسایه را با ip -6 neigh show dev uplink0 تأیید کنید، ip -6 rule show را برای حادثههای ترتیب دوباره بخوانید، و با ترافیکی که با قاعده میخواند آزمایش کنید نه با ping که مسیر پیشفرض را میگیرد. سپس یک لینک بالادست را عمداً پایین بیاورید و ببینید هسته به کدام مسیر برمیگردد؛ پاسخ باید با آنچه نوشتهاید بخواند.