Skip to content

ctlplane: set loose reverse path filtering on TAP representors#640

Merged
maxime-leroy merged 2 commits into
DPDK:mainfrom
rjarry:rp-filter
Jul 20, 2026
Merged

ctlplane: set loose reverse path filtering on TAP representors#640
maxime-leroy merged 2 commits into
DPDK:mainfrom
rjarry:rp-filter

Conversation

@rjarry

@rjarry rjarry commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

When rp_filter=1 (strict mode) is enabled, the kernel does a reverse path FIB lookup on incoming packets to verify that the source address is reachable via the same interface. With only oif rules, this lookup falls through to the main/VRF table where the default route points to the TUN loopback, causing an interface mismatch and dropping the packet.

Add a matching iif rule for each TAP so that the rp_filter FIB lookup hits table 999 and finds the default route via the same TAP the packet arrived on. This does not affect actual routing of return packets which still go through the TUN loopback into the datapath as before.

Update the stale rule flush logic to also collect and clean up iif rules on restart.

Enable rp_filter in all smoke tests to exercise the added iif rules.

  • smoke/_init.sh: after bringing up lo, sets IPv4 strict reverse path filtering for namespace defaults (net.ipv4.conf.all.rp_filter=1 and net.ipv4.conf.default.rp_filter=1); when run_grout is enabled, exports GROUT_OVERRIDE_RP_FILTER=true into the grout environment.
  • Containerfile + main/grout.default: set GROUT_OVERRIDE_RP_FILTER=true in the container/grout defaults (with comments that it’s required when net.ipv4.conf.all.rp_filter is 1/strict where grout runs).
  • docs/grout.8.scdoc: documents GROUT_OVERRIDE_RP_FILTER and that it configures rp_filter=2 (loose) on control plane TAP interfaces when strict (rp_filter=1) is enabled globally.
  • main: adds gr_config.override_rp_filter, parsed from GROUT_OVERRIDE_RP_FILTER; when set, emits a NOTICE that reverse path filtering will be bypassed.
  • modules/infra/control/ctlplane.c: during control-plane TAP creation, when gr_config.override_rp_filter is enabled, writes /proc/sys/net/ipv4/conf/<iface>/rp_filter=2 for the TAP (after the existing /keep_addr_on_down sysctl write) and logs WARNING if the rp_filter sysctl can’t be opened/written.
  • modules/infra/control/netlink.c: configures control-plane policy routing using table 999 for both IPv4 and IPv6 by installing per-TAP policy rules that match oif=<tap> via FRA_OIFNAME and a default dev <tap> route in table 999; on init, flushes stale state for table 999 by dumping RTM_GETRULE/RTM_GETROUTE, collecting entries where table == 999, and deleting the corresponding policy rules (by saved FRA_OIFNAME) and routes (in table 999) to avoid orphan kernel entries across crash/restart cycles.

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This change adds an environment-controlled reverse path filtering override. The configuration is parsed and logged at startup, and control-plane TAP creation writes rp_filter=2 when enabled, warning on sysctl open failure. The container and default configuration enable the option, while smoke initialization sets global and default IPv4 reverse path filtering to 1 and exports the override for grout. Documentation describes the new environment variable and its behavior.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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 clearly matches the main change: adding iif policy routing rules for ctlplane TAPs to prevent rp_filter drops.
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.

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.

@rjarry rjarry changed the title Add iif policy routing rules for ctlplane TAPs to avoid rp_filter drops ctlplane: set loose reverse path filtering on TAP representors Jul 9, 2026
Comment thread smoke/_init.sh

ip link set lo up
sysctl -qw net.ipv4.conf.all.rp_filter=1
sysctl -qw net.ipv4.conf.default.rp_filter=1

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

In that commit, should we remove the other rp_filter config ?
For example:
smoke/bgp6_srv6_frr_test.sh:ip netns exec bgp-peer sysctl -w net.ipv4.conf.all.rp_filter=0

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

These settings are for the bgp-peer netns that does not run grout. Just linux stack. I can try removing them but I think they are needed because of the assymetric vxlan routing.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

ack, my bad !

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The default value is zero on kernel, why always enabled it ?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Setting it to 2 (loose) is the only way to override anything set by system admins.

Comment thread modules/infra/control/ctlplane.c Outdated
// delivered by grout are not dropped by rp_filter. The effective
// rp_filter mode is max(conf.all, conf.<iface>), so setting the
// per-interface value to 2 (loose) overrides a global strict setting.
snprintf(path, sizeof(path), "/proc/sys/net/ipv4/conf/%s/rp_filter", iface->name);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

rp_filter is disable by default, why you want to force at loose for tap. -> NACK

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Setting it to 2 (loose) is the only way to override net.ipv4.conf.all=1 set by system admins.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Just don't put loose when it's disabled in all.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I cannot know if the admin will enable it later. Why do you care about setting it loose? It has no impact at all. It will just verify there is one route to reach the source address. Since grout always installs a default route via the VRF tun interface, the check passes all the time.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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 current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@main/grout.default`:
- Around line 14-17: The reverse-path filtering override is enabled by default
in both configuration locations. Set GROUT_OVERRIDE_RP_FILTER to false or leave
it unset in main/grout.default, and remove the baked-in environment variable
from Containerfile; deployments requiring the workaround must opt in explicitly
at deployment time.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 30faf3a6-83b3-43fa-84fd-3093a08e1ddf

📥 Commits

Reviewing files that changed from the base of the PR and between a07c753 and e1db61c.

📒 Files selected for processing (7)
  • Containerfile
  • docs/grout.8.scdoc
  • main/config.h
  • main/grout.default
  • main/main.c
  • modules/infra/control/ctlplane.c
  • smoke/_init.sh
🚧 Files skipped from review as they are similar to previous changes (2)
  • modules/infra/control/ctlplane.c
  • smoke/_init.sh

Comment thread main/grout.default
Comment on lines +14 to +17
# Set loose reverse path filtering on control plane TAP interfaces.
# Required when net.ipv4.conf.all.rp_filter is set to 1 (strict) in the network
# namespace where grout is running.
GROUT_OVERRIDE_RP_FILTER=true

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Keep the reverse-path filtering override opt-in.

Both defaults enable rp_filter=2 on control-plane TAP interfaces, weakening strict anti-spoofing validation even when the workaround is unnecessary.

  • main/grout.default#L14-L17: default GROUT_OVERRIDE_RP_FILTER to false/unset.
  • Containerfile#L26-L26: remove the baked-in environment variable; set it only for deployments that enable strict filtering.
📍 Affects 2 files
  • main/grout.default#L14-L17 (this comment)
  • Containerfile#L26-L26
🤖 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 `@main/grout.default` around lines 14 - 17, The reverse-path filtering override
is enabled by default in both configuration locations. Set
GROUT_OVERRIDE_RP_FILTER to false or leave it unset in main/grout.default, and
remove the baked-in environment variable from Containerfile; deployments
requiring the workaround must opt in explicitly at deployment time.

rjarry added 2 commits July 20, 2026 14:59
When rp_filter=1 (strict mode) is enabled globally, the kernel drops
packets arriving on TAP interfaces because the reverse path check finds
the default route pointing to the TUN loopback rather than the TAP.

Add support for a new GROUT_OVERRIDE_RP_FILTER environment variable to
control how grout overrides the linux stack configuration.

When GROUT_OVERRIDE_RP_FILTER is set to a true-ish value, set
rp_filter=2 (loose mode) on each TAP at creation time. The effective
rp_filter mode is max(conf.all, conf.<iface>), so the per-interface
value of 2 overrides a global strict setting. Loose mode only checks
that the source address is reachable via some interface, which always
passes since grout has a default route.

Signed-off-by: Robin Jarry <rjarry@redhat.com>
Reviewed-by: Maxime Leroy <maxime@leroys.fr>
Set rp_filter=1 globally in the smoke test init so that all tests run
with strict reverse path filtering. This exercises the per-TAP loose
mode override set by grout on ctlplane interfaces.

Signed-off-by: Robin Jarry <rjarry@redhat.com>
Reviewed-by: Maxime Leroy <maxime@leroys.fr>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
main/grout.default (1)

14-17: 🔒 Security & Privacy | 🟠 Major

Keep the reverse-path filtering override opt-in.

This is the same unresolved security issue from the previous review: enabling GROUT_OVERRIDE_RP_FILTER=true by default forces control-plane TAP interfaces to use loose filtering (rp_filter=2), weakening anti-spoofing validation for every deployment. Leave it unset/false here; deployments requiring the workaround should opt in explicitly.

🤖 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 `@main/grout.default` around lines 14 - 17, Change the default
GROUT_OVERRIDE_RP_FILTER setting in the configuration to unset or false so
reverse-path filtering remains strict by default; deployments needing loose
filtering must opt in explicitly.
🤖 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.

Duplicate comments:
In `@main/grout.default`:
- Around line 14-17: Change the default GROUT_OVERRIDE_RP_FILTER setting in the
configuration to unset or false so reverse-path filtering remains strict by
default; deployments needing loose filtering must opt in explicitly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5834048d-c203-429c-ae90-7d126e43b398

📥 Commits

Reviewing files that changed from the base of the PR and between e1db61c and 920301f.

📒 Files selected for processing (7)
  • Containerfile
  • docs/grout.8.scdoc
  • main/config.h
  • main/grout.default
  • main/main.c
  • modules/infra/control/ctlplane.c
  • smoke/_init.sh
🚧 Files skipped from review as they are similar to previous changes (5)
  • Containerfile
  • main/main.c
  • main/config.h
  • modules/infra/control/ctlplane.c
  • smoke/_init.sh

@maxime-leroy
maxime-leroy merged commit 1df07f5 into DPDK:main Jul 20, 2026
6 checks passed
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.

3 participants