mirror of
https://github.com/qdm12/gluetun.git
synced 2026-05-07 12:30:11 +02:00
122 lines
2.4 KiB
Go
122 lines
2.4 KiB
Go
package netlink
|
|
|
|
import (
|
|
"fmt"
|
|
"net/netip"
|
|
|
|
"github.com/jsimonetti/rtnetlink"
|
|
)
|
|
|
|
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 (r Rule) message() *rtnetlink.RuleMessage {
|
|
src, srcLength := prefixToIPAndLength(r.Src)
|
|
dst, dstLength := prefixToIPAndLength(r.Dst)
|
|
|
|
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 (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 r.Family {
|
|
case FamilyV4:
|
|
debugMessage += " -f inet"
|
|
case FamilyV6:
|
|
debugMessage += " -f inet6"
|
|
default:
|
|
debugMessage += " -f " + fmt.Sprint(r.Family)
|
|
}
|
|
|
|
debugMessage += " rule"
|
|
|
|
if add {
|
|
debugMessage += " add"
|
|
} else {
|
|
debugMessage += " del"
|
|
}
|
|
|
|
if r.Src.IsValid() {
|
|
debugMessage += " from " + r.Src.String()
|
|
}
|
|
|
|
if r.Dst.IsValid() {
|
|
debugMessage += " to " + r.Dst.String()
|
|
}
|
|
|
|
if r.Table != 0 {
|
|
debugMessage += " lookup " + fmt.Sprint(r.Table)
|
|
}
|
|
|
|
if r.Priority != nil {
|
|
debugMessage += " pref " + fmt.Sprint(*r.Priority)
|
|
}
|
|
|
|
return debugMessage
|
|
}
|