Skip to content

rtnl: send a rule's iif and oif as interface names - #517

Open
WiFiGUY512 wants to merge 1 commit into
ucode-lang:masterfrom
WiFiGUY512:rtnl-rule-ifname
Open

WiFiGUY512 wants to merge 1 commit into
ucode-lang:masterfrom
WiFiGUY512:rtnl-rule-ifname

Conversation

@WiFiGUY512

Copy link
Copy Markdown

A rule's iif and oif go to the kernel as FRA_IFNAME and FRA_OIFNAME, which carry an interface name: a NUL-terminated string, read with NLA_STRING by the kernel's fib rule policy. The rule spec declared them DT_NETDEV, so rtnl sent the interface's index as a 32-bit number instead.

The kernel takes those four bytes for a name. No device matches it, so it accepts the rule and marks it detached:

rtnl.request(rtnl.const.RTM_NEWRULE, rtnl.const.NLM_F_CREATE,
             { family: rtnl.const.AF_INET, oif: "lo", table: 100,
               priority: 100 });

This leaves a rule with FIB_RULE_OIF_DETACHED (0x10) in its flags, and it never matches. With iif, the flag is FIB_RULE_IIF_DETACHED (0x8). Reading such a rule back gives null for the interface, because the name string is decoded as an index the same way.

This commit declares both as DT_STRING, which sends and reads the name, as iproute2 does. Scripts pass the same value as before.

Tested on an Arista W-118 (IPQ4019, 32-bit ARM) with OpenWrt main, loading the patched rtnl.so with ucode -L:

oif rule flags iif rule flags Read back
Before 0x10 0x8 null
After 0 0 "lo"

🤖 Generated with Claude Code

FRA_IFNAME and FRA_OIFNAME carry an interface name, a NUL-terminated
string; the kernel's fib rule policy reads them as NLA_STRING. The rule
spec declared them DT_NETDEV, so rtnl sent the interface's index as a
32-bit number. The kernel then took those four bytes for a name that
matches no device, accepted the rule, and marked it detached:

  rtnl.request(rtnl.const.RTM_NEWRULE, rtnl.const.NLM_F_CREATE,
               { family: rtnl.const.AF_INET, oif: "lo", table: 100,
                 priority: 100 });

leaves a rule whose dump has FIB_RULE_OIF_DETACHED (0x10) in its flags,
and which never matches; with iif, FIB_RULE_IIF_DETACHED (0x8). Reading
such a rule back gave null for the interface, the name string being
decoded as an index the same way.

Declare both as DT_STRING, which sends and reads the name, as iproute2
does. A script passes the same value as before. Tested on an OpenWrt
IPQ4019 AP (32-bit ARM): with this change both rules have flags 0 and
read back as "lo".

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Christopher Griffin <christophergriffin05@gmail.com>

This branch has not been deployed

No deployments
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.

1 participant