我安装了 Ubuntu Server 14.04,使用 PPPoE 连接到互联网。目前我的ppp0
接口的 MTU 为 1492,基本可以正常工作。
我想将 MTU 增加到 1500,我的 ISP 支持这个值。
到目前为止,我已将底层以太网接口的 MTU 增加到 1508,并尝试在/etc/ppp/peers/dsl-provider
mtu 1500
mru 1500
但是我的ppp0
接口仍然具有 1492 的 MTU。我相信我添加的行的语法是正确的,因为使用低于 1492 的值确实可以按预期工作。
ppp0
在接口启动后手动将其 MTU 更改为 1500 是可行的,但它只会影响一个方向的数据包。这样做我可以通过互联网发送 1500 字节的数据包,它们将到达目的地而不会出现碎片。但传入我的流量仍然以 1492 字节的碎片形式发送。
通过在建立 PPPoE 连接时捕获以太网接口上的流量,我可以看到,在我的 Ubuntu Server 14.04 计算机发送给提供商的配置请求中,MRU 被指定为 1492。所以我知道问题出在我的连接端。
为什么 Ubuntu Server 14.04 在配置请求中使用 1492 作为 MRU,而配置文件中显示的是 1500?我该如何将其更改为 1500?
答案1
我ppp
通过输入以下两个命令下载了源代码:
sudo apt-get build-dep ppp
apt-get source ppp
在头文件中pppd/plugins/rp-pppoe/pppoe.h
我发现了这个:
/* Header size of a PPPoE packet */
#define PPPOE_OVERHEAD 6 /* type, code, session, length */
#define HDR_SIZE (sizeof(struct ethhdr) + PPPOE_OVERHEAD)
#define MAX_PPPOE_PAYLOAD (ETH_DATA_LEN - PPPOE_OVERHEAD)
#define MAX_PPPOE_MTU (MAX_PPPOE_PAYLOAD - 2)
ETH_DATA_LEN
定义在/usr/include/linux/if_ether.h
#define ETH_DATA_LEN 1500 /* Max. octets in payload */
我pppd/plugins/rp-pppoe/plugin.c
发现了这个:
if (lcp_allowoptions[0].mru > MAX_PPPOE_MTU)
lcp_allowoptions[0].mru = MAX_PPPOE_MTU;
if (lcp_wantoptions[0].mru > MAX_PPPOE_MTU)
lcp_wantoptions[0].mru = MAX_PPPOE_MTU;
所有这些意味着该rp-pppoe
插件具有 1492 字节的硬编码限制。而增加它的唯一方法是修改源代码并重建具有更高限制的插件。
通过删除上述四行plugin.c
并重建模块,我能够将 MTU 从 1492 增加到 1500。这只有在已知底层线路支持更大尺寸的情况下才有效,而我的连接恰好就是这种情况。
为了检测底层线路的功能,必须使用支持 RFC 4638 的较新版本的 pppd。Ubuntu 16.04 具有较新版本的 pppd,因此应该能够为 PPPoE 使用更大的 MTU 大小,而无需重新编译任何代码。
答案2
您可以通过 strace 和过滤器运行 pppd 来显示“打开”请求,以查看它打开哪些文件来获取其配置。
sudo strace -f -e open pppd
根据我的经验(英国宽带),如果通过 BT,所有连接都是 1492,需要另外 8 个八位字节有什么特殊原因吗?
我的理解是,如果您没有正确匹配 MRU,您的数据包最终可能会变成多个数据包,特别是如果您不允许诸如 8 个八位字节的封装开销之类的东西。