You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

macOS开启PMTU发现时,路径MTU缓存能否自动更新?

问题解答:开启net.inet.tcp.path_mtu_discovery后MTU缓存是否自动更新?

核心结论

开启net.inet.tcp.path_mtu_discovery后,你通过sysctl NET_RT_DUMP获取的路由表中的rt_msghdr.rt_metrics.rmx_mtu(路径MTU缓存)会自动更新。

详细说明

macOS的TCP栈在开启该标志后,会自动执行路径MTU发现(PMTUD)流程:

  • 当TCP发送的数据包设置了DF(不分片)位,且在传输路径中遇到MTU更小的节点时,对方会返回ICMP“需要分片但DF位已置位”的错误。
  • 系统收到该错误后,会自动更新对应目的地址路由条目中的rmx_mtu值,这个更新会同步到全局路由缓存中,你通过sysctl轮询可以获取到最新的MTU数据。

注意事项(结合你的场景)

  • 触发条件:只有当有实际的TCP流量经过对应目的路径时,才会触发PMTUD并更新MTU缓存;如果没有流量,系统不会主动探测路径MTU。
  • 轮询策略:你当前通过sysctl轮询路由表的方式可以拿到更新后的MTU,但需要合理设置轮询间隔,避免过于频繁的轮询带来性能开销。
  • UDP场景:PMTUD默认只针对TCP协议,如果你需要处理UDP流量,需要自行在UDP数据包上设置DF位,并手动处理ICMP错误来更新MTU缓存,系统不会自动维护UDP路径的MTU。

你的场景与代码

你创建了一个虚拟接口,接收所有出站数据包,封装额外头部后通过物理适配器转发至最终目的地。为避免分片,计划通过物理接口与目的地间的PMTU减去封装开销来设置虚拟适配器的MTU,为此你通过sysctl轮询macOS的全局MTU缓存,相关代码如下:

size_t sz_needed = 0;
std::vector<char> route_table;
std::array<int, kSysctlMibLength> mib;

mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
mib[2] = 0;
mib[3] = 0;
mib[4] = NET_RT_DUMP;
mib[5] = 0;
// first check the size
if (sysctl(mib.data(), kSysctlMibLength, nullptr, &sz_needed, nullptr, 0) < 0) {
  return {};
}
// allocate needed size for pba
route_table.reserve(sz_needed);

// than I get the route table contents 
if (sysctl(mib.data(), kSysctlMibLength, route_table.data(), &sz_needed, nullptr, 0) < 0) {
  return {};
}

// now we need to get the rt_msghdr.rt_metrics.rmx_mtu /* MTU for this path */

内容的提问来源于stack exchange,提问作者Zohar81

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 08:37:29