Skip to content

Commit 9b61d26

Browse files
trozetaboch
authored andcommitted
Add support for MTU Lock
When adding a route with "mtu lock <mtu>" path MTU discovery (PMTUD) will not be tried and packets will be sent without DF bit set. Upon receiving an ICMP needs frag due to PMTUD, the kernel will not install a cached route and lower the MTU. Signed-off-by: Tim Rozet <[email protected]>
1 parent 0e7078e commit 9b61d26

File tree

3 files changed

+66
-1
lines changed

3 files changed

+66
-1
lines changed

route.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ type Encap interface {
4545
Equal(Encap) bool
4646
}
4747

48-
//Protocol describe what was the originator of the route
48+
// Protocol describe what was the originator of the route
4949
type RouteProtocol int
5050

5151
// Route represents a netlink route.
@@ -70,6 +70,7 @@ type Route struct {
7070
Via Destination
7171
Realm int
7272
MTU int
73+
MTULock bool
7374
Window int
7475
Rtt int
7576
RttVar int

route_linux.go

+6
Original file line numberDiff line numberDiff line change
@@ -1072,6 +1072,10 @@ func (h *Handle) prepareRouteReq(route *Route, req *nl.NetlinkRequest, msg *nl.R
10721072
if route.MTU > 0 {
10731073
b := nl.Uint32Attr(uint32(route.MTU))
10741074
metrics = append(metrics, nl.NewRtAttr(unix.RTAX_MTU, b))
1075+
if route.MTULock {
1076+
b := nl.Uint32Attr(uint32(1 << unix.RTAX_MTU))
1077+
metrics = append(metrics, nl.NewRtAttr(unix.RTAX_LOCK, b))
1078+
}
10751079
}
10761080
if route.Window > 0 {
10771081
b := nl.Uint32Attr(uint32(route.Window))
@@ -1440,6 +1444,8 @@ func deserializeRoute(m []byte) (Route, error) {
14401444
switch metric.Attr.Type {
14411445
case unix.RTAX_MTU:
14421446
route.MTU = int(native.Uint32(metric.Value[0:4]))
1447+
case unix.RTAX_LOCK:
1448+
route.MTULock = native.Uint32(metric.Value[0:4]) == uint32(1<<unix.RTAX_MTU)
14431449
case unix.RTAX_WINDOW:
14441450
route.Window = int(native.Uint32(metric.Value[0:4]))
14451451
case unix.RTAX_RTT:

route_test.go

+58
Original file line numberDiff line numberDiff line change
@@ -2260,6 +2260,64 @@ func TestMTURouteAddDel(t *testing.T) {
22602260
}
22612261
}
22622262

2263+
func TestMTULockRouteAddDel(t *testing.T) {
2264+
_, err := RouteList(nil, FAMILY_V4)
2265+
if err != nil {
2266+
t.Fatal(err)
2267+
}
2268+
2269+
tearDown := setUpNetlinkTest(t)
2270+
defer tearDown()
2271+
2272+
// get loopback interface
2273+
link, err := LinkByName("lo")
2274+
if err != nil {
2275+
t.Fatal(err)
2276+
}
2277+
2278+
// bring the interface up
2279+
if err := LinkSetUp(link); err != nil {
2280+
t.Fatal(err)
2281+
}
2282+
2283+
// add a gateway route
2284+
dst := &net.IPNet{
2285+
IP: net.IPv4(192, 168, 0, 0),
2286+
Mask: net.CIDRMask(24, 32),
2287+
}
2288+
2289+
route := Route{LinkIndex: link.Attrs().Index, Dst: dst, MTU: 500, MTULock: true}
2290+
if err := RouteAdd(&route); err != nil {
2291+
t.Fatal(err)
2292+
}
2293+
routes, err := RouteList(link, FAMILY_V4)
2294+
if err != nil {
2295+
t.Fatal(err)
2296+
}
2297+
if len(routes) != 1 {
2298+
t.Fatal("Route not added properly")
2299+
}
2300+
2301+
if route.MTU != routes[0].MTU {
2302+
t.Fatal("Route MTU not set properly")
2303+
}
2304+
2305+
if route.MTULock != routes[0].MTULock {
2306+
t.Fatal("Route MTU lock not set properly")
2307+
}
2308+
2309+
if err := RouteDel(&route); err != nil {
2310+
t.Fatal(err)
2311+
}
2312+
routes, err = RouteList(link, FAMILY_V4)
2313+
if err != nil {
2314+
t.Fatal(err)
2315+
}
2316+
if len(routes) != 0 {
2317+
t.Fatal("Route not removed properly")
2318+
}
2319+
}
2320+
22632321
func TestRouteViaAddDel(t *testing.T) {
22642322
minKernelRequired(t, 5, 4)
22652323
tearDown := setUpNetlinkTest(t)

0 commit comments

Comments
 (0)