From 3974133ddf46eb016cde4a99900294faa08fbf84 Mon Sep 17 00:00:00 2001 From: Andrey Filatov Date: Fri, 6 Feb 2026 12:55:56 +0300 Subject: [PATCH] feat: add InterfaceMetric and RouteMetric fields --- tun.go | 2 ++ tun_linux.go | 6 +++++- tun_windows.go | 18 ++++++++++++------ 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/tun.go b/tun.go index 35cd095..a5a73cd 100644 --- a/tun.go +++ b/tun.go @@ -74,6 +74,8 @@ type Options struct { Inet6Address []netip.Prefix MTU uint32 GSO bool + InterfaceMetric uint32 + RouteMetric uint32 AutoRoute bool InterfaceScope bool Inet4Gateway netip.Addr diff --git a/tun_linux.go b/tun_linux.go index f35921e..27828c0 100644 --- a/tun_linux.go +++ b/tun_linux.go @@ -520,12 +520,16 @@ func (t *NativeTun) routes(tunLink netlink.Link) ([]netlink.Route, error) { } else if it.Addr().Is6() && !gateway6.IsUnspecified() { gateway = gateway6.AsSlice() } - return netlink.Route{ + route := netlink.Route{ Dst: prefixToIPNet(it), Gw: gateway, LinkIndex: tunLink.Attrs().Index, Table: t.options.IPRoute2TableIndex, } + if t.options.RouteMetric > 0 { + route.Priority = int(t.options.RouteMetric) + } + return route }), nil } diff --git a/tun_windows.go b/tun_windows.go index 54e7395..89e9104 100644 --- a/tun_windows.go +++ b/tun_windows.go @@ -129,7 +129,10 @@ func (t *NativeTun) configure() error { inetIf.ManagedAddressConfigurationSupported = false inetIf.OtherStatefulConfigurationSupported = false inetIf.NLMTU = t.options.MTU - if t.options.AutoRoute { + if t.options.InterfaceMetric > 0 { + inetIf.UseAutomaticMetric = false + inetIf.Metric = t.options.InterfaceMetric + } else if t.options.AutoRoute { inetIf.UseAutomaticMetric = false inetIf.Metric = 0 } @@ -148,7 +151,10 @@ func (t *NativeTun) configure() error { inet6If.ManagedAddressConfigurationSupported = false inet6If.OtherStatefulConfigurationSupported = false inet6If.NLMTU = t.options.MTU - if t.options.AutoRoute { + if t.options.InterfaceMetric > 0 { + inet6If.UseAutomaticMetric = false + inet6If.Metric = t.options.InterfaceMetric + } else if t.options.AutoRoute { inet6If.UseAutomaticMetric = false inet6If.Metric = 0 } @@ -175,7 +181,7 @@ func (t *NativeTun) Start() error { if err != nil { return err } - err = addRouteList(luid, routeRanges, gateway4, gateway6, 0) + err = t.addRouteList(luid, routeRanges, gateway4, gateway6) if err != nil { return err } @@ -584,7 +590,7 @@ func (t *NativeTun) UpdateRouteOptions(tunOptions Options) error { if err != nil { return err } - err = addRouteList(luid, routeRanges, gateway4, gateway6, 0) + err = t.addRouteList(luid, routeRanges, gateway4, gateway6) if err != nil { return err } @@ -595,11 +601,11 @@ func (t *NativeTun) UpdateRouteOptions(tunOptions Options) error { return nil } -func addRouteList(luid winipcfg.LUID, destinations []netip.Prefix, gateway4 netip.Addr, gateway6 netip.Addr, metric uint32) error { +func (t *NativeTun) addRouteList(luid winipcfg.LUID, destinations []netip.Prefix, gateway4 netip.Addr, gateway6 netip.Addr) error { row := winipcfg.MibIPforwardRow2{} row.Init() row.InterfaceLUID = luid - row.Metric = metric + row.Metric = t.options.RouteMetric nextHop4 := row.NextHop nextHop6 := row.NextHop if gateway4.IsValid() {