mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-22 21:39:08 +02:00
buildPeerACLView optimized
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"slices"
|
"slices"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
@@ -112,9 +113,7 @@ func (b *NetworkMapBuilder) buildGlobalIndexes(account *Account) {
|
|||||||
clear(b.cache.policyToRules)
|
clear(b.cache.policyToRules)
|
||||||
clear(b.cache.groupToPolicies)
|
clear(b.cache.groupToPolicies)
|
||||||
|
|
||||||
for id, peer := range account.Peers {
|
maps.Copy(b.cache.globalPeers, account.Peers)
|
||||||
b.cache.globalPeers[id] = peer
|
|
||||||
}
|
|
||||||
|
|
||||||
for groupID, group := range account.Groups {
|
for groupID, group := range account.Groups {
|
||||||
peersCopy := make([]string, len(group.Peers))
|
peersCopy := make([]string, len(group.Peers))
|
||||||
@@ -153,7 +152,7 @@ func (b *NetworkMapBuilder) buildGlobalIndexes(account *Account) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *NetworkMapBuilder) buildPeerACLView(account *Account, peerID string) {
|
func (b *NetworkMapBuilder) buildPeerACLViewOld(account *Account, peerID string) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
peer := account.GetPeer(peerID)
|
peer := account.GetPeer(peerID)
|
||||||
if peer == nil {
|
if peer == nil {
|
||||||
@@ -193,6 +192,240 @@ func (b *NetworkMapBuilder) buildPeerACLView(account *Account, peerID string) {
|
|||||||
b.cache.peerACLs[peerID] = view
|
b.cache.peerACLs[peerID] = view
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *NetworkMapBuilder) buildPeerACLView(account *Account, peerID string) {
|
||||||
|
ctx := context.Background()
|
||||||
|
peer := account.GetPeer(peerID)
|
||||||
|
if peer == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
resourcePolicies := b.cache.resourcePolicies
|
||||||
|
resourceRouters := b.cache.resourceRouters
|
||||||
|
|
||||||
|
allPotentialPeers, firewallRules := b.getPeerConnectionResources(account, peerID, b.validatedPeers)
|
||||||
|
|
||||||
|
isRouter, networkResourcesRoutes, sourcePeers := account.GetNetworkResourcesRoutesToSync(ctx, peerID, resourcePolicies, resourceRouters)
|
||||||
|
|
||||||
|
var emptyExpiredPeers []*nbpeer.Peer
|
||||||
|
finalAllPeers := account.addNetworksRoutingPeers(
|
||||||
|
networkResourcesRoutes,
|
||||||
|
peer,
|
||||||
|
allPotentialPeers,
|
||||||
|
emptyExpiredPeers,
|
||||||
|
isRouter,
|
||||||
|
sourcePeers,
|
||||||
|
)
|
||||||
|
|
||||||
|
view := &PeerACLView{
|
||||||
|
ConnectedPeerIDs: make([]string, 0, len(finalAllPeers)),
|
||||||
|
FirewallRuleIDs: make([]string, 0, len(firewallRules)),
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, p := range finalAllPeers {
|
||||||
|
view.ConnectedPeerIDs = append(view.ConnectedPeerIDs, p.ID)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, rule := range firewallRules {
|
||||||
|
ruleID := b.generateFirewallRuleID(rule)
|
||||||
|
view.FirewallRuleIDs = append(view.FirewallRuleIDs, ruleID)
|
||||||
|
b.cache.globalRules[ruleID] = rule
|
||||||
|
}
|
||||||
|
|
||||||
|
b.cache.peerACLs[peerID] = view
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *NetworkMapBuilder) getPeerConnectionResources(
|
||||||
|
account *Account,
|
||||||
|
peerID string,
|
||||||
|
validatedPeersMap map[string]struct{},
|
||||||
|
) ([]*nbpeer.Peer, []*FirewallRule) {
|
||||||
|
|
||||||
|
peer := b.cache.globalPeers[peerID]
|
||||||
|
if peer == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
peerGroups := b.cache.peerToGroups[peerID]
|
||||||
|
peerGroupsMap := make(map[string]struct{}, len(peerGroups))
|
||||||
|
for _, groupID := range peerGroups {
|
||||||
|
peerGroupsMap[groupID] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
rulesExists := make(map[string]struct{})
|
||||||
|
peersExists := make(map[string]struct{})
|
||||||
|
fwRules := make([]*FirewallRule, 0)
|
||||||
|
peers := make([]*nbpeer.Peer, 0)
|
||||||
|
|
||||||
|
for _, group := range peerGroups {
|
||||||
|
|
||||||
|
policies := b.cache.groupToPolicies[group]
|
||||||
|
for _, policy := range policies {
|
||||||
|
|
||||||
|
rules := b.cache.policyToRules[policy.ID]
|
||||||
|
for _, rule := range rules {
|
||||||
|
|
||||||
|
peerInSources := b.isPeerInGroupsCached(rule.Sources, peerGroupsMap)
|
||||||
|
peerInDestinations := b.isPeerInGroupsCached(rule.Destinations, peerGroupsMap)
|
||||||
|
|
||||||
|
if !peerInSources && !peerInDestinations {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var sourcePeers []*nbpeer.Peer
|
||||||
|
if peerInDestinations {
|
||||||
|
sourcePeers = b.getPeersFromGroupsCached(account, rule.Sources, peerID, policy.SourcePostureChecks, validatedPeersMap)
|
||||||
|
}
|
||||||
|
|
||||||
|
var destinationPeers []*nbpeer.Peer
|
||||||
|
if peerInSources {
|
||||||
|
destinationPeers = b.getPeersFromGroupsCached(account, rule.Destinations, peerID, nil, validatedPeersMap)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rule.Bidirectional {
|
||||||
|
if peerInSources {
|
||||||
|
b.generateResourcesCached(
|
||||||
|
rule, destinationPeers, FirewallRuleDirectionIN,
|
||||||
|
peer, &peers, &fwRules, peersExists, rulesExists,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if peerInDestinations {
|
||||||
|
b.generateResourcesCached(
|
||||||
|
rule, sourcePeers, FirewallRuleDirectionOUT,
|
||||||
|
peer, &peers, &fwRules, peersExists, rulesExists,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if peerInSources {
|
||||||
|
b.generateResourcesCached(
|
||||||
|
rule, destinationPeers, FirewallRuleDirectionOUT,
|
||||||
|
peer, &peers, &fwRules, peersExists, rulesExists,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if peerInDestinations {
|
||||||
|
b.generateResourcesCached(
|
||||||
|
rule, sourcePeers, FirewallRuleDirectionIN,
|
||||||
|
peer, &peers, &fwRules, peersExists, rulesExists,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return peers, fwRules
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *NetworkMapBuilder) isPeerInGroupsCached(
|
||||||
|
groupIDs []string,
|
||||||
|
peerGroupsMap map[string]struct{},
|
||||||
|
) bool {
|
||||||
|
for _, groupID := range groupIDs {
|
||||||
|
if _, exists := peerGroupsMap[groupID]; exists {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *NetworkMapBuilder) getPeersFromGroupsCached(
|
||||||
|
account *Account,
|
||||||
|
groupIDs []string,
|
||||||
|
excludePeerID string,
|
||||||
|
postureChecksIDs []string,
|
||||||
|
validatedPeersMap map[string]struct{},
|
||||||
|
) []*nbpeer.Peer {
|
||||||
|
ctx := context.Background()
|
||||||
|
uniquePeers := make(map[string]*nbpeer.Peer)
|
||||||
|
|
||||||
|
for _, groupID := range groupIDs {
|
||||||
|
peerIDs := b.cache.groupToPeers[groupID]
|
||||||
|
for _, peerID := range peerIDs {
|
||||||
|
if peerID == excludePeerID {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := validatedPeersMap[peerID]; !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
peer := b.cache.globalPeers[peerID]
|
||||||
|
if peer == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(postureChecksIDs) > 0 {
|
||||||
|
if !account.validatePostureChecksOnPeer(ctx, postureChecksIDs, peerID) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uniquePeers[peerID] = peer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result := make([]*nbpeer.Peer, 0, len(uniquePeers))
|
||||||
|
for _, peer := range uniquePeers {
|
||||||
|
result = append(result, peer)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *NetworkMapBuilder) generateResourcesCached(
|
||||||
|
rule *PolicyRule,
|
||||||
|
groupPeers []*nbpeer.Peer,
|
||||||
|
direction int,
|
||||||
|
targetPeer *nbpeer.Peer,
|
||||||
|
peers *[]*nbpeer.Peer,
|
||||||
|
rules *[]*FirewallRule,
|
||||||
|
peersExists map[string]struct{},
|
||||||
|
rulesExists map[string]struct{},
|
||||||
|
) {
|
||||||
|
isAll := false
|
||||||
|
if allGroup, err := b.account.Load().GetGroupAll(); err == nil {
|
||||||
|
isAll = (len(allGroup.Peers) - 1) == len(groupPeers)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, peer := range groupPeers {
|
||||||
|
if peer == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := peersExists[peer.ID]; !ok {
|
||||||
|
*peers = append(*peers, peer)
|
||||||
|
peersExists[peer.ID] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
fr := FirewallRule{
|
||||||
|
PolicyID: rule.ID,
|
||||||
|
PeerIP: peer.IP.String(),
|
||||||
|
Direction: direction,
|
||||||
|
Action: string(rule.Action),
|
||||||
|
Protocol: string(rule.Protocol),
|
||||||
|
}
|
||||||
|
|
||||||
|
if isAll {
|
||||||
|
fr.PeerIP = "0.0.0.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
ruleID := rule.ID + fr.PeerIP + strconv.Itoa(direction) +
|
||||||
|
fr.Protocol + fr.Action + strings.Join(rule.Ports, ",")
|
||||||
|
|
||||||
|
if _, ok := rulesExists[ruleID]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
rulesExists[ruleID] = struct{}{}
|
||||||
|
|
||||||
|
if len(rule.Ports) == 0 && len(rule.PortRanges) == 0 {
|
||||||
|
*rules = append(*rules, &fr)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
*rules = append(*rules, expandPortsAndRanges(fr, rule, targetPeer)...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (b *NetworkMapBuilder) buildPeerRoutesView(account *Account, peerID string) {
|
func (b *NetworkMapBuilder) buildPeerRoutesView(account *Account, peerID string) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
peer := account.GetPeer(peerID)
|
peer := account.GetPeer(peerID)
|
||||||
|
|||||||
Reference in New Issue
Block a user