PPPoE 在发现阶段学到对端以太网地址和一个 16 位会话号,再把 PPP 装进以太网。发现阶段以太类型是 0x8863,会话阶段是 0x8864。规范是 1999 年 2 月的 RFC 2516,状态为 Informational。截至 2026 年 10 月,查阅到的页面没有列出取代它的文件。
四步之后才有非零的会话号
一个可独立引用的定义句:发现阶段让主机和接入集中器都得到 SESSION_ID 与对端以太网地址。一条 PPPoE 会话由这个会话号加上两端的以太网地址共同定义(RFC 2516 第 4 节、第 5 节)。
四步的以太类型都是 0x8863。版本和类型两个四位字段在这份规范里都必须是 0x1。
| 报文 | 代码 | 目的地址 | 会话号 |
|---|---|---|---|
| PADI | 0x09 | 广播 | 必须为 0x0000 |
| PADO | 0x07 | 发出 PADI 的那台主机 | 必须为 0x0000 |
| PADR | 0x19 | 主机选中的集中器 | 必须为 0x0000 |
| PADS | 0x65 | 那台主机 | 接受时必须是集中器生成的唯一值 |
主机先广播 PADI。能提供服务的集中器各自回一份 PADO;不能提供的不得回。主机可以收到多份 PADO,按集中器名字或所提供的服务选一个,再发单播 PADR。集中器接受后,在 PADS 里放入唯一的会话号。若它不接受 PADR 里的服务名,必须回一份带 Service-Name-Error 的 PADS,此时会话号必须仍是 0x0000。
0xffff 保留,不得使用。发现阶段在 PPP 会话建立之前保持无状态。会话一旦建立,主机和集中器都必须为这条 PPP 虚拟接口分配资源。
PADI 必须恰好包含一个服务名标签,标签类型是 0x0101。整份 PADI(含 PPPoE 头)不得超过 1484 字节,给中继留出添加 Relay-Session-Id 的位置。PADO 必须包含集中器名字标签,以及与 PADI 相同的那一个服务名,还可以带上它提供的其他服务名。
广播地址在原文里少写了 16 位
RFC 2516 第 4 节把以太网广播写成 0xffffffff。一条状态为 Held for Document Update、尚未标为 Verified 的勘误认为,48 位广播应写成 0xffffffffffff。PADI 那一节只写「广播地址」,没有再重复这串十六进制。本文按全 1 的 48 位目的地址理解 PADI,同时保留原文的写法,不把尚未验证的勘误当成已经发布的更正。勘误页见 RFC 2516 errata。
同一页上,已验证的技术勘误(Errata ID 7746,2024 年 1 月核实)指出第 7 节列出的三项禁止协商的 LCP 选项,名称与 IANA 及 RFC 1570、RFC 1662 的正式名称不一致。本文不复述那三个可能写错的名字。第 7 节仍然建议使用 Magic Number,不建议协议字段压缩。
会话阶段换成另一个以太类型
一个可独立引用的定义句:会话阶段的以太网帧都是单播。以太类型必须是 0x8864,代码必须是 0x00,会话号不得再变,载荷从 PPP 协议号开始(RFC 2516 第 6 节)。
结束用 PADT,代码是 0xa7。两端都可以发,会话号必须指明要结束的那一条。发出或收到 PADT 之后,不得再在这条会话上发送 PPP 流量,连正常的 PPP 终止包也不得再发。对端应当优先用 PPP 自己结束会话;PPP 不能用时,才可以用 PADT。
LCP 终止后,两端必须停止使用这条 PPPoE 会话。主机若要再开一条,必须回到发现阶段。第 7 节建议集中器不时发送 Echo-Request,否则主机不发终止请求就离开时,集中器无从知道会话已经不在。已验证的编辑勘误只更正了原文里 occasionally 的拼写,不改变这条建议。
第 8 节还写:等不到 PADO 时,主机应当重发 PADI 并把等待时间加倍,次数由实现自定;等 PADS 时对 PADR 做类似的重发。这里没有往返样本,也没有 TCP 重传超时里的 1 秒或 3 秒(RFC 6298)。两份加倍不要合成一只钟。
1492 是没有更大载荷标签时的上限
一个可独立引用的定义句:以太网最大载荷是 1500 字节,PPPoE 头 6 字节,PPP 协议号 2 字节,因此 PPP 的 MTU 不得大于 1492。MRU 选项也不得谈成比 1492 更大(RFC 2516 第 7 节)。
RFC 4638 同样是 Informational。它的页首没有 Updates 或 Obsoletes 行,所以不能把它读成「已经正式更新了 RFC 2516」。正文描述一种可选标签 PPP-Max-Payload:标签值 0x0120,长度 2 字节,内容是客户端在收发两个方向都能支持的最大 PPP 载荷。客户端若想用大于 1492 的 MTU 或 MRU,必须在 PADI 和 PADR 里带上它。服务器若也能支持,必须在 PADO 和 PADS 里原样回显。
标签缺失,或者值不大于 1492 时,1492 的约束必须仍然适用。标签大于 1492 时,服务器可以允许更大的 MRU,上限取标签值与「接口 MTU 减 8」中的较小者。同一节的摘要又写:若没有协商 MRU,RFC 1661 把默认 MRU 定为 1500,即使标签可以大于 1500。这句和「未带标签时不得超过 1492」写在同一节的不同条目里。本文不把其中一条改写成另一条。2026 年 10 月 17 日查阅 RFC 4638 的勘误检索,没有列出条目。
该文件 2006 年的 IESG 注记写明:成文时没有现行 IEEE 标准支持大于 1500 字节的巨型帧。这是 2006 年的注记。2026 年 10 月的 IEEE 802.3 是否另有规定,本文没有核对。
隧道的外层 IP 包若走这条 PPP 会话,就要放进上述 PPP 载荷里。PPPoE 头和协议号先占 8 字节,隧道再在里面加自己的外层头。内层还能有多长,取决于这次谈成的 MRU,而不是以太网名义上的 1500。MTU 不匹配 与 路径 MTU 探包 讨论的是包已经进隧道之后的两步。最大段长度如何被改写,见 TCP MSS 钳制。装不下时谁来分片,见 IP 分片。本文不提供修改 MRU 或钳制的步骤。
地址若改由 DHCP 分配,中间没有这层 PPP,发现阶段和会话号都不出现。那种租约见 DHCP 租约。某一条接入在 2026 年 10 月用的是 PPPoE 还是 DHCP,本文没有测量。
AC-Cookie 不保护会话里的载荷
集中器可以在 PADO 里放上 AC-Cookie,标签类型是 0x0104。主机若收到,必须在随后的 PADR 里原样带回。RFC 2516 第 9 节写明:集中器应当能依据 PADR 的源地址重新生成这个值,从而确认 PADI 的源地址可达,并限制该地址上的并发会话。用什么算法没有规定。原文举的例子是只用集中器知道的密钥,对主机 MAC 做 HMAC。它不加密会话阶段的 PPP 载荷,也不是 TCP 快速打开 里那枚饼干。
一个可独立引用的结论句:会话号标识的是这一次以太网之上的 PPP 会话。它不加密载荷,也不说明隧道已经建好。
本文不提供构造 AC-Cookie、限制并发会话或改写 MRU 的步骤。
现象对照
| 现象 | 更可能先看什么 |
|---|---|
| 以太类型 0x8863,代码 0x09,会话号为 0 | PADI。目的地址应当是广播 |
| 代码 0x65,会话号仍是 0,并带有服务名错误 | 集中器拒绝了请求的服务名 |
| 以太类型变成 0x8864,代码为 0 | 已经进入会话阶段。会话号应是 PADS 里的那个值 |
| 代码 0xa7 | PADT。之后不应再看见这条会话上的 PPP |
| 以太网载荷是 1500,PPP 载荷却谈成 1492 | RFC 2516 的默认上限。先看有没有大于 1492 的 PPP-Max-Payload |
| 隧道里的网页打得开、大包却过不去 | 先分清 PPP 载荷上限和隧道再减去的外层头。两步不是同一个数 |
核对清单
- 会话号在 PADS 里才离开 0:前三步必须是 0x0000。0xffff 不得使用;
- 两个以太类型不要看反:发现是 0x8863,会话是 0x8864,会话阶段代码必须是 0;
- PADT 之后不再发 PPP:包括正常的终止包。要再连,必须重新发现;
- 1492 是没有更大标签时的 PPP 载荷上限:RFC 4638 的页首没有写它更新了 RFC 2516。同一节里还有一条默认 MRU 为 1500 的摘要;
- 它不加密,也不代替 DHCP:AC-Cookie 只在发现阶段被原样带回。某一条宽带用不用 PPPoE,要单独看。