mirror of
https://github.com/tailscale/tailscale.git
synced 2025-10-24 17:48:57 +00:00
wgengine/filter: support FilterRules matching on srcIP node caps [capver 100]
See #12542 for background. Updates #12542 Change-Id: Ida312f700affc00d17681dc7551ee9672eeb1789 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
committed by
Maisem Ali
parent
07063bc5c7
commit
5ec01bf3ce
@@ -4,19 +4,23 @@
|
||||
package filter
|
||||
|
||||
import (
|
||||
"net/netip"
|
||||
|
||||
"tailscale.com/net/packet"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/views"
|
||||
"tailscale.com/wgengine/filter/filtertype"
|
||||
)
|
||||
|
||||
type matches []filtertype.Match
|
||||
|
||||
func (ms matches) match(q *packet.Parsed) bool {
|
||||
for _, m := range ms {
|
||||
func (ms matches) match(q *packet.Parsed, hasCap CapTestFunc) bool {
|
||||
for i := range ms {
|
||||
m := &ms[i]
|
||||
if !views.SliceContains(m.IPProto, q.IPProto) {
|
||||
continue
|
||||
}
|
||||
if !m.SrcsContains(q.Src.Addr()) {
|
||||
if !srcMatches(m, q.Src.Addr(), hasCap) {
|
||||
continue
|
||||
}
|
||||
for _, dst := range m.Dsts {
|
||||
@@ -32,9 +36,33 @@ func (ms matches) match(q *packet.Parsed) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (ms matches) matchIPsOnly(q *packet.Parsed) bool {
|
||||
// srcMatches reports whether srcAddr matche the src requirements in m, either
|
||||
// by Srcs (using SrcsContains), or by the node having a capability listed
|
||||
// in SrcCaps using the provided hasCap function.
|
||||
func srcMatches(m *filtertype.Match, srcAddr netip.Addr, hasCap CapTestFunc) bool {
|
||||
if m.SrcsContains(srcAddr) {
|
||||
return true
|
||||
}
|
||||
if hasCap != nil {
|
||||
for _, c := range m.SrcCaps {
|
||||
if hasCap(srcAddr, c) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// CapTestFunc is the function signature of a function that tests whether srcIP
|
||||
// has a given capability.
|
||||
//
|
||||
// It it used in the fast path of evaluating filter rules so should be fast.
|
||||
type CapTestFunc = func(srcIP netip.Addr, cap tailcfg.NodeCapability) bool
|
||||
|
||||
func (ms matches) matchIPsOnly(q *packet.Parsed, hasCap CapTestFunc) bool {
|
||||
srcAddr := q.Src.Addr()
|
||||
for _, m := range ms {
|
||||
if !m.SrcsContains(q.Src.Addr()) {
|
||||
if !m.SrcsContains(srcAddr) {
|
||||
continue
|
||||
}
|
||||
for _, dst := range m.Dsts {
|
||||
@@ -43,6 +71,15 @@ func (ms matches) matchIPsOnly(q *packet.Parsed) bool {
|
||||
}
|
||||
}
|
||||
}
|
||||
if hasCap != nil {
|
||||
for _, m := range ms {
|
||||
for _, c := range m.SrcCaps {
|
||||
if hasCap(srcAddr, c) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user