rule: add Rule.Type to allow adding/listing unreachable (RTN_UNREACHABLE) rules

Updates #710

Co-authored-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Signed-off-by: Percy Wegmann <percy@tailscale.com>
This commit is contained in:
Percy Wegmann 2024-08-22 14:13:23 -05:00 committed by Alessandro Boch
parent 65a253d375
commit 5b0b9d8260
4 changed files with 55 additions and 7 deletions

View File

@ -28,6 +28,7 @@ type Rule struct {
IPProto int
UIDRange *RuleUIDRange
Protocol uint8
Type uint8
}
func (r Rule) String() string {
@ -41,8 +42,8 @@ func (r Rule) String() string {
to = r.Dst.String()
}
return fmt.Sprintf("ip rule %d: from %s to %s table %d",
r.Priority, from, to, r.Table)
return fmt.Sprintf("ip rule %d: from %s to %s table %d %s",
r.Priority, from, to, r.Table, r.typeString())
}
// NewRule return empty rules.

View File

@ -43,8 +43,8 @@ func ruleHandle(rule *Rule, req *nl.NetlinkRequest) error {
msg.Protocol = unix.RTPROT_BOOT
msg.Scope = unix.RT_SCOPE_UNIVERSE
msg.Table = unix.RT_TABLE_UNSPEC
msg.Type = unix.RTN_UNSPEC
if req.NlMsghdr.Flags&unix.NLM_F_CREATE > 0 {
msg.Type = rule.Type // usually 0, same as unix.RTN_UNSPEC
if msg.Type == 0 && req.NlMsghdr.Flags&unix.NLM_F_CREATE > 0 {
msg.Type = unix.RTN_UNICAST
}
if rule.Invert {
@ -332,3 +332,34 @@ func ptrEqual(a, b *uint32) bool {
}
return *a == *b
}
func (r Rule) typeString() string {
switch r.Type {
case unix.RTN_UNSPEC: // zero
return ""
case unix.RTN_UNICAST:
return ""
case unix.RTN_LOCAL:
return "local"
case unix.RTN_BROADCAST:
return "broadcast"
case unix.RTN_ANYCAST:
return "anycast"
case unix.RTN_MULTICAST:
return "multicast"
case unix.RTN_BLACKHOLE:
return "blackhole"
case unix.RTN_UNREACHABLE:
return "unreachable"
case unix.RTN_PROHIBIT:
return "prohibit"
case unix.RTN_THROW:
return "throw"
case unix.RTN_NAT:
return "nat"
case unix.RTN_XRESOLVE:
return "xresolve"
default:
return fmt.Sprintf("type(0x%x)", r.Type)
}
}

8
rule_nonlinux.go Normal file
View File

@ -0,0 +1,8 @@
//go:build !linux
// +build !linux
package netlink
func (r Rule) typeString() string {
return ""
}

View File

@ -613,7 +613,7 @@ func TestRuleString(t *testing.T) {
s string
}{
"empty rule": {
s: "ip rule 0: from all to all table 0",
s: "ip rule 0: from all to all table 0 ",
},
"rule with src and dst equivalent to <nil>": {
r: Rule{
@ -622,7 +622,7 @@ func TestRuleString(t *testing.T) {
Dst: &net.IPNet{IP: net.IPv4(20, 0, 0, 0)},
Table: 99,
},
s: "ip rule 100: from all to all table 99",
s: "ip rule 100: from all to all table 99 ",
},
"rule with src and dst": {
r: Rule{
@ -631,7 +631,14 @@ func TestRuleString(t *testing.T) {
Dst: &net.IPNet{IP: net.IPv4(20, 0, 0, 0), Mask: net.IPv4Mask(255, 255, 255, 0)},
Table: 99,
},
s: "ip rule 100: from 10.0.0.0/24 to 20.0.0.0/24 table 99",
s: "ip rule 100: from 10.0.0.0/24 to 20.0.0.0/24 table 99 ",
},
"rule with type": {
r: Rule{
Priority: 101,
Type: unix.RTN_UNREACHABLE,
},
s: "ip rule 101: from all to all table 0 unreachable",
},
}
@ -671,6 +678,7 @@ func ruleEquals(a, b Rule) bool {
a.IifName == b.IifName &&
a.Invert == b.Invert &&
a.Tos == b.Tos &&
a.Type == b.Type &&
a.IPProto == b.IPProto &&
a.Protocol == b.Protocol &&
a.Mark == b.Mark &&