Skip to content

NNSR Internal Compact Header 路线图

状态:规划

最后核对:2026-06-22

目标

SD-WAN 内部转发格式是 4 字节 MPLS 风格 compact label,名称为 NNSR-C。它是内部 header: label 放在逐跳 WireGuard 或 QUIC underlay 保护的 payload 里。Transit agent 只有 在完成本跳 underlay 认证和解密后才能读取它,然后再加密发送到下一跳。

本文不定义公网明文 label SD-WAN core。NexusNet 选择信任 WireGuard/BoringTun 和 QUIC/TLS 1.3/REALITY 的密码学安全,不再额外设计自研端到端 AEAD 层。

图的名字

下面这种 ASCII 盒图通常叫 RFC-style packet layout diagram、RFC-style bit diagram,或者 packet header bit-field diagram。中文可以叫 RFC 风格协议头部位图 或协议位字段图。

设计依据

最接近的 wire-format 参考是 MPLS label switching:

  • RFC 3032 定义了 4-octet label stack entry,包含 20-bit label、3-bit traffic class、1-bit bottom-of-stack flag 和 8-bit TTL。
  • 转发动作是查 label、按需替换或 pop label、更新 TTL、转发到下一跳。
  • 这正好匹配 underlay decapsulation 之后的 SD-WAN transit:transit 节点不应该 重新跑策略匹配,也不拥有路径计算。

其他 RFC 形状不适合作为默认 NNSR header:

候选Header 成本适配度
MPLS 风格 label shim,RFC 3032 模型每个 label 4 字节最适合 compact label-swap。
Geneve,RFC 89268 字节加 options灵活,但比当前需求更大、更通用。
IPv6 SRH / SRv6,RFC 87548 字节 base 加每段 16 字节对紧凑公网 SD-WAN 路径太重。

MTU 约束也要求内部 shim 尽量小:

  • IPv6 Internet link 至少要支持 1280-octet MTU。
  • UDP 应用应避免发送超过 path MTU 的 datagram。
  • QUIC endpoint 必须能处理至少 1200-byte UDP datagram,所以 1200 bytes 是 QUIC 路径上保守规划的基线。

4 字节 NNSR-C Header

text
  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 / SID                  | TC  |S|  TTL  |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

字段:

字段Bits含义
Label / SID20当前 route generation 内 node-local forwarding label。
TC3Traffic class。初始为 0,保留给 QoS、OAM、fallback class 或 drop class。
S1Bottom-of-stack flag。初始 single-label 格式固定为 1
TTL8Hop limit。每跳递减,到 0 丢包。

编码规则:

  • 4 字节 compact label 使用 network byte order。
  • Label / SID 占 32-bit word 的 bit 31 到 bit 12。
  • TC 占 bit 11 到 bit 9。
  • S 占 bit 8。
  • TTL 占 bit 7 到 bit 0。

Octet 编码:

OctetBitsEncoding
07..0Label[19:12]
17..0Label[11:4]
27..4Label[3:0]
23..1TC[2:0]
20S
37..0TTL

初始格式只使用一个 label。Label stack 保留给未来 service chaining 或嵌套 overlay, 但默认 SD-WAN 路径应保持 single-label。

WG NNSR Packet Layout

WG NNSR 表示 NNSR-C 是解密后的 WireGuard tunnel payload 的前 4 字节。公网 wire 上 compact label 被逐跳 WireGuard session 加密和认证。

公网 underlay packet:

text
  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
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                                                               |
 ~              Outer IPv4 Header or Outer IPv6 Header          ~
 |                                                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |          UDP Source Port      |       UDP Destination Port    |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |          UDP Length           |       UDP Checksum            |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                 WireGuard Message Type = Data                 |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                    WireGuard Receiver Index                   |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                                                               |
 +                         WireGuard Counter                     +
 |                                                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                                                               |
 ~      AEAD ciphertext of: NNSR-C Label + Inner IPv4/IPv6       ~
 |                                                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                                                               |
 ~                    WireGuard AEAD Tag (16 octets)             ~
 |                                                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Agent 做 WireGuard decapsulation 后可见的 payload:

text
  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 / SID                  | TC  |S|  TTL  |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |Ver|                                                           |
 +---+                                                           +
 |                                                               |
 ~                    Inner IPv4 or IPv6 Packet                  ~
 |                                                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

WG NNSR decrypted payload offsets:

OffsetLengthField
04NNSR-C compact label。
4variableInner IPv4 或 IPv6 packet。第一个 nibble 是 46

WG NNSR 到 inner IP packet 前的 overhead:

LayerBytes
Outer IPv4 header20
Outer IPv6 header40
UDP header8
WireGuard data header16
WireGuard AEAD tag16
NNSR-C label4

IPv4 underlay 到 inner IP 前是 64 字节,IPv6 underlay 到 inner IP 前是 84 字节。 链路层 overhead 不计入这里。

QUIC Tunnel NNSR Packet Layout

QUIC Tunnel NNSR 表示 NNSR-C 位于 QUIC DATAGRAM 内,在 QUIC packet protection 认证和解密之后可见。公网 wire 上外部观察者看不到 compact label。

公网 underlay packet:

text
  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
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                                                               |
 ~              Outer IPv4 Header or Outer IPv6 Header          ~
 |                                                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |          UDP Source Port      |       UDP Destination Port    |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |          UDP Length           |       UDP Checksum            |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                                                               |
 ~             QUIC Header (long or short, variable)             ~
 |                                                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                                                               |
 ~    QUIC packet-protected payload, including DATAGRAM frame    ~
 |                                                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

移除 QUIC packet protection 后的 QUIC DATAGRAM frame:

text
  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
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |        DATAGRAM Frame Type (QUIC varint, usually 1B)          |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |        Optional DATAGRAM Length (QUIC varint, if present)     |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                                                               |
 ~                    DATAGRAM Application Data                  ~
 |                                                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

推荐的 Nexus QUIC Tunnel NNSR application data,QUIC decapsulation 后可见:

text
  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 / SID                  | TC  |S|  TTL  |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |Ver|                                                           |
 +---+                                                           +
 |                                                               |
 ~                    Inner IPv4 or IPv6 Packet                  ~
 |                                                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

推荐 QUIC Tunnel NNSR application-data offsets:

OffsetLengthField
04NNSR-C compact label。
4variableInner IPv4 或 IPv6 packet。第一个 nibble 是 46

兼容 HTTP/3 DATAGRAM 的 application data 可以保留现有 context prefix:

text
  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
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |        Quarter Stream ID / Context ID (QUIC varint, 4B)       |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                 Label / SID                  | TC  |S|  TTL  |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |Ver|                                                           |
 +---+                                                           +
 |                                                               |
 ~                    Inner IPv4 or IPv6 Packet                  ~
 |                                                               |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

为了让 NNSR-C 保持 32-bit 对齐,SD-WAN QUIC context 应从固定编码为 4 字节的 QUIC varint 范围分配:

text
16384 <= context_id <= 1073741823

HTTP/3-compatible offsets:

OffsetLengthField
04Quarter Stream ID / Context ID,编码为 4-byte QUIC varint。
44NNSR-C compact label。
8variableInner IPv4 或 IPv6 packet。第一个 nibble 是 46

转发语义

Transit lookup key:

text
(route_generation, local_label)

Transit lookup value:

text
action: swap | pop | drop
next_label
next_node_short_id
underlay_profile_id
mtu
counter ids
egress_action_id, only for pop entries

Transit 行为:

text
decrypt/authenticate local WG or QUIC underlay
parse 4-byte NNSR-C label
if TTL <= 1: drop and count ttl_expired
lookup (generation, label)
if miss: drop and count missing_forward_entry
if action = swap:
  replace label with next_label
  decrement TTL
  send via next hop WG or QUIC underlay
if action = pop:
  strip 4-byte header
  execute egress action

Ingress 行为:

text
match packet against SD-WAN policy
select active path and first local label from runtime table
prepend NNSR-C label with configured TTL
send via first hop WG or QUIC underlay

Egress 行为:

text
decrypt/authenticate local WG or QUIC underlay
pop label
execute NAT, remote_tun, local_route, service_upstream, or drop

为什么删除 18 字节

当前 18 字节 header 里的多个字段对 fast path 是冗余的:

当前字段Compact 替代
path_idLabel table entry metadata。
hop_index由 local label progression 表达。
path_lenTransit 不需要;TTL 负责防环路。
ip_versionpop 后读 inner packet 第一个 nibble。
flow_hashUnderlay session、UDP source port、QUIC connection routing 或 table metadata。
payload_len来自 QUIC DATAGRAM、WG packet 或 packet buffer length。

每包省 14 字节不是 MTU 的全部问题,但和 QUIC、WireGuard、NAT、保守 MSS 规划叠加后 很有价值。继续保留双格式还会分裂 runtime negotiation、测试、UI 命名和运维诊断, 所以旧 codec 应删除,不设置保留路径。

公网封装位置

公网 wire format 不是:

text
Outer IP / UDP
NNSR-C clear label
Inner IPv4/IPv6 packet

生产公网 wire format 是:

text
Outer IP / UDP
WG or QUIC protected packet
  encrypted/authenticated payload:
    NNSR-C compact label
    Inner IPv4/IPv6 packet

这意味着:

  • 公网观察者看不到 NNSR label。
  • Transit 节点只有在解密本地 underlay session 后才能读取 NNSR。
  • 下一跳能解密,是因为上一跳会把 NNSR payload 重新加密进下一跳的 WG 或 QUIC session。
  • 加密成本是逐跳的,随路径里的 underlay 链路数量增长。

eBPF 和用户态适配

NNSR-C 足够小,适合用户态 fast path;但它不承诺公网 pre-decrypt tc/XDP 转发。

允许的优化路线:

  • 用户态解析、递减 TTL、替换 20-bit label,并通过选定 WG/QUIC adapter 转发。
  • QUIC 和 WG worker 可以批量 decrypt、lookup、enqueue next-hop send。
  • 未来 post-decap helper 可以在 underlay protection 移除后优化 label lookup。
  • 明文 label tc/eBPF 模式只能作为非默认、受控环境 profile。

近期非目标:

  • NIC 级 eBPF 直接从公网 packet 读取 NNSR-C。
  • 公网明文 label swap 作为普通 SD-WAN 模式。

实施计划

  1. 新增 versioned NNSR-C codec。
  2. 后端 runtime generation 增加 per-hop local label 和 action type:swappopdrop
  3. 增加用户态 compact transit 测试,覆盖 ingress、swap、pop、TTL expiry、 missing label 和 route generation replacement。
  4. 增加 runtime feature negotiation:nnsr_compact_label_v1
  5. 将 NNSR-C 接入 QUIC REALITY 和 BoringTun WG adapter。
  6. 前端 path inspector 同时展示 logical path 和 compact label entries。
  7. 所有新 route generation 切换到 compact labels。
  8. 增加回归测试,确保新 runtime config 只生成 NNSR-C over protected underlay sessions。

待定决策

决策当前方向
Label scope每个 route generation 内 node-local。
Underlay security逐跳 WG 或 QUIC/TLS 1.3;无自研 NNSR AEAD。
Stack support保留 S;默认 single-label。
TC 语义初始为 0;保留给 OAM/fallback/QoS class。
认证Underlay authentication 加 generation-scoped labels。
Replay handling由 underlay 负责;compact label 本身不解决 replay。
Fragmentation通过 MTU/MSS planning 和 PLPMTUD 风格 probing 避免 fragmentation。

参考

  • RFC 3032: MPLS Label Stack Encoding.
  • RFC 2784: Generic Routing Encapsulation.
  • RFC 7348: Virtual eXtensible Local Area Network.
  • RFC 8754: IPv6 Segment Routing Header.
  • RFC 8926: Geneve.
  • RFC 8085: UDP Usage Guidelines.
  • RFC 8200: IPv6 Specification.
  • RFC 9000: QUIC.

NexusNet documentation