mirror of
https://github.com/juanfont/headscale.git
synced 2025-11-09 13:39:39 -05:00
types: split SubnetRoutes and ExitRoutes
There are situations where the subnet routes and exit nodes must be treated differently. This splits it so SubnetRoutes only returns routes that are not exit routes. It adds `IsExitRoutes` and `AllApprovedRoutes` for convenience. Signed-off-by: Kristoffer Dalby <kristoffer@tailscale.com>
This commit is contained in:
committed by
Kristoffer Dalby
parent
c649c89e00
commit
1c0bb0338d
@@ -269,11 +269,19 @@ func (node *Node) Prefixes() []netip.Prefix {
|
|||||||
// node has any exit routes enabled.
|
// node has any exit routes enabled.
|
||||||
// If none are enabled, it will return nil.
|
// If none are enabled, it will return nil.
|
||||||
func (node *Node) ExitRoutes() []netip.Prefix {
|
func (node *Node) ExitRoutes() []netip.Prefix {
|
||||||
if slices.ContainsFunc(node.SubnetRoutes(), tsaddr.IsExitRoute) {
|
var routes []netip.Prefix
|
||||||
return tsaddr.ExitRoutes()
|
|
||||||
|
for _, route := range node.AnnouncedRoutes() {
|
||||||
|
if tsaddr.IsExitRoute(route) && slices.Contains(node.ApprovedRoutes, route) {
|
||||||
|
routes = append(routes, route)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return routes
|
||||||
|
}
|
||||||
|
|
||||||
|
func (node *Node) IsExitNode() bool {
|
||||||
|
return len(node.ExitRoutes()) > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (node *Node) IPsAsString() []string {
|
func (node *Node) IPsAsString() []string {
|
||||||
@@ -440,16 +448,22 @@ func (node *Node) AnnouncedRoutes() []netip.Prefix {
|
|||||||
return node.Hostinfo.RoutableIPs
|
return node.Hostinfo.RoutableIPs
|
||||||
}
|
}
|
||||||
|
|
||||||
// SubnetRoutes returns the list of routes that the node announces and are approved.
|
// SubnetRoutes returns the list of routes (excluding exit routes) that the node
|
||||||
|
// announces and are approved.
|
||||||
//
|
//
|
||||||
// IMPORTANT: This method is used for internal data structures and should NOT be used
|
// IMPORTANT: This method is used for internal data structures and should NOT be
|
||||||
// for the gRPC Proto conversion. For Proto, SubnetRoutes must be populated manually
|
// used for the gRPC Proto conversion. For Proto, SubnetRoutes must be populated
|
||||||
// with PrimaryRoutes to ensure it includes only routes actively served by the node.
|
// manually with PrimaryRoutes to ensure it includes only routes actively served
|
||||||
// See the comment in Proto() method and the implementation in grpcv1.go/nodesToProto.
|
// by the node. See the comment in Proto() method and the implementation in
|
||||||
|
// grpcv1.go/nodesToProto.
|
||||||
func (node *Node) SubnetRoutes() []netip.Prefix {
|
func (node *Node) SubnetRoutes() []netip.Prefix {
|
||||||
var routes []netip.Prefix
|
var routes []netip.Prefix
|
||||||
|
|
||||||
for _, route := range node.AnnouncedRoutes() {
|
for _, route := range node.AnnouncedRoutes() {
|
||||||
|
if tsaddr.IsExitRoute(route) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if slices.Contains(node.ApprovedRoutes, route) {
|
if slices.Contains(node.ApprovedRoutes, route) {
|
||||||
routes = append(routes, route)
|
routes = append(routes, route)
|
||||||
}
|
}
|
||||||
@@ -463,6 +477,11 @@ func (node *Node) IsSubnetRouter() bool {
|
|||||||
return len(node.SubnetRoutes()) > 0
|
return len(node.SubnetRoutes()) > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AllApprovedRoutes returns the combination of SubnetRoutes and ExitRoutes
|
||||||
|
func (node *Node) AllApprovedRoutes() []netip.Prefix {
|
||||||
|
return append(node.SubnetRoutes(), node.ExitRoutes()...)
|
||||||
|
}
|
||||||
|
|
||||||
func (node *Node) String() string {
|
func (node *Node) String() string {
|
||||||
return node.Hostname
|
return node.Hostname
|
||||||
}
|
}
|
||||||
@@ -653,6 +672,7 @@ func (node Node) DebugString() string {
|
|||||||
fmt.Fprintf(&sb, "\tApprovedRoutes: %v\n", node.ApprovedRoutes)
|
fmt.Fprintf(&sb, "\tApprovedRoutes: %v\n", node.ApprovedRoutes)
|
||||||
fmt.Fprintf(&sb, "\tAnnouncedRoutes: %v\n", node.AnnouncedRoutes())
|
fmt.Fprintf(&sb, "\tAnnouncedRoutes: %v\n", node.AnnouncedRoutes())
|
||||||
fmt.Fprintf(&sb, "\tSubnetRoutes: %v\n", node.SubnetRoutes())
|
fmt.Fprintf(&sb, "\tSubnetRoutes: %v\n", node.SubnetRoutes())
|
||||||
|
fmt.Fprintf(&sb, "\tExitRoutes: %v\n", node.ExitRoutes())
|
||||||
sb.WriteString("\n")
|
sb.WriteString("\n")
|
||||||
|
|
||||||
return sb.String()
|
return sb.String()
|
||||||
@@ -730,6 +750,13 @@ func (v NodeView) IsSubnetRouter() bool {
|
|||||||
return v.ж.IsSubnetRouter()
|
return v.ж.IsSubnetRouter()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v NodeView) AllApprovedRoutes() []netip.Prefix {
|
||||||
|
if !v.Valid() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return v.ж.AllApprovedRoutes()
|
||||||
|
}
|
||||||
|
|
||||||
func (v NodeView) AppendToIPSet(build *netipx.IPSetBuilder) {
|
func (v NodeView) AppendToIPSet(build *netipx.IPSetBuilder) {
|
||||||
if !v.Valid() {
|
if !v.Valid() {
|
||||||
return
|
return
|
||||||
@@ -808,6 +835,13 @@ func (v NodeView) ExitRoutes() []netip.Prefix {
|
|||||||
return v.ж.ExitRoutes()
|
return v.ж.ExitRoutes()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v NodeView) IsExitNode() bool {
|
||||||
|
if !v.Valid() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return v.ж.IsExitNode()
|
||||||
|
}
|
||||||
|
|
||||||
// RequestTags returns the ACL tags that the node is requesting.
|
// RequestTags returns the ACL tags that the node is requesting.
|
||||||
func (v NodeView) RequestTags() []string {
|
func (v NodeView) RequestTags() []string {
|
||||||
if !v.Valid() || !v.Hostinfo().Valid() {
|
if !v.Valid() || !v.Hostinfo().Valid() {
|
||||||
|
|||||||
Reference in New Issue
Block a user