Skip to content

Commit 63ca7e4

Browse files
committed
Support setting and retrieving route MTU/AdvMSS
1 parent f7e518d commit 63ca7e4

4 files changed

Lines changed: 93 additions & 0 deletions

File tree

nl/nl_linux.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,11 @@ func NewRtAttrChild(parent *RtAttr, attrType int, data []byte) *RtAttr {
278278
return attr
279279
}
280280

281+
// AddChild adds an existing RtAttr as a child.
282+
func (a *RtAttr) AddChild(attr *RtAttr) {
283+
a.children = append(a.children, attr)
284+
}
285+
281286
func (a *RtAttr) Len() int {
282287
if len(a.children) == 0 {
283288
return (unix.SizeofRtAttr + len(a.Data))

route.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ type Route struct {
4545
MPLSDst *int
4646
NewDst Destination
4747
Encap Encap
48+
MTU int
49+
AdvMSS int
4850
}
4951

5052
func (r Route) String() string {

route_linux.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,25 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg
454454
msg.Type = uint8(route.Type)
455455
}
456456

457+
var metrics []*nl.RtAttr
458+
// TODO: support other rta_metric values
459+
if route.MTU > 0 {
460+
b := nl.Uint32Attr(uint32(route.MTU))
461+
metrics = append(metrics, nl.NewRtAttr(unix.RTAX_MTU, b))
462+
}
463+
if route.AdvMSS > 0 {
464+
b := nl.Uint32Attr(uint32(route.AdvMSS))
465+
metrics = append(metrics, nl.NewRtAttr(unix.RTAX_ADVMSS, b))
466+
}
467+
468+
if metrics != nil {
469+
attr := nl.NewRtAttr(unix.RTA_METRICS, nil)
470+
for _, metric := range metrics {
471+
attr.AddChild(metric)
472+
}
473+
rtAttrs = append(rtAttrs, attr)
474+
}
475+
457476
msg.Flags = uint32(route.Flags)
458477
msg.Scope = uint8(route.Scope)
459478
msg.Family = uint8(family)
@@ -685,6 +704,19 @@ func deserializeRoute(m []byte) (Route, error) {
685704
encapType = attr
686705
case nl.RTA_ENCAP:
687706
encap = attr
707+
case unix.RTA_METRICS:
708+
metrics, err := nl.ParseRouteAttr(attr.Value)
709+
if err != nil {
710+
return route, err
711+
}
712+
for _, metric := range metrics {
713+
switch metric.Attr.Type {
714+
case unix.RTAX_MTU:
715+
route.MTU = int(native.Uint32(metric.Value[0:4]))
716+
case unix.RTAX_ADVMSS:
717+
route.AdvMSS = int(native.Uint32(metric.Value[0:4]))
718+
}
719+
}
688720
}
689721
}
690722

route_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -904,3 +904,57 @@ func TestSEG6RouteAddDel(t *testing.T) {
904904
t.Fatal("SEG6 routes not removed properly")
905905
}
906906
}
907+
908+
func TestMTURouteAddDel(t *testing.T) {
909+
_, err := RouteList(nil, FAMILY_V4)
910+
if err != nil {
911+
t.Fatal(err)
912+
}
913+
914+
tearDown := setUpNetlinkTest(t)
915+
defer tearDown()
916+
917+
// get loopback interface
918+
link, err := LinkByName("lo")
919+
if err != nil {
920+
t.Fatal(err)
921+
}
922+
923+
// bring the interface up
924+
if err := LinkSetUp(link); err != nil {
925+
t.Fatal(err)
926+
}
927+
928+
// add a gateway route
929+
dst := &net.IPNet{
930+
IP: net.IPv4(192, 168, 0, 0),
931+
Mask: net.CIDRMask(24, 32),
932+
}
933+
934+
route := Route{LinkIndex: link.Attrs().Index, Dst: dst, MTU: 500}
935+
if err := RouteAdd(&route); err != nil {
936+
t.Fatal(err)
937+
}
938+
routes, err := RouteList(link, FAMILY_V4)
939+
if err != nil {
940+
t.Fatal(err)
941+
}
942+
if len(routes) != 1 {
943+
t.Fatal("Route not added properly")
944+
}
945+
946+
if route.MTU != routes[0].MTU {
947+
t.Fatal("Route mtu not set properly")
948+
}
949+
950+
if err := RouteDel(&route); err != nil {
951+
t.Fatal(err)
952+
}
953+
routes, err = RouteList(link, FAMILY_V4)
954+
if err != nil {
955+
t.Fatal(err)
956+
}
957+
if len(routes) != 0 {
958+
t.Fatal("Route not removed properly")
959+
}
960+
}

0 commit comments

Comments
 (0)