Skip to content

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

Open
rjarry wants to merge 2 commits into
DPDK:mainfrom
rjarry:rp-filter
Open

ctlplane: set loose reverse path filtering on TAP representors#640
rjarry wants to merge 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.

  • Configured smoke test startup to enable strict IPv4 reverse path filtering by setting net.ipv4.conf.all.rp_filter=1 and net.ipv4.conf.default.rp_filter=1 after bringing up loopback.
  • During ctlplane TAP creation, set per-interface /proc/sys/net/ipv4/conf/<iface>/rp_filter=2 (loose) so packets delivered by grout aren’t dropped when an overall strict setting is enabled; emits WARNING if the per-interface sysctl file can’t be opened.
  • Added/maintained control-plane policy routing in table 999: creates per-TAP ip rule entries that match the TAP via FRA_OIFNAME and route lookups through table 999, installs a default dev <tap> route in table 999 for both IPv4 and IPv6, and flushes stale state on restart by dumping and deleting both the table 999 rules and the table 999 default routes (to avoid orphaned rules/routes accumulating across crash/restart cycles).

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a248eea6-5441-47ad-8a3c-507833a70fbe

📥 Commits

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

📒 Files selected for processing (2)
  • modules/infra/control/ctlplane.c
  • smoke/_init.sh
🚧 Files skipped from review as they are similar to previous changes (2)
  • smoke/_init.sh
  • modules/infra/control/ctlplane.c

📝 Walkthrough

Walkthrough

This change adds reverse path filtering configuration in two places. cp_create() writes value 2 to the TAP interface’s IPv4 rp_filter sysctl and logs a warning if opening the file fails. smoke/_init.sh sets net.ipv4.conf.all.rp_filter and net.ipv4.conf.default.rp_filter to 1 after loopback setup.

🚥 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.

rjarry added 2 commits July 10, 2026 08:29
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.

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: Christophe Fontaine <cfontain@redhat.com>
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: Christophe Fontaine <cfontain@redhat.com>
// 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.

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