Skip to content

Commit

Permalink
rule: add Rule.Type to allow adding/listing unreachable (RTN_UNREACHA…
Browse files Browse the repository at this point in the history
…BLE) rules

Updates #710

Co-authored-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Signed-off-by: Percy Wegmann <percy@tailscale.com>
  • Loading branch information
2 people authored and aboch committed Aug 23, 2024
1 parent 65a253d commit 5b0b9d8
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 7 deletions.
5 changes: 3 additions & 2 deletions rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type Rule struct {
IPProto int
UIDRange *RuleUIDRange
Protocol uint8
Type uint8
}

func (r Rule) String() string {
Expand All @@ -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.
Expand Down
35 changes: 33 additions & 2 deletions rule_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 changes: 8 additions & 0 deletions rule_nonlinux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//go:build !linux
// +build !linux

package netlink

func (r Rule) typeString() string {
return ""
}
14 changes: 11 additions & 3 deletions rule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand All @@ -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{
Expand All @@ -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",
},
}

Expand Down Expand Up @@ -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 &&
Expand Down

0 comments on commit 5b0b9d8

Please sign in to comment.