mirror of
https://github.com/slackhq/nebula.git
synced 2025-04-28 14:42:22 +00:00
70 lines
1.4 KiB
Go
70 lines
1.4 KiB
Go
package routing
|
|
|
|
import (
|
|
"fmt"
|
|
"net/netip"
|
|
)
|
|
|
|
const (
|
|
// Sentinal value
|
|
BucketNotCalculated = -1
|
|
)
|
|
|
|
type Gateways []Gateway
|
|
|
|
func (g Gateways) String() string {
|
|
str := ""
|
|
for i, gw := range g {
|
|
str += gw.String()
|
|
if i < len(g)-1 {
|
|
str += ", "
|
|
}
|
|
}
|
|
return str
|
|
}
|
|
|
|
type Gateway struct {
|
|
addr netip.Addr
|
|
weight int
|
|
bucketUpperBound int
|
|
}
|
|
|
|
func NewGateway(addr netip.Addr, weight int) Gateway {
|
|
return Gateway{addr: addr, weight: weight, bucketUpperBound: BucketNotCalculated}
|
|
}
|
|
|
|
func (g *Gateway) BucketUpperBound() int {
|
|
return g.bucketUpperBound
|
|
}
|
|
|
|
func (g *Gateway) Addr() netip.Addr {
|
|
return g.addr
|
|
}
|
|
|
|
func (g *Gateway) String() string {
|
|
return fmt.Sprintf("{addr: %s, weight: %d}", g.addr, g.weight)
|
|
}
|
|
|
|
// Divide and round to nearest integer
|
|
func divideAndRound(v uint64, d uint64) uint64 {
|
|
var tmp uint64 = v + d/2
|
|
return tmp / d
|
|
}
|
|
|
|
// Implements Hash-Threshold mapping, equivalent to the implementation in the linux kernel.
|
|
// After this function returns each gateway will have a
|
|
// positive bucketUpperBound with a maximum value of 2147483647 (INT_MAX)
|
|
func CalculateBucketsForGateways(gateways []Gateway) {
|
|
|
|
var totalWeight int = 0
|
|
for i := range gateways {
|
|
totalWeight += gateways[i].weight
|
|
}
|
|
|
|
var loopWeight int = 0
|
|
for i := range gateways {
|
|
loopWeight += gateways[i].weight
|
|
gateways[i].bucketUpperBound = int(divideAndRound(uint64(loopWeight)<<31, uint64(totalWeight))) - 1
|
|
}
|
|
|
|
}
|