diff --git a/control/controlclient/netmap.go b/control/controlclient/netmap.go index 2f7f39a5b..819560ab1 100644 --- a/control/controlclient/netmap.go +++ b/control/controlclient/netmap.go @@ -273,7 +273,7 @@ func (nm *NetworkMap) WGCfg(logf logger.Logf, flags WGConfigFlags) (*wgcfg.Confi logf("wgcfg: %v skipping default route", peer.Key.ShortString()) continue } - } else if allowedIP.Mask < 32 { + } else if cidrIsSubnet(peer, allowedIP) { if (flags & AllowSubnetRoutes) == 0 { logf("wgcfg: %v skipping subnet route", peer.Key.ShortString()) continue @@ -286,6 +286,29 @@ func (nm *NetworkMap) WGCfg(logf logger.Logf, flags WGConfigFlags) (*wgcfg.Confi return cfg, nil } +// cidrIsSubnet reports whether cidr is a non-default-route subnet +// exported by node that is not one of its own self addresses. +func cidrIsSubnet(node *tailcfg.Node, cidr wgcfg.CIDR) bool { + if cidr.Mask == 0 { + return false + } + if cidr.Mask < 32 { + // Fast path for IPv4, to avoid loop below. + // + // TODO: if cidr.IP is an IPv6 address, we could do "< 128" + // to avoid the range over node.Addresses. Or we could + // just remove this fast path and unconditionally do the range + // loop. + return true + } + for _, selfCIDR := range node.Addresses { + if cidr == selfCIDR { + return false + } + } + return true +} + func appendEndpoint(peer *wgcfg.Peer, epStr string) error { if epStr == "" { return nil