From fed2a7e109e78f7f669ce447a9d8591472a9c16f Mon Sep 17 00:00:00 2001 From: mlsmaycon Date: Wed, 25 Feb 2026 20:24:45 +0100 Subject: [PATCH 1/2] Add support for excluding local routes on Android 13 (Tiramisu) --- .../java/io/netbird/client/tool/IFace.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/tool/src/main/java/io/netbird/client/tool/IFace.java b/tool/src/main/java/io/netbird/client/tool/IFace.java index 918d2acb..d00586d6 100644 --- a/tool/src/main/java/io/netbird/client/tool/IFace.java +++ b/tool/src/main/java/io/netbird/client/tool/IFace.java @@ -3,6 +3,11 @@ import android.annotation.SuppressLint; import android.content.pm.PackageManager; +import android.net.ConnectivityManager; +import android.net.IpPrefix; +import android.net.LinkProperties; +import android.net.Network; +import android.net.RouteInfo; import android.net.VpnService; import android.os.Build; import android.os.Handler; @@ -11,6 +16,8 @@ import android.system.OsConstants; import android.util.Log; +import androidx.annotation.RequiresApi; + import java.util.LinkedList; import java.util.concurrent.CountDownLatch; @@ -74,6 +81,10 @@ private int createTun(String ip, int prefixLength, int mtu, String dns, String[] Log.d(LOGTAG, "add route: "+r.addr+"/"+r.prefixLength); } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + excludeLocalRoutes(builder); + } + disallowApp(builder, "com.google.android.projection.gearhead"); disallowApp(builder, "com.google.android.apps.chromecast.app"); disallowApp(builder, "com.google.android.apps.messaging"); @@ -95,6 +106,38 @@ private int createTun(String ip, int prefixLength, int mtu, String dns, String[] } } + @RequiresApi(api = Build.VERSION_CODES.TIRAMISU) + private void excludeLocalRoutes(VpnService.Builder builder) { + ConnectivityManager cm = vpnService.getSystemService(ConnectivityManager.class); + if (cm == null) { + return; + } + + Network activeNetwork = cm.getActiveNetwork(); + if (activeNetwork == null) { + return; + } + + LinkProperties lp = cm.getLinkProperties(activeNetwork); + if (lp == null) { + return; + } + + for (RouteInfo routeInfo : lp.getRoutes()) { + IpPrefix dest = routeInfo.getDestination(); + if (dest.getPrefixLength() == 0) { + continue; + } + + try { + builder.excludeRoute(dest); + Log.d(LOGTAG, "exclude route: " + dest); + } catch (Exception e) { + Log.d(LOGTAG, "failed to exclude route: " + dest + " - " + e.getMessage()); + } + } + } + private void prepareDnsSetting(VpnService.Builder builder, String dns) { if(dns == null) { return; From b58518b1b69c261d514deab8a2edf037a18efa3d Mon Sep 17 00:00:00 2001 From: mlsmaycon Date: Wed, 25 Feb 2026 21:22:14 +0100 Subject: [PATCH 2/2] Improve local route exclusion logging and user feedback, add PC hardware feature to manifest --- app/src/main/AndroidManifest.xml | 3 +++ .../java/io/netbird/client/tool/IFace.java | 25 +++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index bb289c73..d750e5ac 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -17,6 +17,9 @@ + + Toast.makeText(vpnService, msg, Toast.LENGTH_LONG).show() + ); + } } private void prepareDnsSetting(VpnService.Builder builder, String dns) {