Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
implement TCP MSS clamping (for non-ethernet uplinks)
We didn’t have a need to clamp the TCP Maximum Segment Size (MSS) up until now,
because fiber7 uses an MTU of 1500.

Because Path MTU discovery is often broken on the internet, it’s best practice
to limit the Maximum Segment Size (MSS) of each TCP connection, achieving the
same effect (but only for TCP connections).

This change is beneficial when running router7 behind a non-ethernet uplink,
such as a Fritz!Box cable modem.

This has no adverse effect on fiber7: after clamping, the MSS is still 1440, as
without clamping.
  • Loading branch information
stapelberg committed Oct 22, 2018
1 parent c037bf9 commit 2e8e0da
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 0 deletions.
4 changes: 4 additions & 0 deletions integration/netconfig/netconfig_test.go
Expand Up @@ -287,6 +287,7 @@ func TestNetconfig(t *testing.T) {
` chain forward {`,
` type filter hook forward priority 0; policy accept;`,
` counter name "fwded"`,
` oifname "uplink0" tcp flags syn tcp option maxseg size set rt mtu`,
` }`,
`}`,
`table ip6 filter {`,
Expand All @@ -297,6 +298,7 @@ func TestNetconfig(t *testing.T) {
` chain forward {`,
` type filter hook forward priority 0; policy accept;`,
` counter name "fwded"`,
` oifname "uplink0" tcp flags syn tcp option maxseg size set rt mtu`,
` }`,
`}`,
}
Expand Down Expand Up @@ -352,6 +354,7 @@ func TestNetconfig(t *testing.T) {
` chain forward {`,
` type filter hook forward priority 0; policy accept;`,
` counter name "fwded"`,
` oifname "uplink0" tcp flags syn tcp option maxseg size set rt mtu`,
` }`,
`}`,
`table ip6 filter {`,
Expand All @@ -362,6 +365,7 @@ func TestNetconfig(t *testing.T) {
` chain forward {`,
` type filter hook forward priority 0; policy accept;`,
` counter name "fwded"`,
` oifname "uplink0" tcp flags syn tcp option maxseg size set rt mtu`,
` }`,
`}`,
}
Expand Down
68 changes: 68 additions & 0 deletions internal/netconfig/netconfig.go
Expand Up @@ -576,6 +576,74 @@ func applyFirewall(dir string) error {
Type: nftables.ChainTypeFilter,
})

c.AddRule(&nftables.Rule{
Table: filter,
Chain: forward,
Exprs: []expr.Any{
// [ meta load oifname => reg 1 ]
&expr.Meta{Key: expr.MetaKeyOIFNAME, Register: 1},
// [ cmp eq reg 1 0x30707070 0x00000000 0x00000000 0x00000000 ]
&expr.Cmp{
Op: expr.CmpOpEq,
Register: 1,
Data: ifname("uplink0"),
},

// [ meta load l4proto => reg 1 ]
&expr.Meta{Key: expr.MetaKeyL4PROTO, Register: 1},
// [ cmp eq reg 1 0x00000006 ]
&expr.Cmp{
Op: expr.CmpOpEq,
Register: 1,
Data: []byte{unix.IPPROTO_TCP},
},

// [ payload load 1b @ transport header + 13 => reg 1 ]
&expr.Payload{
DestRegister: 1,
Base: expr.PayloadBaseTransportHeader,
Offset: 13, // TODO
Len: 1, // TODO
},
// [ bitwise reg 1 = (reg=1 & 0x00000002 ) ^ 0x00000000 ]
&expr.Bitwise{
DestRegister: 1,
SourceRegister: 1,
Len: 1,
Mask: []byte{0x02},
Xor: []byte{0x00},
},
// [ cmp neq reg 1 0x00000000 ]
&expr.Cmp{
Op: expr.CmpOpNeq,
Register: 1,
Data: []byte{0x00},
},

// [ rt load tcpmss => reg 1 ]
&expr.Rt{
Register: 1,
Key: expr.RtTCPMSS,
},
// [ byteorder reg 1 = hton(reg 1, 2, 2) ]
&expr.Byteorder{
DestRegister: 1,
SourceRegister: 1,
Op: expr.ByteorderHton,
Len: 2,
Size: 2,
},
// [ exthdr write tcpopt reg 1 => 2b @ 2 + 2 ]
&expr.Exthdr{
SourceRegister: 1,
Type: 2, // TODO
Offset: 2,
Len: 2,
Op: expr.ExthdrOpTcpopt,
},
},
})

counterObj := getCounterObj(c, &nftables.CounterObj{
Table: filter,
Name: "fwded",
Expand Down

0 comments on commit 2e8e0da

Please sign in to comment.