Thiết kế các cổng VPN hiện đại nhằm duy trì thông lượng hàng chục gigabit đòi hỏi khả năng điều phối lập trình được trên cả hai chiều gói tin vào (ingress) và ra (egress). Mặc dù cơ chế eXpress Data Path (XDP) đã khẳng định vị thế trong việc lọc gói tin cực nhanh ở tầng trình điều khiển mạng, XDP lại có một giới hạn cố hữu: nó chỉ hoạt động trên chiều nhận trước khi nhân Linux cấp phát cấu trúc bộ đệm mạng (struct sk_buff). Do đó, XDP không thể can thiệp vào gói tin chiều phát, không quản lý được hàng đợi xuất dữ liệu và không thể thao tác sâu sau khi gói tin đi qua socket.
Để đạt được khả năng xử lý hai chiều toàn diện, các kỹ sư mạng Linux sử dụng phân hệ Điều khiển lưu lượng (Traffic Control - TC) kết hợp với bộ phân loại eBPF (BPF_PROG_TYPE_SCHED_CLS). Được gắn kết thông qua kỷ luật hàng đợi hiện đại clsact (qdisc), các chương trình eBPF TC thực thi trực tiếp trong ngăn xếp mạng của nhân với toàn quyền truy cập cấu trúc sk_buff, cho phép định tuyến L4/L7 linh hoạt, chuyển tiếp gói tin xuyên card mạng và định thời xuất gói (departure-time pacing) mà không cần chuyển ngữ cảnh sang user space.
So sánh vị trí thực thi: eBPF TC và XDP trong ngăn xếp nhân
Để thấy rõ vai trò của eBPF TC đối với các đường hầm mạng mã hóa, cần phân tích vị trí móc nối của nó so với XDP.
Gói tin đi vào (Ingress)
│
▼
┌──────────────┐
│ Hook XDP │ <--- Thao tác trên xdp_md thô trước khi cấp phát skb
└──────┬───────┘ (Hủy/chuyển hướng cực nhanh, chỉ chiều vào, không có chiều ra)
│
▼
alloc_skb()
│
▼
┌──────────────────┐
│ eBPF TC Ingress │ <--- Thao tác trên struct __sk_buff (clsact qdisc)
└──────┬───────────┘ (Phân tích L3/L4 đầy đủ, bảng băm BPF, chuyển hướng đường hầm)
│
▼
Ngăn xếp giao thức (IP/TCP/UDP) ── Tầng Socket
│
▼ (Gói mã hóa chiều ra Egress)
┌──────────────────┐
│ eBPF TC Egress │ <--- Thao tác trên struct __sk_buff trước vòng đệm NIC
└──────┬───────────┘ (Định thời xuất gói EDT, đánh dấu DSCP, giới hạn tốc độ)
│
▼
Hàng đợi của trình điều khiển card mạng vật lý
Thực thi ở tầng TC mang lại các khả năng vận hành khác biệt:
- Bao phủ hai chiều: Các móc nối TC có thể gắn đồng thời vào luồng nhận và luồng phát của cả giao diện vật lý (
eth0) lẫn giao diện đường hầm ảo (wg0). - Toàn quyền tiếp cận
sk_buff: Chương trình TC có thể đọc và sửa đổi tiêu đề mạng, tổng kiểm tra checksum, tem thời gian (skb->tstamp) và nhãn tường lửa (skb->mark). - Thực thi hành động trực tiếp: Nhờ cờ
direct-action(da), chương trình BPF phân loại có thể trả về phán quyết trực tiếp (TC_ACT_OK,TC_ACT_SHOT,TC_ACT_REDIRECT), loại bỏ nhu cầu ghép nối nhiều bộ lọc phức tạp.
Điều hướng gói tin không sao chép bằng bpf_redirect
Trong các mô hình mạng VPN đa người thuê quy mô lớn, việc luân chuyển gói tin giữa cổng mạng vật lý và giao diện đường hầm ảo theo cách truyền thống đòi hỏi gói tin phải đi qua phân hệ định tuyến IP của kernel hai lần. Lộ trình này phải tra cứu bảng định tuyến IP, bảng theo dõi kết nối (conntrack) và các chuỗi netfilter, tạo áp lực lớn lên bộ nhớ đệm CPU.
Với eBPF TC, quản trị viên có thể lập trình chuyển tiếp trực tiếp giữa các thiết bị mạng ngay trong không gian nhân thông qua hàm trợ giúp bpf_redirect():
#include <linux/bpf.h>
#include <linux/pkt_cls.h>
#include <bpf/bpf_helpers.h>
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 65536);
__type(key, __u32); /* IPv4 ảo của máy khách */
__type(value, __u32); /* Chỉ số ifindex của giao diện đích */
} route_map SEC(".maps");
SEC("tc")
int tc_ingress_router(struct __sk_buff *skb)
{
void *data = (void *)(long)skb->data;
void *data_end = (void *)(long)skb->data_end;
/* Kiểm tra biên: đủ tiêu đề Ethernet + IPv4 */
if (data + sizeof(struct ethhdr) + sizeof(struct iphdr) > data_end)
return TC_ACT_OK;
struct iphdr *iph = data + sizeof(struct ethhdr);
__u32 dst_ip = iph->daddr;
/* Tra cứu bảng BPF siêu tốc tìm giao diện đích */
__u32 *ifindex = bpf_map_lookup_elem(&route_map, &dst_ip);
if (ifindex) {
/* Chuyển hướng gói tin trực tiếp, bỏ qua ngăn xếp IP trung gian */
return bpf_redirect(*ifindex, 0);
}
return TC_ACT_OK;
}
Khi được gắn vào giao diện vật lý, bộ phân loại này đọc gói tin đến, xác thực ánh xạ điểm cuối bằng bảng băm BPF tốc độ cao và chuyển hướng gói thẳng vào hàng đợi nhận của giao diện đường hầm tương ứng. Toàn bộ thao tác diễn ra không cần sao chép bộ nhớ, cắt giảm hơn 40% chu kỳ xung nhịp CPU cho mỗi gói tin.
Định thời xuất gói EDT và triệt tiêu xung đột Microburst
Một vấn đề lớn trên các kết nối VPN băng thông cao là hiện tượng cụm gói dồn dập (packet microbursts). Khi nhiều luồng tải dữ liệu lớn đồng thời hoạt động, các nguồn phát TCP đẩy những chùm gói tin dày đặc vào giao diện mạng. Các thuật toán giới hạn lưu lượng truyền thống như TBF hay HTB buộc phải gom giữ gói tin thừa trong hàng đợi bộ nhớ dùng khóa quay vòng (spinlock). Dưới tải cao, hiện tượng tranh chấp khóa làm suy giảm nghiêm trọng khả năng co giãn đa lõi.
Nhân Linux hiện đại giải quyết tình trạng nghẽn đệm thông qua cơ chế lập lịch thời gian xuất sớm (Early Departure Time - EDT). Thay vì giữ gói trong hàng đợi có khóa, hệ thống gán nhãn tem thời gian xuất dự kiến (skb->tstamp) cho từng gói tin.
Sử dụng eBPF TC trên luồng xuất (egress), các kỹ sư có thể hiện thực hóa việc điều tiết băng thông không khóa:
- Chương trình eBPF egress tính toán khoảng cách phát tối thiểu dựa trên gói cước băng thông được cấu hình của máy khách.
- Chương trình cập nhật
skb->tstamp = max(current_time, last_departure_time + packet_len / rate). - Kỷ luật hàng đợi công bằng (
sch_fq) ở tầng dưới sẽ đẩy gói tin ra đường truyền vật lý chính xác theo tem thời gian được gán, hoàn toàn không gây tắc nghẽn bộ nhớ đệm phần mềm.
Hướng dẫn nạp chương trình eBPF TC qua clsact
Thao tác triển khai eBPF TC trên máy chủ Linux sử dụng bộ công cụ tiêu chuẩn iproute2:
# 1. Gắn hàng đợi clsact vào cổng mạng vật lý WAN
tc qdisc add dev eth0 clsact
# 2. Nạp bộ phân loại BPF vào móc Ingress với chế độ direct-action
tc filter add dev eth0 ingress bpf da obj vpn_router.o sec tc_ingress
# 3. Nạp bộ điều tiết băng thông EDT vào móc Egress
tc filter add dev eth0 egress bpf da obj vpn_shaper.o sec tc_egress
# 4. Kiểm tra danh sách bộ lọc và thông số thống kê
tc filter show dev eth0 ingress
tc filter show dev eth0 egress
Nhờ cơ chế tách biệt móc nối của clsact, việc nạp mới hoặc nâng cấp chương trình BPF diễn ra tức thì, không gây rớt gói và không cần khởi động lại kết nối.
Ứng dụng thực chiến trong hạ tầng mạng RiceGuard
RiceGuard áp dụng sâu rộng eBPF TC trên toàn bộ cụm cổng Anycast phân tán nhằm duy trì chất lượng dịch vụ:
- Kiểm soát hạn mức băng thông từng phiên: Gắn bộ lọc egress eBPF trực tiếp vào từng giao diện kết nối, áp dụng đồng hồ định thời EDT riêng biệt cho mỗi khách hàng nhằm ngăn tình trạng chiếm dụng băng thông làm ảnh hưởng đến các luồng tương tác nhạy cảm với độ trễ.
- Thu thập dữ liệu đo kiểm thời gian thực qua BPF Map: Các bộ phân loại ingress truyền trực tiếp thông số lưu lượng (số gói, tốc độ byte, gói tin dị thường) vào vòng đệm ring buffer để hệ thống phân tích phát hiện bất thường mà không tốn tài nguyên thăm dò user space.
- Tương thích tăng tốc phần cứng SmartNIC: Tại các trung tâm dữ liệu trang bị card mạng thông minh, các quy tắc eBPF TC được nạp thẳng vào mạch ASIC phần cứng, mang lại năng lực định tuyến tốc độ đường truyền 100 Gbps với độ trễ dưới một micro giây.
Sự kết hợp giữa điều phối luồng linh hoạt bằng eBPF TC và kỹ thuật định thời xuất không khóa giúp WireGuard và RiceGuard tối ưu hóa mật độ thông lượng, mang lại kết nối mượt mà và an toàn cho người dùng.



