From a3122c761f09b917dacf386c618541f38e1f7465 Mon Sep 17 00:00:00 2001 From: Chen Tang Date: Wed, 25 Mar 2026 11:01:56 +0800 Subject: [PATCH] rule: populate Type field in RuleList and RuleListFiltered The Rule.Type field was missing from the Rule struct, causing RuleList and RuleListFiltered to always return Type as 0 regardless of the actual FIB rule action type (e.g. RTN_UNICAST, RTN_BLACKHOLE). Add Type field to Rule struct, populate it from msg.Type during deserialization, support setting it during rule creation, and add RT_FILTER_TYPE filtering support. Fixes #1055 --- rule.go | 1 + rule_linux.go | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/rule.go b/rule.go index 9a6b57dac..d77d2d266 100644 --- a/rule.go +++ b/rule.go @@ -13,6 +13,7 @@ type Rule struct { Mark int Mask int Tos uint + Type int TunID uint Goto int Src *net.IPNet diff --git a/rule_linux.go b/rule_linux.go index 5f4f98d9b..84ee28859 100644 --- a/rule_linux.go +++ b/rule_linux.go @@ -59,6 +59,9 @@ func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error { if rule.Tos != 0 { msg.Tos = uint8(rule.Tos) } + if rule.Type > 0 { + msg.Type = uint8(rule.Type) + } var dstFamily uint8 var rtAttrs []*nl.RtAttr @@ -225,6 +228,7 @@ func (h *Handle) RuleListFiltered(family int, filter *Rule, filterMask uint64) ( rule.Invert = msg.Flags&FibRuleInvert > 0 rule.Family = int(msg.Family) rule.Tos = uint(msg.Tos) + rule.Type = int(msg.Type) for j := range attrs { switch attrs[j].Attr.Type { @@ -292,6 +296,8 @@ func (h *Handle) RuleListFiltered(family int, filter *Rule, filterMask uint64) ( continue case filterMask&RT_FILTER_TOS != 0 && rule.Tos != filter.Tos: continue + case filterMask&RT_FILTER_TYPE != 0 && rule.Type != filter.Type: + continue case filterMask&RT_FILTER_PRIORITY != 0 && rule.Priority != filter.Priority: continue case filterMask&RT_FILTER_MARK != 0 && rule.Mark != filter.Mark: