From 391cc95300b4ec55f185d9e5fd60b4152f9df268 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maxime=20Soul=C3=A9?= Date: Mon, 26 Feb 2024 17:07:32 +0100 Subject: [PATCH] Add RouteChange API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maxime Soulé --- handle_unspecified.go | 4 +++ netlink_unspecified.go | 4 +++ route_linux.go | 15 ++++++++++ route_test.go | 67 +++++++++++++++++++++++++++++++++++++++++- 4 files changed, 89 insertions(+), 1 deletion(-) diff --git a/handle_unspecified.go b/handle_unspecified.go index d0966680..3fe03642 100644 --- a/handle_unspecified.go +++ b/handle_unspecified.go @@ -263,6 +263,10 @@ func (h *Handle) RouteAppend(route *Route) error { return ErrNotImplemented } +func (h *Handle) RouteChange(route *Route) error { + return ErrNotImplemented +} + func (h *Handle) RouteDel(route *Route) error { return ErrNotImplemented } diff --git a/netlink_unspecified.go b/netlink_unspecified.go index adac048f..0f6fde25 100644 --- a/netlink_unspecified.go +++ b/netlink_unspecified.go @@ -204,6 +204,10 @@ func RouteAppend(route *Route) error { return ErrNotImplemented } +func RouteChange(route *Route) error { + return ErrNotImplemented +} + func RouteDel(route *Route) error { return ErrNotImplemented } diff --git a/route_linux.go b/route_linux.go index 99467df3..8c274414 100644 --- a/route_linux.go +++ b/route_linux.go @@ -790,6 +790,21 @@ func (h *Handle) RouteAddEcmp(route *Route) error { return err } +// RouteChange will add a route to the system. +// Equivalent to: `ip route change $route` +func RouteChange(route *Route) error { + return pkgHandle.RouteChange(route) +} + +// RouteChange will add a route to the system. +// Equivalent to: `ip route change $route` +func (h *Handle) RouteChange(route *Route) error { + flags := unix.NLM_F_REPLACE | unix.NLM_F_ACK + req := h.newNetlinkRequest(unix.RTM_NEWROUTE, flags) + _, err := h.routeHandle(route, req, nl.NewRtMsg()) + return err +} + // RouteReplace will add a route to the system. // Equivalent to: `ip route replace $route` func RouteReplace(route *Route) error { diff --git a/route_test.go b/route_test.go index a862bbb5..67497e24 100644 --- a/route_test.go +++ b/route_test.go @@ -331,6 +331,72 @@ func TestRoute6AddDel(t *testing.T) { } } +func TestRouteChange(t *testing.T) { + tearDown := setUpNetlinkTest(t) + defer tearDown() + + // get loopback interface + link, err := LinkByName("lo") + if err != nil { + t.Fatal(err) + } + + // bring the interface up + if err := LinkSetUp(link); err != nil { + t.Fatal(err) + } + + // add a gateway route + dst := &net.IPNet{ + IP: net.IPv4(192, 168, 0, 0), + Mask: net.CIDRMask(24, 32), + } + + ip := net.IPv4(127, 1, 1, 1) + route := Route{LinkIndex: link.Attrs().Index, Dst: dst, Src: ip} + + if err := RouteChange(&route); err == nil { + t.Fatal("Route added while it should fail") + } + + if err := RouteAdd(&route); err != nil { + t.Fatal(err) + } + routes, err := RouteList(link, FAMILY_V4) + if err != nil { + t.Fatal(err) + } + if len(routes) != 1 { + t.Fatal("Route not added properly") + } + + ip = net.IPv4(127, 1, 1, 2) + route = Route{LinkIndex: link.Attrs().Index, Dst: dst, Src: ip} + if err := RouteChange(&route); err != nil { + t.Fatal(err) + } + + routes, err = RouteList(link, FAMILY_V4) + if err != nil { + t.Fatal(err) + } + + if len(routes) != 1 || !routes[0].Src.Equal(ip) { + t.Fatal("Route not changed properly") + } + + if err := RouteDel(&route); err != nil { + t.Fatal(err) + } + routes, err = RouteList(link, FAMILY_V4) + if err != nil { + t.Fatal(err) + } + if len(routes) != 0 { + t.Fatal("Route not removed properly") + } +} + func TestRouteReplace(t *testing.T) { tearDown := setUpNetlinkTest(t) defer tearDown() @@ -390,7 +456,6 @@ func TestRouteReplace(t *testing.T) { if len(routes) != 0 { t.Fatal("Route not removed properly") } - } func TestRouteAppend(t *testing.T) {