Bối cảnh thực tế: Khi link vật lý vẫn Up nhưng traffic rụng sạch
2 giờ sáng, PagerDuty réo liên tục vì toàn bộ cụm API backend timeout. Mình bật dậy SSH vào gateway Ubuntu ở datacenter. Cả session BGP lẫn OSPF trên FRRouting vẫn báo trạng thái Established và Full xanh lè. Tuy nhiên, lưu lượng thực tế rơi tự do về 0 Mbps.
Thủ phạm là một media converter quang ở switch trung gian bị treo vi điều khiển. Cổng mạng cắm vào NIC server vẫn nhận điện, đèn link sáng trưng. Linux kernel vì thế không hề biết tuyến cáp phía sau đã tê liệt. Hậu quả là toàn bộ gói tin bị đẩy thẳng vào hố đen (blackhole).
Điểm nghẽn nằm ở cơ chế kiểm tra mặc định của các giao thức định tuyến:
- OSPF: Hello timer 10 giây, Dead timer lên tới 40 giây. Mất gần một phút mạng mới chịu chuyển hướng.
- BGP: Mặc định Keepalive 60 giây và Hold timer tận 180 giây. Nghĩa là traffic rớt suốt 3 phút trước khi BGP router nhận ra neighbor đã chết.
Hạ OSPF Hello timer xuống 1 giây được không? Được, nhưng CPU router sẽ giật cục khi có hàng chục neighbor. OSPF vốn không được thiết kế cho mức độ phản ứng mili-giây. Đó là lúc bạn cần BFD (Bidirectional Forwarding Detection – RFC 5880).
BFD hoạt động độc lập ở tầng data plane qua UDP (port 3784 cho single-hop, 3785 cho echo). Gói tin BFD siêu nhẹ, chỉ khoảng vài chục byte và tiêu tốn chưa tới 0.1% CPU. Nhiệm vụ duy nhất của nó là bắt tay định kỳ ở chu kỳ mili-giây. Nếu mất 3 gói liên tiếp, BFD lập tức kích hoạt ngắt neighbor OSPF/BGP. Toàn bộ bảng routing sẽ hội tụ lại sang đường dự phòng chỉ trong chưa đầy 300ms.
Cài đặt FRRouting và bật BFD daemon
FRRouting (FRR) hiện là phần mềm routing suite chuẩn nhất trên Linux để thay thế Quagga. Để có đầy đủ tính năng của bfdd, bạn nên cài từ repo chính thức của FRR thay vì dùng bản mặc định trong apt repo của Ubuntu:
# 1. Thêm repo chính thức của FRR
sudo apt update && sudo apt install -y curl gnupg2 lsb-release
curl -s https://deb.frrouting.org/frr/keys.asc | sudo gpg --dearmor -o /usr/share/keyrings/frrouting.gpg
echo "deb [signed-by=/usr/share/keyrings/frrouting.gpg] https://deb.frrouting.org/frr $(lsb_release -s -c) frr-stable" | sudo tee /etc/apt/sources.list.d/frr.list
# 2. Cài đặt FRR package
sudo apt update
sudo apt install -y frr frr-pythontools
Mặc định FRR chỉ kích hoạt daemon trung tâm zebra. Bạn mở file /etc/frr/daemons để bật thêm BFD, OSPF và BGP:
sudo nano /etc/frr/daemons
Cập nhật lại các flag tương ứng:
zebra=yes
bgpd=yes
ospfd=yes
ospf6d=no
ripd=no
bfdd=yes
Khởi động lại dịch vụ và đặt tự chạy cùng hệ thống:
sudo systemctl restart frr
sudo systemctl enable frr
Cấu hình BFD cho OSPF và BGP từng bước
Mô hình thử nghiệm gồm hai gateway: Router-A (IP: 10.10.10.1/30 trên eth1) nối tới Router-B (IP: 10.10.10.2/30 trên eth1) qua một switch L2 trung gian.
1. Truy cập vtysh
Mở shell cấu hình hợp nhất của FRR:
sudo vtysh
2. Khai báo BFD peer
Tại Router-A, cấu hình chu kỳ gửi/nhận 100ms với hệ số nhân mất gói (detect-multiplier) bằng 3. Nếu router lỡ 3 gói liên tiếp (300ms), kết nối được xác định là đứt:
configure terminal
bfd
peer 10.10.10.2 interface eth1
detect-multiplier 3
receive-interval 100
transmit-interval 100
exit
exit
3. Gán BFD vào interface OSPF
Thêm lệnh ip ospf bfd trực tiếp vào interface kết nối neighbor:
configure terminal
interface eth1
ip address 10.10.10.1/30
ip ospf area 0
ip ospf bfd
exit
router ospf
router-id 1.1.1.1
network 10.10.10.0/30 area 0
exit
Chỉ cần khai báo 1 dòng ip ospf bfd, tiến trình OSPF sẽ tự động đăng ký với bfdd để theo dõi neighbor trên cổng eth1.
4. Tích hợp BFD vào BGP
Với BGP (eBGP hoặc iBGP), bạn gắn BFD thẳng vào từng neighbor chỉ định:
configure terminal
router bgp 65001
neighbor 10.10.10.2 remote-as 65002
neighbor 10.10.10.2 bfd
exit
5. Đồng bộ cấu hình đối ứng trên Router-B
Cấu hình tương tự trên Router-B để thiết lập bắt tay BFD hai chiều:
configure terminal
bfd
peer 10.10.10.1 interface eth1
detect-multiplier 3
receive-interval 100
transmit-interval 100
exit
exit
interface eth1
ip address 10.10.10.2/30
ip ospf area 0
ip ospf bfd
exit
router ospf
router-id 2.2.2.2
network 10.10.10.0/30 area 0
exit
router bgp 65002
neighbor 10.10.10.1 remote-as 65001
neighbor 10.10.10.1 bfd
exit
# Đừng quên lưu lại cấu hình ra đĩa cứng
write memory
Lưu ý: Lệnh write memory ghi toàn bộ runtime config vào file /etc/frr/frr.conf. Bỏ qua bước này, máy khởi động lại sẽ mất trắng cấu hình.
Kiểm tra trạng thái & Test đứt link thực tế
Sau khi lưu cấu hình, bạn cần kiểm tra xem BFD đã bắt tay thành công chưa trước khi đưa vào chạy production.
1. Kiểm tra session BFD
Trong vtysh, chạy lệnh tóm tắt trạng thái peer:
show bfd peers
Kết quả hiển thị mong đợi:
FRR-Router-A# show bfd peers
BFD Peers:
peer 10.10.10.2 interface eth1
ID: 219481023
Remote ID: 198302194
Status: up
Uptime: 0 hour(s), 12 minute(s), 18 second(s)
Diagnostic: ok
Remote diagnostics: ok
Receive Interval: 100ms
Transmit Interval: 100ms
Remote Receive Interval: 100ms
Remote Transmit Interval: 100ms
Trạng thái Status: up cùng các thông số 100ms xác nhận hai router đã trao đổi gói tin BFD thành công.
2. Kiểm tra OSPF và BGP đã link với BFD chưa
Kiểm tra chi tiết neighbor OSPF:
show ip ospf neighbor detail
Bạn sẽ thấy dòng: BFD enabled: status is Up. Kiểm tra tiếp với BGP:
show ip bgp neighbors 10.10.10.2
Dòng thông tin cần có: BFD enabled: yes, status: Up.
3. Thử nghiệm sự cố ngắt kết nối (Chaos Test)
Làm sao kiểm tra phản ứng khi cáp quang trung gian rụng? Ta dùng iptables chặn cổng UDP 3784 của BFD trên Router-B để mô phỏng mất kết nối:
# Chặn gói tin BFD một chiều trên Router-B
sudo iptables -I INPUT -p udp --dport 3784 -j DROP
Ngay lập tức, bật màn hình log trên Router-A:
show log monitor
Thông điệp xuất hiện gần như tức thì:
%BFD_PEER_DOWN: BFD peer 10.10.10.2 down
%OSPF-5-ADJCHANGE: Nbr 2.2.2.2 on eth1: Reset (BFD down)
%BGP-5-ADJCHANGE: neighbor 10.10.10.2 Down BFD session down
Đúng 300ms sau lệnh drop, cả OSPF và BGP lập tức hạ neighbor. Bảng định tuyến tự động chuyển hướng qua đường backup. Không còn cảnh traffic bị treo cứng 40 giây hay 3 phút như trước. Xóa rule iptables (sudo iptables -D INPUT 1), BFD bắt tay lại sau vài mili-giây và định tuyến khôi phục mượt mà.
