在桥接端口上设置 TCP MSS

在桥接端口上设置 TCP MSS

我在两台 Linux 主机之间有一条 VXLAN 隧道。该隧道通过 MTU 为 1500 字节的以太网链路承载。在每一端,VXLAN 接口以及另一个以太网接口都从属于桥接器。它看起来像这样:

                 |         Host A               |                 Host B       |
Client Device  <--> eth0 <--> br0 <--> vxlan0 <-|-> vxlan0 <--> br0 <--> eth0 <--> Client Device
                 |                              |                              |
                 |                       eth1 <-|-> eth1                       |

这里只有客户端设备和 eth1 有 IP 配置 - 其他一切都只是两个站点之间的第 2 层链接。

VXLAN 涉及 50 字节的开销。为了避免破坏某些协议,我将第 2 层链路(eth0、br0、vxlan0)上的 MTU 设置为 1500 字节。为了避免 TCP 碎片,我想将 vxlan0 接口上的 TCP MSS 设置为 1400 字节。我怎样才能做到这一点?

我知道我可以为网桥打开 iptables ( echo 1 > /sys/class/net/br0/bridge/nf_call_iptables)。然而,iptables 有很多与系统这部分无关的其他规则,这样做会带来相当大的性能成本。

我知道我可以使用 为路由设置 MSS ip route add ... advmss 1400。但请注意,所涉及的数据包均不会在主机 A 或主机 B 上路由。它们只是从一个接口桥接到另一个接口。

是否有某种方法可以对此流量应用较低的 TCP MSS,而不会导致 iptables 性能损失?

答案1

nftables旨在取代ebtables+iptables:大多数功能也可以在桥接级别上使用,就像在 IP 级别上使用一样,无需使用br_netfilter(包括桥接级别的状态 IP 防火墙,内核 >= 5.3)。

bridgemss.nft这是一个在 HostA 和 HostB 上加载的规则集(我们称之为) nft -f bridgemss.nft

table bridge t
delete table bridge t

table bridge t {
    chain c {
        type filter hook forward priority filter; policy accept;
        oifname vxlan0 tcp flags syn tcp option maxseg size set 1400
    }
}

当然,可以更改规则集以满足需要(例如:仅在主机 A 上使用两个方向,而不是在主机 A 和主机 B 上各使用一个方向)。

HostA 和 HostB 是否应该分配一个地址br0以通过 VXLAN 进行通信,而不是直接与以太网1,那么应该在桥输出挂钩(或一个系统输出+输入挂钩)中重复此规则,因为这不会被视为转发帧。

相关内容