chore(all): replace netlink library for more flexibility (#3107)

This commit is contained in:
Quentin McGaw
2026-01-27 10:11:39 +01:00
committed by GitHub
parent e292a4c9be
commit facc6df3be
50 changed files with 1074 additions and 579 deletions
+80 -39
View File
@@ -2,54 +2,95 @@ package netlink
import (
"fmt"
"net/netip"
"github.com/vishvananda/netlink"
"github.com/jsimonetti/rtnetlink"
)
func NewRule() Rule {
// defaults found from netlink.NewRule() for fields we use,
// the rest of the defaults is set when converting from a `Rule`
// to a `netlink.Rule`
return Rule{
Priority: -1,
Mark: 0,
type Rule struct {
Priority *uint32
Family uint8
Table uint32
Mark *uint32
Src netip.Prefix
Dst netip.Prefix
Flags uint32
Action uint8
}
func (r *Rule) fromMessage(message rtnetlink.RuleMessage) {
table := uint32(message.Table)
if table == 0 || table == rtTableCompat {
table = *message.Attributes.Table
}
r.Priority = message.Attributes.Priority
r.Family = message.Family
r.Table = table
r.Mark = message.Attributes.FwMark
r.Src = ipAndLengthToPrefix(message.Attributes.Src, message.SrcLength)
r.Dst = ipAndLengthToPrefix(message.Attributes.Dst, message.DstLength)
r.Flags = message.Flags
r.Action = message.Action
}
func ruleToNetlinkRule(rule Rule) (netlinkRule netlink.Rule) {
netlinkRule = *netlink.NewRule()
netlinkRule.Priority = rule.Priority
netlinkRule.Family = rule.Family
netlinkRule.Table = rule.Table
netlinkRule.Mark = rule.Mark
netlinkRule.Src = netipPrefixToIPNet(rule.Src)
netlinkRule.Dst = netipPrefixToIPNet(rule.Dst)
netlinkRule.Invert = rule.Invert
return netlinkRule
}
func (r Rule) message() *rtnetlink.RuleMessage {
src, srcLength := prefixToIPAndLength(r.Src)
dst, dstLength := prefixToIPAndLength(r.Dst)
func netlinkRuleToRule(netlinkRule netlink.Rule) (rule Rule) {
return Rule{
Priority: netlinkRule.Priority,
Family: netlinkRule.Family,
Table: netlinkRule.Table,
Mark: netlinkRule.Mark,
Src: netIPNetToNetipPrefix(netlinkRule.Src),
Dst: netIPNetToNetipPrefix(netlinkRule.Dst),
Invert: netlinkRule.Invert,
message := &rtnetlink.RuleMessage{
Family: r.Family,
SrcLength: srcLength,
DstLength: dstLength,
Flags: r.Flags,
Action: r.Action,
Attributes: &rtnetlink.RuleAttributes{
Priority: r.Priority,
FwMark: r.Mark,
Src: src,
Dst: dst,
},
}
if r.Table <= uint32(^uint8(0)) {
message.Table = uint8(r.Table)
} else {
message.Table = rtTableCompat
message.Attributes.Table = &r.Table
}
return message
}
func ruleDbgMsg(add bool, rule Rule) (debugMessage string) {
func (r Rule) String() string {
from := "all"
if r.Src.IsValid() && !r.Src.Addr().IsUnspecified() {
from = r.Src.String()
}
to := "all"
if r.Dst.IsValid() && !r.Dst.Addr().IsUnspecified() {
to = r.Dst.String()
}
priority := ""
if r.Priority != nil {
priority = fmt.Sprintf(" %d", *r.Priority)
}
return fmt.Sprintf("ip rule%s: from %s to %s table %d",
priority, from, to, r.Table)
}
func (r Rule) debugMessage(add bool) (debugMessage string) {
debugMessage = "ip"
switch rule.Family {
switch r.Family {
case FamilyV4:
debugMessage += " -f inet"
case FamilyV6:
debugMessage += " -f inet6"
default:
debugMessage += " -f " + fmt.Sprint(rule.Family)
debugMessage += " -f " + fmt.Sprint(r.Family)
}
debugMessage += " rule"
@@ -60,20 +101,20 @@ func ruleDbgMsg(add bool, rule Rule) (debugMessage string) {
debugMessage += " del"
}
if rule.Src.IsValid() {
debugMessage += " from " + rule.Src.String()
if r.Src.IsValid() {
debugMessage += " from " + r.Src.String()
}
if rule.Dst.IsValid() {
debugMessage += " to " + rule.Dst.String()
if r.Dst.IsValid() {
debugMessage += " to " + r.Dst.String()
}
if rule.Table != 0 {
debugMessage += " lookup " + fmt.Sprint(rule.Table)
if r.Table != 0 {
debugMessage += " lookup " + fmt.Sprint(r.Table)
}
if rule.Priority != -1 {
debugMessage += " pref " + fmt.Sprint(rule.Priority)
if r.Priority != nil {
debugMessage += " pref " + fmt.Sprint(*r.Priority)
}
return debugMessage