Skip to main content

Tungsten Fabric vRouter Phần 2: Agent vs Forwarder Sâu, 4 Kiểu Forwarder

Phần 2/18 trong loạt Tungsten Fabric vRouter. Bài này đào sâu đúng phần đã sơ lược ở Bài 1 Mục 3, ngay trước khi dựng lab thật ở Bài 3. Người đọc giả định đã đọc Contrail Architecture Part 3 — Compute Node và vRouter (Section 4, đặc biệt 4.1-4.2) và Part 4 — Forwarding Plane (Section 5.1-5.2, packet walk MPLSoUDP) — bài này viết tiếp ngay sau đoạn đó, không giảng lại.

Mục tiêu bài học: sau bài này bạn phân biệt được 2 kiểu forwarder thật sự của vRouter (kernel module, DPDK) khỏi 2 kỹ thuật liên quan đến phần cứng mà outline ban đầu của series này từng gộp chung thành "4 kiểu forwarder" nhưng quan hệ với vRouter hoàn toàn khác nhau (SR-IOV bypass, SmartNIC offload); và đọc được packet walk byte-level của một gói TCP egress từ VM tới khi rời NIC vật lý — sâu hơn một mức so với bảng "Packet Processing Pipeline" đã có ở Contrail Part 3.

Ba câu hỏi mà bài này trả lời:

  1. "4 kiểu forwarder" mà outline gốc liệt kê có thực sự đều là forwarder không, hay một số trong đó quan hệ với vRouter theo cách hoàn toàn khác?
  2. SR-IOV và SmartNIC offload khác nhau ở điểm nào trong việc vRouter còn kiểm soát được gì trên đường đi packet?
  3. Một gói TCP rời VM tới khi ra khỏi NIC vật lý thay đổi những gì ở mức byte, qua từng hop vật lý?

Mục lục


1. Điểm xuất phát: Agent vs Forwarder theo Contrail Part 3

Không nhắc lại toàn bộ — chỉ tóm tắt đúng phần bài này sẽ dùng làm nền. Contrail Part 3, Section 4 đã chia vRouter thành hai nửa sống ở hai không gian khác nhau trên cùng một compute node:

  • vRouter Agent (user space) — XMPP client nói chuyện với Control Node, cài forwarding state, xử lý first packet (policy, ARP proxy), proxy DNS/DHCP/metadata, phát hiện VM mới.
  • vRouter Forwarding Plane (kernel module hoặc DPDK process) — giữ bảng forwarding (Global IP FIB, MPLS FIB, per-VRF IP/MAC FIB, flow table), thực thi packet processing pipeline: vif binding → flow lookup → FIB lookup → encap/decap → gửi ra NIC.

Outline nội bộ dùng để lên kế hoạch series này (viết trước khi bắt tay viết từng bài) liệt kê "4 kiểu forwarder": kernel, DPDK, SR-IOV bypass, SmartNIC offload — với ý định đào sâu 2 kiểu đầu ở bài này, để dành SR-IOV/SmartNIC cho Bài 11. Trước khi đi tiếp theo đúng kế hoạch đó, cần dừng lại một bước: "kiểu forwarder" có phải cách gọi đúng cho cả 4 thứ này không? Mục 2 trả lời câu hỏi đó bằng cách verify qua nguồn chính thức, thay vì mặc định outline ban đầu đúng.


2. "4 kiểu forwarder" — verify lại trước khi tin outline gốc

SR-IOV: không phải "kiểu forwarder thứ 3" — mà là đường né hẳn vRouter

Tài liệu triển khai SR-IOV cho Tungsten Fabric (qua Mirantis OpenStack for Kubernetes, một bản đóng gói thương mại dùng đúng kiến trúc Tungsten Fabric classic) nói thẳng về giới hạn cốt lõi:

"Since SR-IOV involves bypassing the vRouter, the interfaces don't participate in Tungsten Fabric virtual networks and don't participate in network policies and network services."

Đây là điểm khác biệt về bản chất kiến trúc, không phải khác biệt về hiệu năng như kernel vs DPDK. Với SR-IOV, một Virtual Function (VF) của NIC vật lý được gán thẳng cho VM qua PCI passthrough — gói tin đi thẳng từ VM ra NIC vật lý, không hề đi qua vRouter Agent lẫn Forwarding Plane. Hệ quả trực tiếp: Security Group, Network Policy, Floating IP/SNAT (đã học ở Contrail Part 8) — tất cả đều được vRouter Agent/Forwarder thực thi — không áp dụng được cho interface chạy SR-IOV. Nói "SR-IOV là kiểu forwarder thứ 3 của vRouter" vì vậy sai về bản chất: nó không phải một cách khác để vRouter forward gói, mà là một cách để gói không cần qua vRouter nữa.

💡 Hình dung như thế này: kernel forwarder và DPDK forwarder giống hai nhân viên hải quan khác nhau (một đi bộ chậm nhưng theo đúng quy trình, một đi xe điện nhanh hơn) nhưng cả hai đều kiểm tra hộ chiếu (áp SG/NP/FIP) trước khi cho qua. SR-IOV giống một làn đường VIP đi thẳng ra máy bay, không qua quầy hải quan nào cả — nhanh tuyệt đối, nhưng không ai kiểm tra hộ chiếu ở làn đó nữa.

SmartNIC offload: ngược lại — vẫn là vRouter, chỉ san sẻ việc xuống phần cứng

Trái với SR-IOV, tài liệu về SmartNIC offload cho thấy một mô hình hoàn toàn khác. Có hai nguồn, ở hai mức "chín" khác nhau, cần phân biệt rõ:

(a) Netronome Agilio CX — tính năng đã có tài liệu triển khai cụ thể, mirror nguyên vẹn sang docs.opensdn.io. Tài liệu OpenSDN ghi rõ:

"The Netronome SmartNIC vRouter technology covered in this document is available for evaluation purposes only. It is not intended for deployment in production networks."

Môi trường validate là Red Hat OpenStack Platform Director (RHOSPd) 13 trên RHEL 7.6, container tag 2.38-rhel-queens — nghĩa là tài liệu này khá cũ (theo dòng release OpenStack Queens), và ngay cả tài liệu gốc cũng tự nhận không dành cho production, chỉ để đánh giá. Mục tiêu nêu ra là tăng packets-per-second (PPS) của vRouter và giải phóng CPU core cho VM/VNF khác — nhưng tài liệu không mô tả chi tiết kỹ thuật "cái gì cụ thể được offload xuống NIC" hay vRouter Agent còn kiểm soát phần nào của datapath đã offload.

(b) Generic Smart NIC Offload — một spec thiết kế mức kiến trúc, tìm thấy trong repo tf-specs (chưa xác nhận được đã merge vào code chạy thật hay chỉ dừng ở thiết kế). Spec này mô tả rõ hơn nhiều so với tài liệu Netronome: một lớp offload chung nằm giữa vRouter datapath và SmartNIC, nhận thông báo cấu hình từ Agent rồi dịch thành rule phần cứng, dùng API chuẩn thay vì viết riêng cho từng hãng — ưu tiên DPDK rte_flow cho vRouter-DPDK, để dành Linux TC flower cho vRouter kernel sau. Phạm vi offload ban đầu: phân loại gói tunnel đến trên fabric interface (IP classification, tunnel ID MPLS/VXLAN, flow table lookup) — nếu NIC khớp được rule, nó đánh dấu sẵn flow ID lên gói, giúp vRouter bỏ qua các bước classification đó; gói không khớp vẫn rơi lại xử lý bình thường trong vRouter — tức là offload chỉ tăng tốc, không thay đổi hành vi khi tắt.

Điểm mấu chốt: trong cả hai cách tiếp cận, vRouter Agent vẫn là nơi duy nhất cấu hình rule (SG, NP, FIP, forwarding state không đổi chỗ) — chỉ có phần thực thi match/action lặp lại nhiều lần (datapath) được san sẻ một phần xuống ASIC/SmartNIC để chạy nhanh hơn. Đây là lý do SmartNIC offload xứng đáng gọi là "kiểu forwarder" hơn SR-IOV nhiều: nó vẫn là vRouter, chỉ đổi nơi một phần forwarding chạy, không phải loại bỏ hẳn vRouter khỏi đường đi packet.

💡 Nối tiếp analogy hải quan: SmartNIC offload giống việc quầy hải quan vẫn đứng đó, vẫn theo đúng danh sách kiểm tra do "Agent" (đội trưởng ca trực) lập ra — chỉ là với hành khách đã có vé quen thuộc (rule đã khớp trước đó), có một máy quét tự động (ASIC) làm hộ bước soát vé lặp lại, nhân viên không cần tự tay kiểm tra lại từ đầu mỗi lần.

Liên hệ ngược OVS Bài 15: nếu bạn đã đọc OVS Part 15 — Hardware Offload TC Flower và SmartNIC, mô hình "generic offload layer dùng TC flower/rte_flow" ở đây sẽ rất quen — đúng nguyên lý OvS-TC: OVS thử đẩy flow xuống TC flower trước, thất bại thì rơi lại kernel datapath xử lý bằng CPU. Điểm khác: OVS đã triển khai và tài liệu hóa đầy đủ cấu hình thật (hw-offload=true, tc-policy) từ bản 2.8; còn "Generic SmartNIC Offload" của vRouter, theo nguồn đã đọc, mới dừng ở mức spec thiết kế trong tf-specs, chưa tìm được tài liệu vận hành/cấu hình thật tương đương — cần verify thêm nếu triển khai thật (Bài 11 sẽ đào sâu tiếp, kể cả khả năng phần này phải viết dưới dạng "thiết kế đề xuất, chưa xác nhận đã ship" thay vì "tính năng đang chạy").


3. Bảng so sánh 4 kỹ thuật, đúng vai trò từng cái

Kỹ thuậtvRouter Agent còn kiểm soát?Datapath chạy ở đâuSG/NP/FIP áp dụng?Yêu cầu phần cứngĐộ chín tài liệu (đã verify)
Kernel forwarderCó, đầy đủKernel module (vrouter.ko), CPUNIC bất kỳChính, mặc định — Contrail Part 3
DPDK forwarderCó, đầy đủUserspace poll-mode process, CPU (hugepages, pinned core)NIC hỗ trợ DPDK PMDChính thức, production — Contrail Part 9
SR-IOVKhông — bypass hoàn toànASIC cố định trên NIC (VF gán thẳng VM qua PCI passthrough)KhôngNIC hỗ trợ SR-IOV, đủ số VFCó tài liệu triển khai, nhưng tự nhận giới hạn rõ
SmartNIC offloadCó (control plane) — datapath san sẻ một phầnMột phần trên SmartNIC (ASIC/Arm core), phần còn lại vẫn ở kernel/DPDKCó (agent vẫn cấu hình)SmartNIC hỗ trợ offload (Netronome Agilio đã xác nhận)Netronome: "evaluation only", khá cũ (RHOSP 13); Generic offload: mới ở mức spec, chưa xác nhận đã ship

Hai dòng đầu là forwarder thật sự của vRouter, khác nhau ở chỗ chạy (kernel vs userspace) — đã có bảng so sánh chi tiết hơn (yêu cầu hugepages, CPU pinning, throughput) ở Contrail Part 9, Section 17, không lặp lại ở đây. Điểm khác nhau ở cách gắn VM cũng đáng chú ý: kernel forwarder gắn VM qua tap — interface ảo tiêu chuẩn của Linux, packet đi qua kernel network stack như một NIC thật; DPDK forwarder gắn VM qua vhost-user — một giao thức dựa trên virtio, cho phép QEMU (chạy VM) trao đổi packet trực tiếp với vRouter DPDK (một process userspace) qua vùng nhớ chia sẻ (shared memory), bỏ qua hoàn toàn kernel network stack ở phía host. Hai dòng sau là chủ đề chính của Bài 11 — bài này chỉ dừng ở mức phân loại đúng bản chất, chưa đi vào cấu hình chi tiết.

Kernel / DPDK / SR-IOV / SmartNIC Offload — Ai còn đứng trên đường đi packet?Cùng xuất phát từ VM, nhưng 4 kỹ thuật rẽ 4 hướng rất khác nhau quanh vRouterKernelDPDKSR-IOVSmartNIC OffloadVM (tap/vif)VM (vhost-user)VM (VF passthrough)VM (tap/vif)vRouter AgentXMPP, SG/NP, FIP— đầy đủ —vRouter AgentXMPP, SG/NP, FIP— đầy đủ —vRouter Agentkhông nằm trênđường đi packetvRouter Agentvẫn cấu hình rule— đầy đủ —Forwarderkernel module(vrouter.ko), CPUForwarderuserspace poll-mode(hugepages, pinned CPU)Forwarderkernel/DPDK, một phầnviệc san sẻ xuống NICPhysical NICPhysical NIC(DPDK PMD-bound)Physical NICASIC cố định (VF)SmartNICASIC + Arm coreSG/NP/FIP: CóSG/NP/FIP: CóSG/NP/FIP: KhôngSG/NP/FIP: Có (agent cấu hình)Kernel/DPDK = 2 kiểu forwarder thật, khác nhau ở CHỖ CHẠY (kernel vs userspace).SR-IOV = né hẳn vRouter (đường xám nét đứt phía trên bỏ qua Agent + Forwarder).SmartNIC offload = vẫn là vRouter, chỉ san sẻ một phần datapath xuống ASIC/SmartNIC —Netronome Agilio: "evaluation only"; Generic offload (tf-specs): mới ở mức spec, chưa xác nhận đã ship.

4. Packet walk byte-level: một gói TCP rời VM tới khi ra khỏi NIC vật lý

Contrail Part 4, Section 5.2 đã có packet walk 11 bước cho đúng kịch bản này (VM1a 10.1.1.3 trên Compute1 gửi HTTP đến VM2a 10.1.1.5 trên Compute2, qua MPLSoUDP) — bài này dùng lại đúng kịch bản đó, không lặp lại 11 bước, mà zoom sâu hơn vào hai chỗ Part 4 chỉ lướt qua: (a) cấu trúc byte thật của từng header thay vì ký hiệu [MPLS: label=51, TTL=64], và (b) chuyện gì xảy ra ở từng hop vật lý giữa Compute1 và Compute2 — điều Part 4 chỉ gói gọn trong một dòng "Packet đi qua ToR → Spine → ToR2".

Checkpoint 1 — packet rời VM, trước khi chạm vRouter

VM1a chỉ biết gửi một frame Ethernet bình thường (theo RFC 894, Ethernet II framing):

Ethernet: dst=<MAC gateway ảo> src=<MAC VM1a> type=0x0800 (IPv4)
IPv4: src=10.1.1.3 dst=10.1.1.5 proto=6 (TCP) TTL=64
TCP: sport=X dport=80

Không có gì đặc biệt ở bước này — đây là một frame Ethernet/IP/TCP tiêu chuẩn, giống hệt bất kỳ gói nào một VM Linux thông thường gửi đi. vRouter chưa chạm vào.

Checkpoint 2 — sau khi Forwarding Plane + Agent xử lý (vẫn trên Compute1)

Đúng như Part 4 đã mô tả (Bước 3-6): vif binding → flow miss → PUNT lên Agent → Agent check policy, cài flow entry → FIB lookup ra next-hop là tunnel tới Compute2 với MPLS label 51. Ở bước này payload gói chưa đổi gì — chỉ có state nội bộ vRouter (flow table, FIB) được cập nhật để quyết định encap thế nào.

Checkpoint 3 — sau khi encapsulate (MPLSoUDP), rời vRouter Forwarding Plane

Đây là chỗ đáng nhìn kỹ ở mức bit. Theo RFC 3032 (MPLS label stack encoding), header MPLS 32-bit chia thành 4 field:

0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Label (20 bit) | EXP |S| TTL |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Với label=51 (do vRouter compute1 tự cấp phát nội bộ — locally significant, không phải giá trị global), EXP thường =0 (không dùng cho QoS ở đây), S=1 (bottom-of-stack — chỉ 1 label, không stack chồng thêm), TTL=64 (giá trị outer, độc lập với TTL inner). Gói đầy đủ sau encap:

Ethernet outer: dst=<MAC next-hop, ví dụ ToR1> src=<MAC Compute1 uplink> type=0x0800
IPv4 outer: src=192.168.1.10 (Compute1) dst=192.168.1.20 (Compute2) proto=17 (UDP) TTL=64
UDP outer: sport=hash(inner 5-tuple) dport=6635 (IANA-assigned, RFC 7510 — xem ghi chú bên dưới)
MPLS: label=51 EXP=0 S=1 TTL=64
IPv4 inner: src=10.1.1.3 dst=10.1.1.5 proto=6 TTL=64 (nguyên vẹn, không đổi)
TCP inner: sport=X dport=80 (nguyên vẹn, không đổi)

Ba điểm đáng chú ý mà bảng ký hiệu [...] của Part 4 không thể hiện rõ:

  1. UDP source port không cố định — nó là kết quả hash 5-tuple của gói inner (đã nhắc ở Contrail Part 4 mục so sánh encapsulation), mục đích tạo entropy cho ECMP hash ở underlay — hai flow inner khác nhau sẽ có UDP source port outer khác nhau, dù cùng đi giữa Compute1-Compute2, giúp load-balance qua nhiều path Spine khác nhau.
  2. Overhead byte thật: Ethernet (14) + IPv4 (20) + UDP (8) + MPLS (4) = 46 byte thêm vào trước inner packet với MPLSoUDP. VXLAN (sẽ học kỹ ở Bài 8) cộng thêm Ethernet(14)+IPv4(20)+UDP(8)+VXLAN(8) = 50 byte — nhiều hơn 4 byte vì VXLAN header 8 byte so với MPLS chỉ 4 byte, nhưng VXLAN không cần thêm Ethernet inner riêng cho L3-only traffic trong khi MPLSoUDP L2 mode cần. Overhead này ăn trực tiếp vào MTU khả dụng của VM — một lý do thực tế phải tăng MTU underlay (jumbo frame) khi triển khai overlay.
  3. TTL inner giữ nguyên 64, TTL outer cũng khởi tạo 64 nhưng độc lập — hai TTL này không liên quan nhau tại điểm encap. Việc TTL outer có "kế thừa" giá trị còn lại của TTL inner hay luôn khởi tạo lại theo cấu hình cố định (hai mô hình uniform vs pipe theo RFC 3443 cho tunnel nói chung) — chưa verify được cụ thể cho vRouter qua nguồn đã đọc ở bài này, cần kiểm tra qua tcpdump thật khi có lab (Bài 4).

Checkpoint 4 — hop-by-hop qua underlay (ToR1 → Spine → ToR2)

Đây là phần Part 4 chỉ nói "underlay chỉ thấy outer IP" — đúng, nhưng "thấy" cụ thể nghĩa là gì? Underlay là một fabric IP thuần túy (ECMP Clos, cùng nguyên lý "mọi loopback phải thấy nhau" đã học ở EVPN Part 01, Section 3) — khác với world EVPN-VXLAN nơi chính leaf switch làm VTEP, ở đây ToR/Spine chỉ đóng vai trò router L3 thuần túy cho outer IP, không biết gì về MPLS label hay inner packet bên trong UDP payload:

Compute1 → ToR1: Ethernet(dst=MAC-ToR1, src=MAC-Compute1) [IP/UDP/MPLS/inner không đổi]
ToR1 → Spine: Ethernet(dst=MAC-Spine, src=MAC-ToR1) IP outer TTL: 64→63 [còn lại không đổi]
Spine → ToR2: Ethernet(dst=MAC-ToR2, src=MAC-Spine) IP outer TTL: 63→62 [còn lại không đổi]
ToR2 → Compute2: Ethernet(dst=MAC-Compute2, src=MAC-ToR2) IP outer TTL: 62→61 [còn lại không đổi]

mỗi hop L3, chỉ có Ethernet header outer bị viết lại hoàn toàn (MAC nguồn/đích đổi theo từng chặng — hành vi L3 routing tiêu chuẩn, giống hệt nguyên lý đã học khi một IP fabric route gói giữa các loopback) và TTL của IP outer giảm 1 mỗi hop. Toàn bộ phần từ UDP header trở vào trong (UDP/MPLS/inner IP/inner TCP) — không một byte nào bị chạm tới trên suốt hành trình qua fabric. Đây chính là bản chất "underlay không biết gì về overlay": với ToR/Spine, gói này chỉ là một gói UDP bình thường giữa hai IP 192.168.1.10 và 192.168.1.20.

Checkpoint 5 — Compute2 nhận, decap

Compute2 nhận outer IP dst=192.168.1.20 khớp chính nó → decap UDP/IP outer → đọc MPLS label=51 → tra MPLS FIB ra routing instance VN-A → decap MPLS → inner IP lộ ra nguyên vẹn như Checkpoint 1 → tra IP FIB VN-A → giao cho vif của VM2a. Gói tới VM2a với đúng nội dung Ethernet/IP/TCP ban đầu — VM1a và VM2a hoàn toàn không biết có 46 byte overhead và 3 hop L3 vừa xảy ra ở giữa.

⚠️ Cảnh báo verify (áp dụng quy ước Mục "Cảnh báo rủi ro" của outline series): giá trị UDP dst port 6635 dùng trong ví dụ này là port IANA-assigned theo RFC 7510 — Contrail/tf-vrouter đã chuyển sang dùng port này khi transmit từ bản R3.0 (2016), thay cho port proprietary 51234 trước đó (vẫn tiếp tục nhận cả hai port khi receive để tương thích ngược, xem Nguồn tham khảo). Đây là thay đổi đã tồn tại gần 10 năm trong chính codebase, nhưng chưa re-verify riêng trên OpenSDN hiện tại ở bài này. Bài 8 (bài trọng tâm Module 2, chủ đề MPLSoUDP vs VXLAN) sẽ verify lại cụ thể qua docs.opensdn.io/source opensdn-io/tf-vrouter trước khi dùng con số này làm căn cứ cấu hình thật.


5. CLI: chưa có lab, chờ Bài 3

Giống Bài 1, series này chưa có cluster nào dựng sẵn để chạy lệnh thật — lsmod | grep vrouter (xác nhận vrouter.ko đã load) hay ovs-style version check đều cần một compute node OpenSDN thật. Bộ lệnh introspect vif/rt/nh/mpls/flow đã có cú pháp đầy đủ ở Contrail Part 3 — Bài 4 (sau khi Bài 3 dựng lab xong) sẽ chạy lại đúng các lệnh đó với output thật, đối chiếu với packet walk byte-level vừa học ở Mục 4.


Bài tập cuối bài

  1. Cho một máy chủ giả định: NIC không hỗ trợ DPDK PMD, không hỗ trợ SR-IOV (không có VF), nhưng vẫn cần chạy VM đa tenant với Security Group đầy đủ. Từ bảng Mục 3, chọn đúng 1 trong 4 kỹ thuật và giải thích bằng đúng 1 câu vì sao 3 kỹ thuật còn lại không khả thi hoặc không phù hợp cho máy này.
  2. Không nhìn lại Mục 4, tự liệt kê byte-level: những field nào trong header (Ethernet/IP/UDP/MPLS) thay đổi ở mỗi hop L3 giữa Compute1 và Compute2, và những field nào giữ nguyên hoàn toàn từ lúc rời Compute1 tới lúc tới Compute2. So lại với Checkpoint 4 — nếu nhầm phần "Ethernet header outer bị viết lại mỗi hop nhưng payload từ UDP trở vào không đổi", đọc lại Checkpoint 4 trước khi sang Bài 3.

Nguồn tham khảo

  • "Since SR-IOV involves bypassing the vRouter, the interfaces don't participate in Tungsten Fabric virtual networks and don't participate in network policies and network services"Enable SR-IOV for Tungsten Fabric, Mirantis OpenStack for Kubernetes docs, truy cập 02/09/2026.
  • "The Netronome SmartNIC vRouter technology covered in this document is available for evaluation purposes only. It is not intended for deployment in production networks", môi trường RHOSPd13/RHEL7.6, container tag 2.38-rhel-queensUsing Netronome SmartNIC vRouter with OpenSDN, docs.opensdn.io, truy cập 02/09/2026 (mirror nguyên vẹn từ tài liệu Tungsten Fabric gốc).
  • Thiết kế "Generic Smart NIC Offload": lớp offload chung giữa vRouter datapath và SmartNIC, ưu tiên DPDK rte_flow, để dành Linux TC flower cho kernel vRouter sau, phạm vi offload ban đầu (IP/tunnel classification, flow table lookup) — tf-specs/smart-nic-generic-offload.md, truy cập 02/09/2026. Chưa xác nhận được spec này đã merge vào code chạy thật hay chỉ dừng ở thiết kế — cần verify thêm ở Bài 11.
  • Cấu trúc MPLS label 32-bit (Label/EXP/S/TTL) — RFC 3032, Multiprotocol Label Switching (MPLS) Label Stack Encoding.
  • Ethernet II framing — RFC 894, A Standard for the Transmission of IP Datagrams over Ethernet Networks.
  • Cổng UDP đích chuẩn cho MPLS-in-UDP là 6635, IANA-assigned — RFC 7510, Encapsulating MPLS in UDP.
  • Contrail/tf-vrouter chuyển default destination port MPLSoUDP từ 51234 (proprietary) sang 6635 (IANA-assigned) khi transmit, bắt đầu từ release R3.0 (2016); tiếp tục nhận cả 2 port khi receive để tương thích ngược — Bug #1420900, Launchpad Juniper OpenStack, truy cập 02/09/2026.
  • Mô hình offload TC flower/rte_flow, cấu hình hw-offload/tc-policy đã triển khai thật trên OVS — OVS Part 15 — Hardware Offload TC Flower và SmartNIC, dùng làm đối chiếu "công nghệ tương tự đã triển khai xong ở hệ sinh thái khác".
  • Underlay IP fabric, nguyên tắc "mọi loopback phải thấy nhau", ECMP Clos — EVPN Part 01, Section 3.
  • Packet Processing Pipeline, cấu trúc bảng forwarding, CLI introspect — Contrail Architecture Part 3, Section 4.
  • Packet walk 11 bước MPLSoUDP, so sánh 3 loại encapsulation — Contrail Architecture Part 4, Section 5.
  • Bảng so sánh Kernel vs DPDK, yêu cầu hugepages/CPU pinning — Contrail Architecture Part 9, Section 17.

Tiếp theo: Bài 3 — Lab đầu tiên: dựng OpenSDN all-in-one.