2022-11-16 10:51:49 +01:00
|
|
|
package pools
|
|
|
|
|
|
|
|
import (
|
|
|
|
"reflect"
|
|
|
|
"sync"
|
|
|
|
|
|
|
|
"github.com/alice-lg/alice-lg/pkg/api"
|
|
|
|
)
|
|
|
|
|
2022-11-16 11:12:09 +01:00
|
|
|
// CommunitiesPool is for deduplicating a list of BGP communities
|
2022-11-16 10:51:49 +01:00
|
|
|
// (Large and default. The ext communities representation right now
|
|
|
|
// makes problems and need to be fixed. TODO.)
|
2022-11-16 11:12:09 +01:00
|
|
|
type CommunitiesPool struct {
|
|
|
|
communitiesRoot *Node
|
|
|
|
root *Node
|
2022-11-16 10:51:49 +01:00
|
|
|
sync.Mutex
|
|
|
|
}
|
|
|
|
|
2022-11-16 11:12:09 +01:00
|
|
|
// NewCommunitiesPool creates a new pool for lists
|
2022-11-16 10:51:49 +01:00
|
|
|
// of BGP communities.
|
2022-11-16 11:12:09 +01:00
|
|
|
func NewCommunitiesPool() *CommunitiesPool {
|
|
|
|
return &CommunitiesPool{
|
2022-11-16 11:20:54 +01:00
|
|
|
communitiesRoot: NewNode([]int{}),
|
|
|
|
root: NewNode([]api.Community{}),
|
2022-11-16 10:51:49 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Acquire a list of bgp communities
|
2022-11-16 11:12:09 +01:00
|
|
|
func (p *CommunitiesPool) Acquire(communities []api.Community) []api.Community {
|
|
|
|
p.Lock()
|
|
|
|
defer p.Unlock()
|
|
|
|
// Make identification list by using the pointer address
|
|
|
|
// of the deduplicated community as ID
|
2022-11-16 10:51:49 +01:00
|
|
|
ids := make([]int, len(communities))
|
|
|
|
for i, comm := range communities {
|
2022-11-16 11:12:09 +01:00
|
|
|
commPtr := p.communitiesRoot.traverse(comm, comm)
|
2022-11-16 10:51:49 +01:00
|
|
|
addr := reflect.ValueOf(commPtr).UnsafePointer()
|
|
|
|
ids[i] = int(uintptr(addr))
|
|
|
|
}
|
|
|
|
if len(ids) == 0 {
|
|
|
|
return p.root.ptr.([]api.Community)
|
|
|
|
}
|
|
|
|
return p.root.traverse(communities, ids).([]api.Community)
|
|
|
|
}
|
2022-11-16 13:30:44 +01:00
|
|
|
|
|
|
|
// NewExtCommunitiesPool creates a new pool for extended communities
|
|
|
|
func NewExtCommunitiesPool() *CommunitiesPool {
|
|
|
|
return &CommunitiesPool{
|
|
|
|
communitiesRoot: NewNode([]int{}),
|
|
|
|
root: NewNode([]api.ExtCommunity{}),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// AcquireExt a list of ext bgp communities
|
|
|
|
func (p *CommunitiesPool) AcquireExt(communities []api.ExtCommunity) []api.ExtCommunity {
|
|
|
|
p.Lock()
|
|
|
|
defer p.Unlock()
|
|
|
|
|
|
|
|
// Make identification list
|
|
|
|
ids := make([]int, len(communities))
|
|
|
|
for i, comm := range communities {
|
|
|
|
r := 0 // RO
|
|
|
|
if comm[0].(string) == "rt" {
|
|
|
|
r = 1
|
|
|
|
}
|
|
|
|
icomm := []int{r, comm[1].(int), comm[2].(int)}
|
|
|
|
|
|
|
|
// get community identifier
|
|
|
|
commPtr := p.communitiesRoot.traverse(icomm, icomm)
|
|
|
|
addr := reflect.ValueOf(commPtr).UnsafePointer()
|
|
|
|
ids[i] = int(uintptr(addr))
|
|
|
|
}
|
|
|
|
if len(ids) == 0 {
|
|
|
|
return p.root.ptr.([]api.ExtCommunity)
|
|
|
|
}
|
|
|
|
return p.root.traverse(communities, ids).([]api.ExtCommunity)
|
|
|
|
}
|