Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[client] Add IPv6 dual-stack support#148

Open
lixmal wants to merge 12 commits intomainnetbirdio/android-client:mainfrom
feature/ipv6-supportnetbirdio/android-client:feature/ipv6-supportCopy head branch name to clipboard
Open

[client] Add IPv6 dual-stack support#148
lixmal wants to merge 12 commits intomainnetbirdio/android-client:mainfrom
feature/ipv6-supportnetbirdio/android-client:feature/ipv6-supportCopy head branch name to clipboard

Conversation

@lixmal
Copy link
Copy Markdown
Contributor

@lixmal lixmal commented Mar 30, 2026

Add IPv6 dual-stack support to the Android client.

  • Expand TunAdapter.ConfigureInterface to accept an IPv6 address and add it to the VPN builder
  • Display peer IPv6 addresses in the peer list with a copy-to-clipboard option
  • Add a "Disable IPv6" toggle in Advanced settings
  • Point netbird submodule to the IPv6 branch

Summary by CodeRabbit

  • New Features

    • Peer IPv6 shown alongside IPv4 and a new "Copy IPv6" clipboard action.
    • Advanced Settings: toggle to disable IPv6 overlay addressing on the tunnel (persists).
    • Remote/TV-style interaction can toggle the IPv6 disable option.
    • Tunnel reconfiguration can include an IPv6 address when available.
  • Bug Fixes / Enhancements

    • Exit-node detection now recognizes IPv6 default routes.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 30, 2026

Warning

Rate limit exceeded

@lixmal has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 50 minutes and 51 seconds before requesting another review.

To continue reviewing without waiting, purchase usage credits in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4a33a30e-a578-4f7f-9b89-e63a890e82dc

📥 Commits

Reviewing files that changed from the base of the PR and between 3dddd20 and 09ff3bf.

📒 Files selected for processing (3)
  • app/src/main/java/io/netbird/client/ui/home/PeersFragmentViewModel.java
  • tool/src/main/java/io/netbird/client/tool/EngineRunner.java
  • tool/src/main/java/io/netbird/client/tool/VPNService.java
📝 Walkthrough

Walkthrough

Adds IPv6 support across UI and tooling: new disable‑IPv6 preference and UI entry, Peer model and adapter show/copy IPv6, TUN/VPN tooling accepts and persists IPv6 address, NetworkChangeNotifier gains an IPv6 setter, and the netbird submodule pointer is bumped.

Changes

Advanced Settings UI

Layer / File(s) Summary
Data / Resources
app/src/main/res/layout/fragment_advanced.xml, app/src/main/res/values/strings.xml
Add layout_disable_ipv6, switch_disable_ipv6, and strings advanced_disable_ipv6, advanced_disable_ipv6_desc.
UI Wiring
app/src/main/java/io/netbird/client/ui/advanced/AdvancedFragment.java
Initialize switchDisableIpv6 from goPreferences.getDisableIPv6(), persist changes via goPreferences.setDisableIPv6(...) + commit, log on failure, and add container click to toggle the switch for TV-remote input.

Peer Model & List UI

Layer / File(s) Summary
Data Shape
app/src/main/java/io/netbird/client/ui/home/Peer.java
Add ipv6 field, constructor parameter, and getIpv6() getter.
ViewModel
app/src/main/java/io/netbird/client/ui/home/PeersFragmentViewModel.java
Construct Peer with peerInfo.getIPv6() in addition to existing fields.
Adapter / Menu
app/src/main/java/io/netbird/client/ui/home/PeersAdapter.java, app/src/main/res/menu/peer_clipboard_menu.xml
Show IPv6 beneath IPv4 when present; conditionally show copy_ipv6 menu item and handle copying IPv6 to clipboard.

Resource Detection

Layer / File(s) Summary
Logic
app/src/main/java/io/netbird/client/ui/home/Resource.java
isExitNode() now guards null address and treats address containing 0.0.0.0/0 or ::/0 as an exit node.

VPN / TUN Interface Logic

Layer / File(s) Summary
Data Shape
tool/src/main/java/io/netbird/client/tool/TUNParameters.java
Add addressV6 field and constructor parameter.
Core Implementation
tool/src/main/java/io/netbird/client/tool/IFace.java
configureInterface signature gains addressV6; parse optional IPv6, pass into createTun, add IPv6 addr to VpnService.Builder when present, and append IPv6 default route when appropriate; add hasIPv4DefaultRoute(...) helper.
Wiring
tool/src/main/java/io/netbird/client/tool/VPNService.java, tool/src/main/java/io/netbird/client/tool/NetworkChangeNotifier.java
recreateTUN(...) now passes currentTUNParameters.addressV6 to IFace.configureInterface; NetworkChangeNotifier adds empty setInterfaceIPv6(String) override.

EngineRunner / Misc

Layer / File(s) Summary
Refactor / Readability
tool/src/main/java/io/netbird/client/tool/EngineRunner.java
Localize cacheDir into a variable before constructing AndroidPlatformFiles; debugBundle(boolean anonymize) moved later without signature change.

Dependencies

Layer / File(s) Summary
Submodule
netbird (git submodule)
Bump netbird submodule commit reference to a newer commit SHA.

Sequence Diagram(s)

sequenceDiagram
    participant User as "User (UI)"
    participant Advanced as "AdvancedFragment"
    participant Prefs as "goPreferences"
    participant VM as "PeersFragmentViewModel"
    participant Adapter as "PeersAdapter"
    participant Clipboard as "Clipboard"
    participant VPN as "VPNService"
    participant IFace as "IFace / TUN builder"

    User->>Advanced: Toggle Disable IPv6 / click container
    Advanced->>Prefs: setDisableIPv6(isChecked) + commit
    Prefs-->>Advanced: ack

    VM->>Adapter: bind Peer(status, ip, ipv6, fqdn)
    Adapter->>User: display IPv4 and IPv6 (if present)
    User->>Adapter: long-press -> select "copy IPv6"
    Adapter->>Clipboard: copy "IPv6 Address"

    VPN->>IFace: configureInterface(address, addressV6, mtu, dns, routes)
    IFace->>IFace: parse addressV6, add IPv6 addr or add IPv6 default route
    IFace-->>VPN: tunFd / success
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • pappz
  • mlsmaycon

Poem

🐇 I hopped through code to add a second lane,
Gave peers a nimble IPv6 name.
A switch to hush the extra route,
TUN learned two stacks with a gentle boot.
Clipboard and UI now pair with a twitch.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.56% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title '[client] Add IPv6 dual-stack support' clearly and concisely describes the primary change: adding IPv6 support to the Android client, which is reflected across all modified files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/ipv6-support

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@lixmal lixmal force-pushed the feature/ipv6-support branch from fa435ce to 3f573e8 Compare March 30, 2026 17:38
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/src/main/java/io/netbird/client/ui/home/Resource.java`:
- Around line 38-40: The isExitNode method in class Resource can NPE and misses
IPv6 when multiple addresses are present; update Resource.isExitNode to be
null-safe and use the same containment logic for both IPv4 and IPv6 (e.g., check
address != null and then address.contains("0.0.0.0/0") ||
address.contains("::/0")) so both "0.0.0.0/0,::/0" and "::/0,10.0.0.0/8" are
detected consistently.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 07976be7-06ad-4c85-aeb7-69281ce165ee

📥 Commits

Reviewing files that changed from the base of the PR and between f7e1c65 and 3f573e8.

📒 Files selected for processing (13)
  • app/src/main/java/io/netbird/client/ui/advanced/AdvancedFragment.java
  • app/src/main/java/io/netbird/client/ui/home/Peer.java
  • app/src/main/java/io/netbird/client/ui/home/PeersAdapter.java
  • app/src/main/java/io/netbird/client/ui/home/PeersFragmentViewModel.java
  • app/src/main/java/io/netbird/client/ui/home/Resource.java
  • app/src/main/res/layout/fragment_advanced.xml
  • app/src/main/res/menu/peer_clipboard_menu.xml
  • app/src/main/res/values/strings.xml
  • netbird
  • tool/src/main/java/io/netbird/client/tool/IFace.java
  • tool/src/main/java/io/netbird/client/tool/NetworkChangeNotifier.java
  • tool/src/main/java/io/netbird/client/tool/TUNParameters.java
  • tool/src/main/java/io/netbird/client/tool/VPNService.java

Comment thread app/src/main/java/io/netbird/client/ui/home/Resource.java
lixmal and others added 4 commits March 30, 2026 19:53
Use contains() for IPv6 check to match IPv4 logic, so multi-address
strings like "0.0.0.0/0,::/0" are handled correctly. Add null guard
for address field.
# Conflicts:
#	app/src/main/java/io/netbird/client/ui/home/PeersFragmentViewModel.java
#	netbird
pappz
pappz previously approved these changes Apr 15, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tool/src/main/java/io/netbird/client/tool/IFace.java`:
- Around line 80-82: The current logic only adds a blackhole ::/0 when addrV6 ==
null and hasIPv4DefaultRoute(routes) is true, but the presence of an IPv6
address is not the right signal — we must add the ::/0 blackhole whenever there
is an IPv4 default route and there is no IPv6 default route. Change the
condition in IFace where routes are built: replace the addrV6 == null check with
a check for absence of an IPv6 default route (e.g., !hasIPv6DefaultRoute(routes)
or !routes.stream().anyMatch(r -> r.prefix.equals("::/0"))), so that if
hasIPv4DefaultRoute(routes) && no IPv6 /0 route then routes.add(new
Route("::/0")). Use or add a helper like hasIPv6DefaultRoute(routes) to mirror
hasIPv4DefaultRoute for clarity; keep Route and routes usage unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 08479a13-3a8b-4b3b-b88c-f6846203f348

📥 Commits

Reviewing files that changed from the base of the PR and between bce03cb and 70eb8be.

📒 Files selected for processing (2)
  • netbird
  • tool/src/main/java/io/netbird/client/tool/IFace.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • netbird

Comment thread tool/src/main/java/io/netbird/client/tool/IFace.java
New PlatformFiles.CacheDir() method in the netbird submodule.
Pass context.getCacheDir() through from EngineRunner.
@lixmal lixmal temporarily deployed to android-release April 21, 2026 08:55 — with GitHub Actions Inactive
# Conflicts:
#	netbird
#	tool/src/main/java/io/netbird/client/tool/EngineRunner.java
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tool/src/main/java/io/netbird/client/tool/EngineRunner.java (1)

23-239: ⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

Restore EngineRunner.debugBundle(boolean) to avoid a hard API break.

EngineRunner no longer exposes debugBundle, but VPNService still calls engineRunner.debugBundle(anonymize) (tool/src/main/java/io/netbird/client/tool/VPNService.java, Line 242). This is a compile-time break and also disrupts the app-layer troubleshooting chain (ServiceAccessorMainActivityTroubleshootFragment).

Suggested fix
 class EngineRunner {
@@
+    public String debugBundle(boolean anonymize) throws Exception {
+        return goClient.debugBundle(anonymize);
+    }
+
     public PeerInfoArray peersInfo() {
         return goClient.peersList();
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tool/src/main/java/io/netbird/client/tool/EngineRunner.java` around lines 23
- 239, EngineRunner no longer provides debugBundle(boolean) causing a
compile-time break where VPNService calls engineRunner.debugBundle(anonymize);
restore compatibility by adding a public synchronized debugBundle(boolean
anonymize) method on EngineRunner that delegates to the appropriate goClient or
internal logic to produce the debug bundle (or returns the same data structure
VPNService expects), ensuring the signature matches VPNService's call; reference
EngineRunner.debugBundle(boolean), VPNService's call to
engineRunner.debugBundle(anonymize), and preserve behavior used by
ServiceAccessor/MainActivity/TroubleshootFragment so callers continue to work
without changes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@tool/src/main/java/io/netbird/client/tool/EngineRunner.java`:
- Around line 23-239: EngineRunner no longer provides debugBundle(boolean)
causing a compile-time break where VPNService calls
engineRunner.debugBundle(anonymize); restore compatibility by adding a public
synchronized debugBundle(boolean anonymize) method on EngineRunner that
delegates to the appropriate goClient or internal logic to produce the debug
bundle (or returns the same data structure VPNService expects), ensuring the
signature matches VPNService's call; reference
EngineRunner.debugBundle(boolean), VPNService's call to
engineRunner.debugBundle(anonymize), and preserve behavior used by
ServiceAccessor/MainActivity/TroubleshootFragment so callers continue to work
without changes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0a9ea66e-4cf7-4735-aab4-45ff7b8e04c3

📥 Commits

Reviewing files that changed from the base of the PR and between 70eb8be and 96e29f3.

📒 Files selected for processing (6)
  • app/src/main/java/io/netbird/client/ui/advanced/AdvancedFragment.java
  • app/src/main/res/layout/fragment_advanced.xml
  • app/src/main/res/values/strings.xml
  • netbird
  • tool/src/main/java/io/netbird/client/tool/EngineRunner.java
  • tool/src/main/java/io/netbird/client/tool/VPNService.java
✅ Files skipped from review due to trivial changes (3)
  • netbird
  • app/src/main/res/layout/fragment_advanced.xml
  • app/src/main/res/values/strings.xml
🚧 Files skipped from review as they are similar to previous changes (2)
  • app/src/main/java/io/netbird/client/ui/advanced/AdvancedFragment.java
  • tool/src/main/java/io/netbird/client/tool/VPNService.java

@lixmal lixmal had a problem deploying to android-release May 5, 2026 14:31 — with GitHub Actions Failure
@lixmal lixmal deployed to android-release May 5, 2026 14:41 — with GitHub Actions Active
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.