mirror of
https://github.com/netbirdio/netbird.git
synced 2024-11-25 09:33:24 +01:00
32880c56a4
Restructure data handling for improved performance and flexibility. Introduce 'G'-prefixed fields to represent Gorm relations, simplifying resource management. Eliminate complexity in lookup tables for enhanced query and write speed. Enable independent operations on data structures, requiring adjustments in the Store interface and Account Manager.
167 lines
4.2 KiB
Go
167 lines
4.2 KiB
Go
package route
|
|
|
|
import (
|
|
"net/netip"
|
|
|
|
"github.com/netbirdio/netbird/management/server/status"
|
|
)
|
|
|
|
// Windows has some limitation regarding metric size that differ from Unix-like systems.
|
|
// Because of that we are limiting the min and max metric size based on Windows limits:
|
|
// see based on info from https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/route_ws2008
|
|
const (
|
|
// MinMetric max metric input
|
|
MinMetric = 1
|
|
// MaxMetric max metric input
|
|
MaxMetric = 9999
|
|
// MaxNetIDChar Max Network Identifier
|
|
MaxNetIDChar = 40
|
|
)
|
|
|
|
const (
|
|
// InvalidNetworkString invalid network type string
|
|
InvalidNetworkString = "Invalid"
|
|
// IPv4NetworkString IPv4 network type string
|
|
IPv4NetworkString = "IPv4"
|
|
// IPv6NetworkString IPv6 network type string
|
|
IPv6NetworkString = "IPv6"
|
|
)
|
|
|
|
const (
|
|
// InvalidNetwork invalid network type
|
|
InvalidNetwork NetworkType = iota
|
|
// IPv4Network IPv4 network type
|
|
IPv4Network
|
|
// IPv6Network IPv6 network type
|
|
IPv6Network
|
|
)
|
|
|
|
// NetworkType route network type
|
|
type NetworkType int
|
|
|
|
// String returns prefix type string
|
|
func (p NetworkType) String() string {
|
|
switch p {
|
|
case IPv4Network:
|
|
return IPv4NetworkString
|
|
case IPv6Network:
|
|
return IPv6NetworkString
|
|
default:
|
|
return InvalidNetworkString
|
|
}
|
|
}
|
|
|
|
// ToPrefixType returns a prefix type
|
|
func ToPrefixType(prefix string) NetworkType {
|
|
switch prefix {
|
|
case IPv4NetworkString:
|
|
return IPv4Network
|
|
case IPv6NetworkString:
|
|
return IPv6Network
|
|
default:
|
|
return InvalidNetwork
|
|
}
|
|
}
|
|
|
|
// Route represents a route
|
|
type Route struct {
|
|
ID string `gorm:"primaryKey"`
|
|
// AccountID is a reference to Account that this object belongs
|
|
AccountID string `gorm:"index"`
|
|
Network netip.Prefix `gorm:"serializer:gob"`
|
|
NetID string
|
|
Description string
|
|
Peer string
|
|
PeerGroups []string `gorm:"serializer:gob"`
|
|
NetworkType NetworkType
|
|
Masquerade bool
|
|
Metric int
|
|
Enabled bool
|
|
Groups []string `gorm:"serializer:json"`
|
|
}
|
|
|
|
// EventMeta returns activity event meta related to the route
|
|
func (r *Route) EventMeta() map[string]any {
|
|
return map[string]any{"name": r.NetID, "network_range": r.Network.String(), "peer_id": r.Peer, "peer_groups": r.PeerGroups}
|
|
}
|
|
|
|
// Copy copies a route object
|
|
func (r *Route) Copy() *Route {
|
|
route := &Route{
|
|
ID: r.ID,
|
|
Description: r.Description,
|
|
NetID: r.NetID,
|
|
Network: r.Network,
|
|
NetworkType: r.NetworkType,
|
|
Peer: r.Peer,
|
|
PeerGroups: make([]string, len(r.PeerGroups)),
|
|
Metric: r.Metric,
|
|
Masquerade: r.Masquerade,
|
|
Enabled: r.Enabled,
|
|
Groups: make([]string, len(r.Groups)),
|
|
}
|
|
copy(route.Groups, r.Groups)
|
|
copy(route.PeerGroups, r.PeerGroups)
|
|
return route
|
|
}
|
|
|
|
// IsEqual compares one route with the other
|
|
func (r *Route) IsEqual(other *Route) bool {
|
|
return other.ID == r.ID &&
|
|
other.Description == r.Description &&
|
|
other.NetID == r.NetID &&
|
|
other.Network == r.Network &&
|
|
other.NetworkType == r.NetworkType &&
|
|
other.Peer == r.Peer &&
|
|
other.Metric == r.Metric &&
|
|
other.Masquerade == r.Masquerade &&
|
|
other.Enabled == r.Enabled &&
|
|
compareList(r.Groups, other.Groups) &&
|
|
compareList(r.PeerGroups, other.PeerGroups)
|
|
}
|
|
|
|
// ParseNetwork Parses a network prefix string and returns a netip.Prefix object and if is invalid, IPv4 or IPv6
|
|
func ParseNetwork(networkString string) (NetworkType, netip.Prefix, error) {
|
|
prefix, err := netip.ParsePrefix(networkString)
|
|
if err != nil {
|
|
return InvalidNetwork, netip.Prefix{}, status.Errorf(status.InvalidArgument, "invalid network %s", networkString)
|
|
}
|
|
|
|
masked := prefix.Masked()
|
|
|
|
if !masked.IsValid() {
|
|
return InvalidNetwork, netip.Prefix{}, status.Errorf(status.InvalidArgument, "invalid range %s", networkString)
|
|
}
|
|
|
|
if masked.Addr().Is6() {
|
|
return IPv6Network, masked, nil
|
|
}
|
|
|
|
return IPv4Network, masked, nil
|
|
}
|
|
|
|
func compareList(list, other []string) bool {
|
|
if len(list) != len(other) {
|
|
return false
|
|
}
|
|
for _, id := range list {
|
|
match := false
|
|
for _, otherID := range other {
|
|
if id == otherID {
|
|
match = true
|
|
break
|
|
}
|
|
}
|
|
if !match {
|
|
return false
|
|
}
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
// GetHAUniqueID returns a highly available route ID by combining Network ID and Network range address
|
|
func GetHAUniqueID(input *Route) string {
|
|
return input.NetID + "-" + input.Network.String()
|
|
}
|