[PR #6289] [client] Fix fwmark bit 0x20 conflict with OVH OKS kube-proxy MASQUERADE rules #25281

Open
opened 2026-08-05 07:05:48 -04:00 by saavagebueno · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/netbirdio/netbird/pull/6289
Author: @elprofessor-de
Created: 5/29/2026
Status: 🔄 Open

Base: mainHead: fix/fwmark-ovh-oks-conflict


📝 Commits (1)

  • 6daa99a [client] Fix fwmark conflict with OVH OKS kube-proxy rules

📊 Changes

1 file changed (+6 additions, -4 deletions)

View changed files

📝 client/net/net.go (+6 -4)

📄 Description

Describe your changes

On OVH Managed Kubernetes (OKS) nodes, a pre-installed iptables rule in
mangle POSTROUTING matches packets where bit 0x20 is set in the fwmark,
and strips bit 0x4000 — which is kube-proxy's MASQUERADE bit set by
KUBE-MARK-MASQ. As a result, KUBE-POSTROUTING bails out, MASQUERADE
never happens, and NodePort replies never reach the client.

Since v0.40, the three PreroutingFwmark* constants use values 0x1BD20,
0x1BD21, 0x1BD22 — all of which have bit 0x20 set in their lower byte.
This was introduced in #3623 as a sequential grouping choice (after
0x1BD10/0x1BD11), with no intention of using that specific bit.

Root cause confirmed with nft monitor trace: 0x4000 is added by
KUBE-MARK-MASQ then immediately stripped by the OVH hairpin rule. That
rule's counter shows ~4M packet matches vs ~2.4K for legitimate hairpin
traffic — almost entirely Netbird-marked packets. Manually deleting the rule
fixes NodePort access immediately.

Fix: shift the three prerouting marks from 0x1BD2x to 0x1BD4x
(0x40 has bit 0x20 clear). No other code changes are needed as all
consumers reference these constants.

Constant Before After
PreroutingFwmarkRedirected 0x1BD20 0x1BD40
PreroutingFwmarkMasquerade 0x1BD21 0x1BD41
PreroutingFwmarkMasqueradeReturn 0x1BD22 0x1BD42

These marks are managed entirely by the Netbird daemon at start/stop —
no user-visible config or persistent state is affected.

No existing issue — bug found in production on OVH OKS.

Stack

Checklist

  • Is it a bug fix
  • Is a typo/documentation fix
  • Is a feature enhancement
  • It is a refactor
  • Created tests that fail without the change (if possible)
  • This change does not modify the public API, gRPC protocols, functionality behavior, CLI / service flags, or introduce a new feature — OR I have discussed it with the NetBird team beforehand.

Documentation

  • Documentation is not needed for this change (internal constants, no user-facing behavior change)

Summary by CodeRabbit

  • Chores
    • Updated internal firewall mark constants to prevent conflicts with network routing behavior.

Review Change Stack


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/netbirdio/netbird/pull/6289 **Author:** [@elprofessor-de](https://github.com/elprofessor-de) **Created:** 5/29/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `fix/fwmark-ovh-oks-conflict` --- ### 📝 Commits (1) - [`6daa99a`](https://github.com/netbirdio/netbird/commit/6daa99a505374ce65e6a4104622311f6b7866aa5) [client] Fix fwmark conflict with OVH OKS kube-proxy rules ### 📊 Changes **1 file changed** (+6 additions, -4 deletions) <details> <summary>View changed files</summary> 📝 `client/net/net.go` (+6 -4) </details> ### 📄 Description ## Describe your changes On OVH Managed Kubernetes (OKS) nodes, a pre-installed iptables rule in `mangle POSTROUTING` matches packets where bit `0x20` is set in the fwmark, and strips bit `0x4000` — which is kube-proxy's MASQUERADE bit set by `KUBE-MARK-MASQ`. As a result, `KUBE-POSTROUTING` bails out, MASQUERADE never happens, and NodePort replies never reach the client. Since v0.40, the three `PreroutingFwmark*` constants use values `0x1BD20`, `0x1BD21`, `0x1BD22` — all of which have bit `0x20` set in their lower byte. This was introduced in #3623 as a sequential grouping choice (after `0x1BD10`/`0x1BD11`), with no intention of using that specific bit. **Root cause confirmed with `nft monitor trace`**: `0x4000` is added by `KUBE-MARK-MASQ` then immediately stripped by the OVH hairpin rule. That rule's counter shows ~4M packet matches vs ~2.4K for legitimate hairpin traffic — almost entirely Netbird-marked packets. Manually deleting the rule fixes NodePort access immediately. **Fix**: shift the three prerouting marks from `0x1BD2x` to `0x1BD4x` (`0x40` has bit `0x20` clear). No other code changes are needed as all consumers reference these constants. | Constant | Before | After | |---|---|---| | `PreroutingFwmarkRedirected` | `0x1BD20` | `0x1BD40` | | `PreroutingFwmarkMasquerade` | `0x1BD21` | `0x1BD41` | | `PreroutingFwmarkMasqueradeReturn` | `0x1BD22` | `0x1BD42` | These marks are managed entirely by the Netbird daemon at start/stop — no user-visible config or persistent state is affected. ## Issue ticket number and link No existing issue — bug found in production on OVH OKS. ## Stack <!-- branch-stack --> ### Checklist - [x] Is it a bug fix - [ ] Is a typo/documentation fix - [ ] Is a feature enhancement - [ ] It is a refactor - [ ] Created tests that fail without the change (if possible) - [x] This change does **not** modify the public API, gRPC protocols, functionality behavior, CLI / service flags, or introduce a new feature — **OR** I have discussed it with the NetBird team beforehand. ## Documentation - [x] Documentation is **not needed** for this change (internal constants, no user-facing behavior change) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Chores** * Updated internal firewall mark constants to prevent conflicts with network routing behavior. <!-- review_stack_entry_start --> [![Review Change Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/netbirdio/netbird/pull/6289?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack) <!-- review_stack_entry_end --> <!-- end of auto-generated comment: release notes by coderabbit.ai --> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
saavagebueno added the pull-request label 2026-08-05 07:05:48 -04:00
Sign in to join this conversation.
No Label pull-request
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: DYNR/netbird#25281