Преглед изворни кода

NET-1990: add peerkey to network egress routes model (#3379)

* add peerkey to network egress routes model

* add peerkey to network egress routes model

* filter out conflicting routes from node

* add support for egress HA on relay

* add support for egress HA on relay

* add support for egress HA on relay

* skip if curr node is relay node of the peer

* skip if curr node is relay node of the peer

* fix failover egress HA

* add network to egress route model

* clone before modifying
Abhishek K пре 5 месеци
родитељ
комит
4cc56fd3be
4 измењених фајлова са 80 додато и 4 уклоњено
  1. 1 0
      logic/extpeers.go
  2. 76 3
      logic/peers.go
  3. 2 0
      models/mqtt.go
  4. 1 1
      pro/controllers/users.go

+ 1 - 0
logic/extpeers.go

@@ -854,6 +854,7 @@ func GetExtPeers(node, peer *models.Node) ([]wgtypes.PeerConfig, []models.IDandA
 
 func getExtPeerEgressRoute(node models.Node, extPeer models.ExtClient) (egressRoutes []models.EgressNetworkRoutes) {
 	egressRoutes = append(egressRoutes, models.EgressNetworkRoutes{
+		PeerKey:       extPeer.PublicKey,
 		EgressGwAddr:  extPeer.AddressIPNet4(),
 		EgressGwAddr6: extPeer.AddressIPNet6(),
 		NodeAddr:      node.Address,

+ 76 - 3
logic/peers.go

@@ -241,20 +241,45 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
 				PersistentKeepaliveInterval: &peerHost.PersistentKeepalive,
 				ReplaceAllowedIPs:           true,
 			}
+			_, isFailOverPeer := node.FailOverPeers[peer.ID.String()]
 			if peer.IsEgressGateway {
+				peerKey := peerHost.PublicKey.String()
+				if isFailOverPeer && peer.FailedOverBy.String() != node.ID.String() {
+					// get relay host
+					failOverNode, err := GetNodeByID(peer.FailedOverBy.String())
+					if err == nil {
+						relayHost, err := GetHost(failOverNode.HostID.String())
+						if err == nil {
+							peerKey = relayHost.PublicKey.String()
+						}
+					}
+				}
+				if peer.IsRelayed && (peer.RelayedBy != node.ID.String()) {
+					// get relay host
+					relayNode, err := GetNodeByID(peer.RelayedBy)
+					if err == nil {
+						relayHost, err := GetHost(relayNode.HostID.String())
+						if err == nil {
+							peerKey = relayHost.PublicKey.String()
+						}
+					}
+				}
+
 				hostPeerUpdate.EgressRoutes = append(hostPeerUpdate.EgressRoutes, models.EgressNetworkRoutes{
+					PeerKey:                peerKey,
 					EgressGwAddr:           peer.Address,
 					EgressGwAddr6:          peer.Address6,
 					NodeAddr:               node.Address,
 					NodeAddr6:              node.Address6,
-					EgressRanges:           peer.EgressGatewayRanges,
-					EgressRangesWithMetric: peer.EgressGatewayRequest.RangesWithMetric,
+					EgressRanges:           filterConflictingEgressRoutes(node, peer),
+					EgressRangesWithMetric: filterConflictingEgressRoutesWithMetric(node, peer),
+					Network:                peer.Network,
 				})
 			}
 			if peer.IsIngressGateway {
 				hostPeerUpdate.EgressRoutes = append(hostPeerUpdate.EgressRoutes, getExtpeersExtraRoutes(node)...)
 			}
-			_, isFailOverPeer := node.FailOverPeers[peer.ID.String()]
+
 			if (node.IsRelayed && node.RelayedBy != peer.ID.String()) ||
 				(peer.IsRelayed && peer.RelayedBy != node.ID.String()) || isFailOverPeer {
 				// if node is relayed and peer is not the relay, set remove to true
@@ -517,6 +542,42 @@ func GetPeerListenPort(host *models.Host) int {
 	return peerPort
 }
 
+func filterConflictingEgressRoutes(node, peer models.Node) []string {
+	egressIPs := slices.Clone(peer.EgressGatewayRanges)
+	if node.IsEgressGateway {
+		// filter conflicting addrs
+		nodeEgressMap := make(map[string]struct{})
+		for _, rangeI := range node.EgressGatewayRanges {
+			nodeEgressMap[rangeI] = struct{}{}
+		}
+		for i := len(egressIPs) - 1; i >= 0; i-- {
+			if _, ok := nodeEgressMap[egressIPs[i]]; ok {
+				egressIPs = append(egressIPs[:i], egressIPs[i+1:]...)
+			}
+		}
+	}
+
+	return egressIPs
+}
+
+func filterConflictingEgressRoutesWithMetric(node, peer models.Node) []models.EgressRangeMetric {
+	egressIPs := slices.Clone(peer.EgressGatewayRequest.RangesWithMetric)
+	if node.IsEgressGateway {
+		// filter conflicting addrs
+		nodeEgressMap := make(map[string]struct{})
+		for _, rangeI := range node.EgressGatewayRanges {
+			nodeEgressMap[rangeI] = struct{}{}
+		}
+		for i := len(egressIPs) - 1; i >= 0; i-- {
+			if _, ok := nodeEgressMap[egressIPs[i].Network]; ok {
+				egressIPs = append(egressIPs[:i], egressIPs[i+1:]...)
+			}
+		}
+	}
+
+	return egressIPs
+}
+
 // GetAllowedIPs - calculates the wireguard allowedip field for a peer of a node based on the peer and node settings
 func GetAllowedIPs(node, peer *models.Node, metrics *models.Metrics) []net.IPNet {
 	var allowedips []net.IPNet
@@ -605,6 +666,18 @@ func getNodeAllowedIPs(peer, node *models.Node) []net.IPNet {
 	if peer.IsEgressGateway {
 		// hasGateway = true
 		egressIPs := GetEgressIPs(peer)
+		if node.IsEgressGateway {
+			// filter conflicting addrs
+			nodeEgressMap := make(map[string]struct{})
+			for _, rangeI := range node.EgressGatewayRanges {
+				nodeEgressMap[rangeI] = struct{}{}
+			}
+			for i := len(egressIPs) - 1; i >= 0; i-- {
+				if _, ok := nodeEgressMap[egressIPs[i].String()]; ok {
+					egressIPs = append(egressIPs[:i], egressIPs[i+1:]...)
+				}
+			}
+		}
 		allowedips = append(allowedips, egressIPs...)
 	}
 	if peer.IsRelay {

+ 2 - 0
models/mqtt.go

@@ -70,12 +70,14 @@ type EgressInfo struct {
 
 // EgressNetworkRoutes - struct for egress network routes for adding routes to peer's interface
 type EgressNetworkRoutes struct {
+	PeerKey                string              `json:"peer_key"`
 	EgressGwAddr           net.IPNet           `json:"egress_gw_addr" yaml:"egress_gw_addr"`
 	EgressGwAddr6          net.IPNet           `json:"egress_gw_addr6" yaml:"egress_gw_addr6"`
 	NodeAddr               net.IPNet           `json:"node_addr"`
 	NodeAddr6              net.IPNet           `json:"node_addr6"`
 	EgressRanges           []string            `json:"egress_ranges"`
 	EgressRangesWithMetric []EgressRangeMetric `json:"egress_ranges_metric"`
+	Network                string              `json:"network"`
 }
 
 // PeerRouteInfo - struct for peer info for an ext. client

+ 1 - 1
pro/controllers/users.go

@@ -424,7 +424,7 @@ func createUserGroup(w http.ResponseWriter, r *http.Request) {
 			ID:          uuid.New().String(),
 			Name:        fmt.Sprintf("%s group", userGroupReq.Group.Name),
 			MetaData:    "This Policy allows user group to communicate with all gateways",
-			Default:     true,
+			Default:     false,
 			ServiceType: models.Any,
 			NetworkID:   models.NetworkID(network.NetID),
 			Proto:       models.ALL,