Skip to main content

OVS Phần 8: VLAN Trunking & Isolation — 5 vlan_mode và QinQ

Phần 8/21 trong loạt Open vSwitch (OVS) — nối tiếp Phần 7, nơi VLAN chỉ xuất hiện đúng một câu set port vnet0 tag=100 áp lại nguyên xi cú pháp Bài 5. Bài 5 Mục 3 đã nhắc tên cột vlan_mode và nói nó quyết định 5 hành vi khác nhau, nhưng chỉ dừng ở hai trường hợp cơ bản (access, trunk) rồi hẹn đào sâu ở đây. Bài này mở đúng cái hẹn đó: 5 giá trị vlan_mode đầy đủ, một trunk port thật nối hai OVS bridge, và dot1q-tunnel — chế độ QinQ dễ hiểu nhầm nhất trong toàn bộ schema Port.

Mục tiêu bài học: sau bài này bạn phân biệt chính xác cả 5 giá trị vlan_mode (không chỉ 2 giá trị cơ bản Bài 5 đã dùng), tự dựng được một trunk port thật giữ nguyên VLAN tag giữa hai OVS bridge, và hiểu đúng dot1q-tunnel/QinQ giải quyết bài toán gì — kể cả biết trước cái bẫy cấu hình khiến QinQ "chạy nhưng sai" nếu bỏ qua một tùy chọn ít ai để ý.

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

  1. 5 giá trị vlan_mode khác nhau chính xác ở đâu — đặc biệt native-taggednative-untagged, cặp dễ nhầm nhất?
  2. Trunk port thật giữa hai OVS bridge hoạt động thế nào, và VLAN tag có thật sự "sống sót" nguyên vẹn qua uplink không?
  3. dot1q-tunnel (QinQ) trên OVS giải quyết bài toán gì, và cấu hình đúng cần thêm tùy chọn nào ngoài tag=/cvlans=?

Mục lục


1. Nhắc lại: tag và trunks đã đủ để mô tả VLAN chưa?

Bài 5 Mục 3 đã dựng hai trường hợp cơ bản nhất: đặt tag=10 mà không đặt trunks → OVS tự hiểu là access port VLAN 10; đặt trunks=10,20 mà không đặt tag → OVS tự hiểu là trunk port cho VLAN 10 và 20. Bài đó cũng đã trích đúng một câu quan trọng từ tài liệu schema (ovs-vswitchd.conf.db): khi cột vlan_mode để trống, "a default mode is selected as follows: if tag contains a value, the port is an access port... Otherwise, the port is a trunk port".

Câu đó ngầm nói một điều: vlan_mode không phải cột phụ, nó là cột quyết định thật sự hành vi của port — tag/trunks chỉ là dữ liệu đầu vào, còn vlan_mode mới là cái quy định cách dữ liệu đó được diễn giải. Hai trường hợp Bài 5 dùng chỉ là 2 trong 5 giá trị hợp lệ. Ba giá trị còn lại — native-tagged, native-untagged, dot1q-tunnel — không tự suy ra được từ tag/trunks một cách mặc định, bắt buộc phải gõ tường minh vlan_mode=..., và đây chính xác là ba giá trị gây nhầm lẫn nhiều nhất khi mới học OVS, kể cả với người đã quen VLAN vật lý.


2. Năm giá trị vlan_mode: access, trunk và ba biến thể ít ai để ý

Tài liệu schema chính thức (ovs-vswitchd.conf.db(5)) mô tả chính xác hành vi ingress (packet đi vào port) và egress (packet đi ra port) cho từng giá trị. Dịch sát nghĩa, giữ nguyên các cụm kỹ thuật quan trọng:

  • access: "An access port carries packets on exactly one VLAN specified in the tag column. Packets egressing on an access port have no 802.1Q header." — đúng như Bài 5 đã dùng: một VLAN duy nhất, egress luôn không có tag.
  • trunk: "A trunk port carries packets on one or more specified VLANs specified in the trunks column (often, on every VLAN). A packet that ingresses on a trunk port is in the VLAN specified in its 802.1Q header, or VLAN 0 if the packet has no 802.1Q header." — điểm hay bị bỏ sót: packet không tag đi vào một trunk port không bị từ chối, nó được xếp vào VLAN 0 (thường không có thiết bị nào thật sự dùng VLAN 0, nên trong thực tế coi như "bị bỏ qua" trừ khi bạn cố tình trunk cả VLAN 0).
  • native-tagged: "A native-tagged port resembles a trunk port, with the exception that a packet without an 802.1Q header that ingresses on a native-tagged port is in the native VLAN (specified in the tag column)." — vẫn là trunk (nhiều VLAN qua trunks), nhưng thêm một VLAN "mặc định" (tag) dành cho packet không tag đi vào.
  • native-untagged: "A native-untagged port resembles a native-tagged port, with the exception that a packet that egresses on a native-untagged port in the native VLAN will not have an 802.1Q header." — giống hệt native-tagged, chỉ khác đúng một chỗ: khi packet thuộc VLAN native đi ra khỏi port, nó bị bỏ tag trước khi ra.
  • dot1q-tunnel: theo mô tả man page, đây là chế độ "giống access port" ở chỗ chỉ khai một VLAN duy nhất trong cột tag — nhưng khác hẳn access ở cách xử lý packet đã có sẵn 802.1Q header đi vào: thay vì coi đó là lỗi hay bỏ tag, port này đối xử với nó như một frame double-tagged, dùng tag làm outer "service VLAN". Đây chính là QinQ, đào sâu ở Mục 5.
Năm giá trị vlan_mode trên Port tableovs-vswitchd.conf.db(5) — Port.vlan_modevlan_modeHành vi ingress / egress (tóm tắt theo man page)access1 VLAN duy nhất, khai trong cột tagEgress LUÔN không có 802.1Q headertrunkNhiều VLAN trong trunks (rỗng = mọi VLAN)Ingress: theo đúng tag 802.1Q; untagged = VLAN 0native-taggedGiống trunk, nhưng untagged ingressđược coi là VLAN native (cột tag)Egress ở VLAN native VẪN giữ tagnative-untaggedGiống native-tagged, khác đúng 1 điểm:Egress ở VLAN native thì KHÔNG có tag(giống hệt native VLAN kiểu Cisco)dot1q-tunnel1 VLAN dịch vụ duy nhất (tag = outer S-TAG)Frame khách (giới hạn bởi cvlans) bị đóngthêm 1 lớp tag ngoài — QinQ / 802.1adKhông set vlan_mode? OVS tự suy: có tag → access; có trunks (không tag) → trunk

Ba giá trị native-*dot1q-tunnel không nằm trong quy tắc suy luận mặc định — bỏ trống vlan_mode không bao giờ tự ra một trong ba giá trị này, dù tagtrunks có được đặt cùng lúc thế nào đi nữa. Muốn dùng, bắt buộc gõ tường minh vlan_mode=native-tagged (hoặc native-untagged, dot1q-tunnel).


Bài 5 Mục 3 mới tạo một trunk port đơn lẻ (uplink0, trunks=10,20) và dừng ở đó — "chưa cần traffic thật đi qua nó". Giờ là lúc cho traffic thật đi qua, đúng kịch bản một trunk port thật sự tồn tại để làm: nối hai switch, giữ nguyên nhiều VLAN qua đúng một sợi cáp (hoặc một veth pair mô phỏng uplink vật lý, đúng phong cách lab từ Bài 4).

Dựng hai OVS bridge br-a/br-b (mô phỏng hai OVS host khác nhau, đặt cùng máy cho gọn — thực tế đây là hai uplink port trên hai hypervisor riêng biệt nối qua switch vật lý), nối chúng bằng một veth pair đóng vai trò uplink, cả hai đầu đặt vlan_mode=trunk:

sudo ovs-vsctl add-br br-a
sudo ovs-vsctl add-br br-b

# veth pair mô phỏng đường uplink vật lý nối 2 OVS host
sudo ip link add trunk-a type veth peer name trunk-b
sudo ip link set trunk-a up
sudo ip link set trunk-b up

# Trunk cả 2 đầu, cho qua đúng VLAN 10 và 20 (không trunk "mọi VLAN" để tránh rò rỉ)
sudo ovs-vsctl add-port br-a trunk-a -- set port trunk-a vlan_mode=trunk trunks=10,20
sudo ovs-vsctl add-port br-b trunk-b -- set port trunk-b vlan_mode=trunk trunks=10,20

Mỗi bên gắn hai namespace access port, một VLAN 10 và một VLAN 20 — bên A đặt IP .11, bên B đặt IP .12 để phân biệt:

# Bên A: 2 namespace VLAN 10 và VLAN 20
for v in 10 20; do
sudo ip netns add a$v
sudo ip link add veth-a$v type veth peer name veth-a$v-ns
sudo ip link set veth-a$v-ns netns a$v
sudo ip netns exec a$v ip link set veth-a$v-ns name eth0
sudo ip netns exec a$v ip addr add 10.0.$v.11/24 dev eth0
sudo ip netns exec a$v ip link set eth0 up
sudo ip link set veth-a$v up
sudo ovs-vsctl add-port br-a veth-a$v tag=$v
done

# Bên B: y hệt, đổi IP .12
for v in 10 20; do
sudo ip netns add b$v
sudo ip link add veth-b$v type veth peer name veth-b$v-ns
sudo ip link set veth-b$v-ns netns b$v
sudo ip netns exec b$v ip link set veth-b$v-ns name eth0
sudo ip netns exec b$v ip addr add 10.0.$v.12/24 dev eth0
sudo ip netns exec b$v ip link set eth0 up
sudo ip link set veth-b$v up
sudo ovs-vsctl add-port br-b veth-b$v tag=$v
done

Kiểm chứng đúng điều Mục tiêu bài học đã hứa — VLAN tag phải giữ nguyên qua trunk, cùng VLAN thì thông dù khác bridge, khác VLAN thì cô lập dù đi qua cùng một sợi trunk:

# Cùng VLAN 10, khác bridge (a10 -> b10) — PHẢI thông
sudo ip netns exec a10 ping -c 3 10.0.10.12

# Khác VLAN (a10 -> b20) — PHẢI timeout, dù đi qua đúng trunk vừa dựng
sudo ip netns exec a10 ping -c 3 -W 1 10.0.20.12
# Output minh họa — a10 tới b10 (cùng VLAN 10)
3 packets transmitted, 3 received, 0% packet loss, time 2044ms

# Output minh họa — a10 tới b20 (khác VLAN)
3 packets transmitted, 0 received, 100% packet loss, time 2041ms

(Output minh họa — cấu trúc đúng theo lệnh thật, số liệu cụ thể tùy máy.) Không có gì huyền bí ở đây, nhưng đáng để bạn nhìn kỹ một lần đúng chuyện gì vừa xảy ra trên dây: gói ICMP từ a10 rời veth-a10 không tag (vì đó là access port), br-a gắn thêm 802.1Q tag VLAN 10 khi đẩy ra trunk-a, gói đi qua veth pair mang nguyên tag đó sang trunk-b, br-b đọc đúng tag VLAN 10 và forward vào đúng veth-b10 — access port bên B lại bóc tag ra trước khi tới eth0 trong namespace b10. VLAN "sống sót" không phải vì nó là một khái niệm trừu tượng, mà vì cả hai đầu trunk port cùng đồng ý đọc/ghi đúng một con số trong đúng một trường của header 802.1Q.

Dùng ovs-vsctl show hoặc ovsdb-client dump Open_vSwitch Port (Bài 5 Mục 4) trên cả hai bridge để bạn tự xác nhận trunk-a/trunk-btrunks: [10, 20] còn bốn access port kia có đúng tag tương ứng — thói quen "đừng chỉ tin ping chạy đúng, đọc luôn OVSDB để chắc chắn vì sao nó đúng" nên giữ từ đây trở đi.


4. native-tagged và native-untagged: khi nào cần một VLAN native kiểu switch vật lý

💡 Hình dung như thế này: một trunk port thường giống cổng soát vé chung của một buổi hòa nhạc nhiều khu vực — mỗi khách phải đeo vòng tay đúng màu (VLAN tag) của khu mình được vào, khách không đeo vòng tay bị mặc định coi là đi lạc (VLAN 0), gần như chắc chắn bị chặn. native-tagged/native-untagged thêm một khu "phổ thông" mặc định cho khách không đeo vòng tay, thay vì chặn họ — chỉ khác nhau ở khâu ra cổng: native-tagged vẫn bắt khách khu phổ thông đeo vòng tay khi đi ra (để soát vé audit dễ, đồng nhất với các khu khác), còn native-untagged cho khách khu phổ thông tháo vòng tay ra khi rời cổng — với họ, buổi hòa nhạc trông y hệt như không hề có khái niệm "nhiều khu" nào cả.

Đây chính là khái niệm switch vật lý gọi là native VLAN trên trunk port (Cisco, Juniper đều có khái niệm tương đương) — OVS không phát minh ra ý tưởng mới, chỉ tách nó thành hai biến thể tường minh thay vì gộp chung một hành vi cố định. Ví dụ chính thức từ FAQ VLAN của dự án, dựng một cổng uplink vật lý cần vừa trunk nhiều VLAN vừa có một VLAN mặc định cho traffic không tag đi vào:

sudo ovs-vsctl add-br br0
sudo ovs-vsctl add-port br0 eth0 tag=9 vlan_mode=native-tagged

Tài liệu FAQ ghi thêm ngay sau ví dụ này: "In this situation, 'native-untagged' mode will probably work equally well." — với nhiều switch vật lý phía đối diện (nơi VLAN native theo mặc định luôn đi untagged, đúng hành vi 802.1Q gốc), native-untagged thường là lựa chọn tương thích hơn; native-tagged hữu ích khi bạn muốn nhìn thấy VLAN native tường minh trong mọi gói tin đi qua dump-flows/tcpdump, kể cả gói thuộc VLAN mặc định, để không phải đoán "gói không tag này đang thuộc VLAN nào".

Tự lab nhanh trên đúng br-a vừa dựng ở Mục 3 — đổi veth-a10 (đang là access VLAN 10) thành cổng nhận cả traffic không tag lẫn VLAN 20 trunk qua, coi VLAN 10 là native:

sudo ovs-vsctl set port veth-a10 tag=10 trunks=10,20 vlan_mode=native-untagged

Từ giờ, veth-a10 vừa nhận đúng gói tag VLAN 20 (forward vào namespace nếu namespace đó lắng nghe VLAN 20 — thường không, chỉ để minh họa cơ chế) vừa nhận gói không tag (coi là VLAN 10, và ra khỏi port cũng không tag, đúng định nghĩa native-untagged). Đổi lại access (vlan_mode=access, bỏ trunks) sau khi bạn lab xong, để không phá vỡ bài tập ở Mục 3.


5. dot1q-tunnel (QinQ): khi một lớp tag không đủ, phải đóng gói VLAN trong VLAN

💡 Hình dung như thế này: một VLAN tag 802.1Q thường giống địa chỉ ghi trên phong bì thư — đủ để bưu điện nội địa phân loại. Nhưng khi một nhà mạng (hoặc một OVS bridge đóng vai trò uplink dùng chung cho nhiều khách hàng) cần vận chuyển hàng nghìn phong bì đã có sẵn địa chỉ riêng của nhiều khách hàng khác nhau qua cùng một tuyến, cách làm không phải mở từng phong bì ra đọc — mà bỏ nguyên cả phong bì đó vào một túi vận chuyển lớn hơn, dán đúng một nhãn tuyến (VLAN dịch vụ) lên túi. Người vận chuyển tuyến chỉ cần đọc nhãn túi ngoài, không cần biết (và không được đọc) địa chỉ ghi trên từng phong bì bên trong. Tới nơi, túi được bóc ra, từng phong bì lấy lại nguyên vẹn địa chỉ gốc như chưa từng bị đóng gói.

dot1q-tunnel chính là cơ chế đó, đúng chuẩn 802.1ad, thường gọi bằng cái tên quen thuộc hơn: QinQ ("VLAN trong VLAN"). Man page mô tả nó "somewhat like an access port" — chỉ khai một VLAN duy nhất trong tag — nhưng khác access ở chỗ nó không coi 802.1Q header sẵn có trên packet đi vào là điều bất thường; nó coi packet đó là "double-tagged with the outer service VLAN tag", tức là gắn thêm đúng một lớp tag mới (outer, hay còn gọi S-TAG — service tag) bọc quanh tag gốc của khách hàng (inner, C-TAG — customer tag) mà không đụng vào C-TAG đó.

Cột đi kèm bắt buộc phải biết: cvlans — man page định nghĩa: "For a dot1q-tunnel port, the customer VLANs that this port includes. If this is empty, the port includes all customer VLANs." Nói cách khác, tag quyết định "cái túi vận chuyển" mang nhãn gì (outer S-VLAN), còn cvlans quyết định những "phong bì" (VLAN khách hàng) nào được phép bỏ vào túi đó — để trống nghĩa là chấp nhận mọi VLAN khách hàng.

dot1q-tunnel (QinQ): S-TAG bọc ngoài, C-TAG khách giữ nguyênvlan_mode=dot1q-tunnel — tag = outer S-VLAN — cvlans = customer VLAN cho phépCustomer side AVLAN 10, VLAN 20(tagged 802.1Q hoặc untagged)port: vlan_mode=dot1q-tunneltag=100 (S-VLAN), cvlans=10,20Provider trunk chỉ thấy VLAN 100Customer side BVLAN 10, VLAN 20khôi phục nguyên vẹn ở đầu kiaCả 2 đầu cùng đặt tag=100 — S-TAG thêm lúc vào, gỡ lúc ra; C-TAG gốc của khách không đổiFrame thật đi trên provider trunk (double-tagged)Dest MACSrc MACS-TAG (outer)0x88a8, VLAN 100C-TAG (inner)0x8100, VLAN 10EtherTypePayloadTPID ngoài chọn qua other_config:qinq-ethtype — mặc định 802.1ad (0x88a8), đổi 802.1q (0x8100) nếu cầnDatapath mặc định chỉ đọc 1 lớp tag — cần other_config:vlan-limit=0 (hoặc 2) mới match được cả C-TAG bên trong

Hai chi tiết cấu hình dễ bỏ sót, cả hai đều nằm ở bảng Open_vSwitch (cấu hình toàn cục, không phải trên từng Port):

  • other_config:qinq-ethtype — chọn EtherType/TPID (Tag Protocol Identifier, 2 byte đầu tiên của header 802.1Q/802.1ad, giá trị này báo cho thiết bị nhận biết "đây là một VLAN tag, không phải payload") cho lớp S-TAG ngoài cùng. Man page ghi: "optional string, either 802.1ad or 802.1q" — mặc định là 802.1ad (TPID 0x88a8, đúng chuẩn QinQ chính thức); đổi sang 802.1q (TPID 0x8100, cùng giá trị với tag khách hàng thông thường) chỉ cần thiết khi thiết bị phía đối diện không hỗ trợ đọc 0x88a8.
  • other_config:vlan-limit — đây là chỗ dễ khiến QinQ "cấu hình đúng theo hướng dẫn nhưng vẫn không hoạt động đúng" nếu bỏ qua. Man page ghi rõ: "Limits the number of VLAN headers that can be matched to the specified number. Further VLAN headers will be treated as payload", và mặc định: "If this value is absent, the default is currently 1. This maintains backward compatibility with controllers that were designed for use with Open vSwitch versions earlier than 2.8, which only supported one VLAN." Nói thẳng ra: mặc định OVS chỉ parse một lớp VLAN header; với một port dot1q-tunnel, muốn OVS thật sự nhìn xuyên qua được cả C-TAG bên trong (để match/log/troubleshoot đúng), phải nâng giới hạn này lên bằng tay:
sudo ovs-vsctl set Open_vSwitch . other_config:vlan-limit=0

Tạo một port dot1q-tunnel hoàn chỉnh, gộp cả tag/cvlans/vlan_mode vào đúng một transaction (đúng thói quen Bài 5 Mục 5 đã dạy):

sudo ovs-vsctl add-br br-provider
sudo ovs-vsctl \
-- add-port br-provider cust-uplink \
-- set port cust-uplink tag=100 vlan_mode=dot1q-tunnel cvlans=10,20 \
-- set Open_vSwitch . other_config:vlan-limit=0

Đọc lại đúng cấu hình vừa tạo để tự xác nhận, thay vì chỉ tin lệnh chạy không báo lỗi:

sudo ovsdb-client dump Open_vSwitch Port
# Output minh họa
Port table
_uuid ... name tag trunks cvlans vlan_mode
--------------- --- --------------- ---- ------- -------- --------------
7f2a1e00-.... ... "cust-uplink" 100 [] [10, 20] "dot1q-tunnel"

(Output minh họa — cấu trúc đúng theo lệnh thật, số liệu cụ thể tùy máy; số cột thật nhiều hơn, đã lược bớt để dễ đọc.) trunks để rỗng — đúng, dot1q-tunnel không dùng trunks, việc lọc VLAN khách hàng là việc của cvlans, hai cột phục vụ hai vai trò khác nhau dù nhìn qua bạn có thể tưởng chúng giống nhau.

Cần verify thêm nếu triển khai production thật: dot1q-tunnel được thêm vào OVS từ bản 2.8.0 (2017) và cần kernel Linux 4.9+ để datapath kernel xử lý đúng — nếu bridge đang chạy datapath_type=netdev (userspace, Bài 3/14) thay vì kernel datapath mặc định, hành vi giới hạn kernel version này không áp dụng theo cùng cách, nên tự kiểm tra lại theo đúng loại datapath đang dùng trước khi đưa vào production.

Nếu chỉ nhớ được một điều sau bài này, hãy nhớ: vlan_mode mới là cột quyết định thật sự — tag/trunks/cvlans chỉ là dữ liệu đầu vào, còn vlan_mode quy định OVS diễn giải dữ liệu đó theo nghĩa nào. Và riêng dot1q-tunnel là giá trị duy nhất trong năm giá trị đó "khai đúng vẫn chạy sai" nếu thiếu một bước ở bảng Open_vSwitch: quên nâng other_config:vlan-limit lên khỏi mặc định 1, QinQ vẫn double-tag đúng trên dây, nhưng OVS sẽ không bao giờ tự nhìn xuyên qua được lớp C-TAG bên trong để bạn match/troubleshoot nó.


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

  1. Dựng lại đúng lab Mục 3 (hai bridge br-a/br-b, trunk qua veth pair) nhưng đổi trunk port sang vlan_mode=native-untagged với tag=10 (VLAN 10 làm native) thay vì trunk thường. Từ một namespace mới không gắn access port (dùng thẳng một veth cắm trực tiếp cạnh trunk port, gửi packet không tag), xác nhận packet đó được xử lý như thuộc VLAN 10 — trong khi ở cấu hình vlan_mode=trunk thuần Mục 3, packet không tag tương tự sẽ bị coi là VLAN 0 và không tới được namespace nào.
  2. Dựng port dot1q-tunnel như Mục 5, sau đó cố tình gửi một frame đã có sẵn tag VLAN 30 (không nằm trong cvlans=10,20) qua port đó bằng ip link add ... type vlan id 30 trên đầu gửi. Dùng tcpdump -e -n ở đầu nhận (hoặc ovs-appctl dpctl/dump-flows nếu chạy kernel datapath) để tự quan sát: frame VLAN 30 có bị port từ chối/không match, hay vẫn lọt qua theo cách khác — đối chiếu lại đúng câu định nghĩa cvlans đã trích ở Mục 5.

Nguồn tham khảo

  • Định nghĩa đầy đủ 5 giá trị Port.vlan_mode (access, trunk, native-tagged, native-untagged, dot1q-tunnel), cột tag/trunks/cvlans, và quy tắc suy luận mặc định khi bỏ trống vlan_mode — 2026, ovs-vswitchd.conf.db(5), openvswitch.org.
  • Open_vSwitch.other_config:qinq-ethtype: "optional string, either 802.1ad or 802.1q", TPID 0x88a8/0x8100 tương ứng, mặc định 802.1ad — cùng nguồn ovs-vswitchd.conf.db(5) ở trên.
  • Open_vSwitch.other_config:vlan-limit: giới hạn số lớp VLAN header datapath match được, mặc định 1 để tương thích ngược với controller viết cho OVS trước bản 2.8, cần đặt 0 hoặc 2 để QinQ match được cả VLAN header thứ hai — cùng nguồn ovs-vswitchd.conf.db(5) ở trên (chi tiết verify thêm ngoài danh sách research ban đầu, không có trong outline gốc).
  • Ví dụ tag=9 vlan_mode=native-tagged cho uplink port, và ghi chú native-untagged "probably work equally well" trong tình huống tương tự — 2026, VLAN Configuration Samples FAQ, docs.openvswitch.org.
  • dot1q-tunnel (802.1ad/QinQ) được thêm vào Open vSwitch từ bản 2.8.0 (31/8/2017) — OVS NEWS, v2.8.0, github.com/openvswitch/ovs.
  • QinQ trên OVS dùng làm giải pháp nhẹ thay thế VXLAN/GENEVE/GRE trong một số trường hợp, tận dụng được NIC hardware offload, overhead thấp hơn tunnel (chỉ +4 byte/frame so với VLAN thường); cấu hình vlan-limit (0 hoặc 2) là bước bắt buộc để bật QinQ đầy đủ — 6/6/2017, Open vSwitch: Overview of 802.1ad (QinQ) Support, developers.redhat.com.
  • Cần kernel Linux 4.9+ để kernel datapath hỗ trợ đúng QinQ VLAN — theo tóm tắt đã verify từ Red Hat Developer blog cùng chủ đề (cần verify thêm nếu số kernel version thay đổi ở bản phát hành mới hơn).

Tiếp theo: Module 2, Bài 9 — Tunnel: VXLAN/GRE/Geneve trên OVS, đối chiếu trực tiếp với VXLAN/EVPN vật lý.