|  | @@ -5,7 +5,6 @@ import (
 | 
	
		
			
				|  |  |  	"encoding/json"
 | 
	
		
			
				|  |  |  	"errors"
 | 
	
		
			
				|  |  |  	"maps"
 | 
	
		
			
				|  |  | -	"net"
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	"github.com/gravitl/netmaker/db"
 | 
	
		
			
				|  |  |  	"github.com/gravitl/netmaker/models"
 | 
	
	
		
			
				|  | @@ -20,41 +19,12 @@ func ValidateEgressReq(e *schema.Egress) error {
 | 
	
		
			
				|  |  |  	if err != nil {
 | 
	
		
			
				|  |  |  		return errors.New("failed to get network " + err.Error())
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | -	if !e.IsInetGw {
 | 
	
		
			
				|  |  | -		if e.Range == "" {
 | 
	
		
			
				|  |  | -			return errors.New("egress range is empty")
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		_, _, err = net.ParseCIDR(e.Range)
 | 
	
		
			
				|  |  | -		if err != nil {
 | 
	
		
			
				|  |  | -			return errors.New("invalid egress range " + err.Error())
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		err = ValidateEgressRange(e.Network, []string{e.Range})
 | 
	
		
			
				|  |  | -		if err != nil {
 | 
	
		
			
				|  |  | -			return errors.New("invalid egress range " + err.Error())
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -	} else {
 | 
	
		
			
				|  |  | -		if len(e.Nodes) > 1 {
 | 
	
		
			
				|  |  | -			return errors.New("can only set one internet routing node")
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		acls, _ := ListAclsByNetwork(models.NetworkID(e.Network))
 | 
	
		
			
				|  |  | -		req := models.InetNodeReq{}
 | 
	
		
			
				|  |  | -		eli, _ := (&schema.Egress{Network: e.Network}).ListByNetwork(db.WithContext(context.TODO()))
 | 
	
		
			
				|  |  | -		for k := range e.Nodes {
 | 
	
		
			
				|  |  | -			inetNode, err := GetNodeByID(k)
 | 
	
		
			
				|  |  | -			if err != nil {
 | 
	
		
			
				|  |  | -				return errors.New("invalid routing node " + err.Error())
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -			// check if node is acting as egress gw already
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -			GetNodeEgressInfo(&inetNode, eli, acls)
 | 
	
		
			
				|  |  | -			if err := ValidateInetGwReq(inetNode, req, false); err != nil {
 | 
	
		
			
				|  |  | -				return err
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +	if len(e.Nodes) > 1 {
 | 
	
		
			
				|  |  | +		return errors.New("can only set one internet routing node")
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | -	if len(e.Nodes) != 0 {
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if len(e.Nodes) > 0 {
 | 
	
		
			
				|  |  |  		for k := range e.Nodes {
 | 
	
		
			
				|  |  |  			_, err := GetNodeByID(k)
 | 
	
		
			
				|  |  |  			if err != nil {
 | 
	
	
		
			
				|  | @@ -68,29 +38,19 @@ func ValidateEgressReq(e *schema.Egress) error {
 | 
	
		
			
				|  |  |  func DoesNodeHaveAccessToEgress(node *models.Node, e *schema.Egress, acls []models.Acl) bool {
 | 
	
		
			
				|  |  |  	nodeTags := maps.Clone(node.Tags)
 | 
	
		
			
				|  |  |  	nodeTags[models.TagID(node.ID.String())] = struct{}{}
 | 
	
		
			
				|  |  | -	if !e.IsInetGw {
 | 
	
		
			
				|  |  | -		nodeTags[models.TagID("*")] = struct{}{}
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	if !e.IsInetGw {
 | 
	
		
			
				|  |  | -		defaultDevicePolicy, _ := GetDefaultPolicy(models.NetworkID(node.Network), models.DevicePolicy)
 | 
	
		
			
				|  |  | -		if defaultDevicePolicy.Enabled {
 | 
	
		
			
				|  |  | -			return true
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  |  	for _, acl := range acls {
 | 
	
		
			
				|  |  |  		if !acl.Enabled {
 | 
	
		
			
				|  |  |  			continue
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  		srcVal := ConvAclTagToValueMap(acl.Src)
 | 
	
		
			
				|  |  | -		if !e.IsInetGw && acl.AllowedDirection == models.TrafficDirectionBi {
 | 
	
		
			
				|  |  | +		if acl.AllowedDirection == models.TrafficDirectionBi {
 | 
	
		
			
				|  |  |  			if _, ok := srcVal["*"]; ok {
 | 
	
		
			
				|  |  |  				return true
 | 
	
		
			
				|  |  |  			}
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  		for _, dstI := range acl.Dst {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -			if !e.IsInetGw && dstI.ID == models.NodeTagID && dstI.Value == "*" {
 | 
	
		
			
				|  |  | +			if dstI.ID == models.NodeTagID && dstI.Value == "*" {
 | 
	
		
			
				|  |  |  				return true
 | 
	
		
			
				|  |  |  			}
 | 
	
		
			
				|  |  |  			if dstI.ID == models.EgressID && dstI.Value == e.ID {
 | 
	
	
		
			
				|  | @@ -127,21 +87,11 @@ func AddEgressInfoToPeerByAccess(node, targetNode *models.Node, eli []schema.Egr
 | 
	
		
			
				|  |  |  		NodeID: targetNode.ID.String(),
 | 
	
		
			
				|  |  |  		NetID:  targetNode.Network,
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | -	defer func() {
 | 
	
		
			
				|  |  | -		if targetNode.Mutex != nil {
 | 
	
		
			
				|  |  | -			targetNode.Mutex.Lock()
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		IsNodeUsingInternetGw(targetNode, acls)
 | 
	
		
			
				|  |  | -		if targetNode.Mutex != nil {
 | 
	
		
			
				|  |  | -			targetNode.Mutex.Unlock()
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -	}()
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  	for _, e := range eli {
 | 
	
		
			
				|  |  |  		if !e.Status || e.Network != targetNode.Network {
 | 
	
		
			
				|  |  |  			continue
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  | -		if !isDefaultPolicyActive || e.IsInetGw {
 | 
	
		
			
				|  |  | +		if !isDefaultPolicyActive {
 | 
	
		
			
				|  |  |  			if !DoesNodeHaveAccessToEgress(node, &e, acls) {
 | 
	
		
			
				|  |  |  				if node.IsRelayed && node.RelayedBy == targetNode.ID.String() {
 | 
	
		
			
				|  |  |  					if !DoesNodeHaveAccessToEgress(targetNode, &e, acls) {
 | 
	
	
		
			
				|  | @@ -155,37 +105,17 @@ func AddEgressInfoToPeerByAccess(node, targetNode *models.Node, eli []schema.Egr
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  		if metric, ok := e.Nodes[targetNode.ID.String()]; ok {
 | 
	
		
			
				|  |  | -			if e.IsInetGw {
 | 
	
		
			
				|  |  | -				targetNode.EgressDetails.IsInternetGateway = true
 | 
	
		
			
				|  |  | -				targetNode.EgressDetails.InetNodeReq = models.InetNodeReq{
 | 
	
		
			
				|  |  | -					InetNodeClientIDs: GetInetClientsFromAclPolicies(e.ID),
 | 
	
		
			
				|  |  | -				}
 | 
	
		
			
				|  |  | -				req.Ranges = append(req.Ranges, "0.0.0.0/0")
 | 
	
		
			
				|  |  | -				req.RangesWithMetric = append(req.RangesWithMetric, models.EgressRangeMetric{
 | 
	
		
			
				|  |  | -					Network:     "0.0.0.0/0",
 | 
	
		
			
				|  |  | -					Nat:         true,
 | 
	
		
			
				|  |  | -					RouteMetric: 256,
 | 
	
		
			
				|  |  | -				})
 | 
	
		
			
				|  |  | -				req.Ranges = append(req.Ranges, "::/0")
 | 
	
		
			
				|  |  | -				req.RangesWithMetric = append(req.RangesWithMetric, models.EgressRangeMetric{
 | 
	
		
			
				|  |  | -					Network:     "::/0",
 | 
	
		
			
				|  |  | -					Nat:         true,
 | 
	
		
			
				|  |  | -					RouteMetric: 256,
 | 
	
		
			
				|  |  | -				})
 | 
	
		
			
				|  |  | -			} else {
 | 
	
		
			
				|  |  | -				m64, err := metric.(json.Number).Int64()
 | 
	
		
			
				|  |  | -				if err != nil {
 | 
	
		
			
				|  |  | -					m64 = 256
 | 
	
		
			
				|  |  | -				}
 | 
	
		
			
				|  |  | -				m := uint32(m64)
 | 
	
		
			
				|  |  | -				req.Ranges = append(req.Ranges, e.Range)
 | 
	
		
			
				|  |  | -				req.RangesWithMetric = append(req.RangesWithMetric, models.EgressRangeMetric{
 | 
	
		
			
				|  |  | -					Network:     e.Range,
 | 
	
		
			
				|  |  | -					Nat:         e.Nat,
 | 
	
		
			
				|  |  | -					RouteMetric: m,
 | 
	
		
			
				|  |  | -				})
 | 
	
		
			
				|  |  | +			m64, err := metric.(json.Number).Int64()
 | 
	
		
			
				|  |  | +			if err != nil {
 | 
	
		
			
				|  |  | +				m64 = 256
 | 
	
		
			
				|  |  |  			}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +			m := uint32(m64)
 | 
	
		
			
				|  |  | +			req.Ranges = append(req.Ranges, e.Range)
 | 
	
		
			
				|  |  | +			req.RangesWithMetric = append(req.RangesWithMetric, models.EgressRangeMetric{
 | 
	
		
			
				|  |  | +				Network:     e.Range,
 | 
	
		
			
				|  |  | +				Nat:         e.Nat,
 | 
	
		
			
				|  |  | +				RouteMetric: m,
 | 
	
		
			
				|  |  | +			})
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  	if targetNode.Mutex != nil {
 | 
	
	
		
			
				|  | @@ -205,132 +135,28 @@ func AddEgressInfoToPeerByAccess(node, targetNode *models.Node, eli []schema.Egr
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -// TODO
 | 
	
		
			
				|  |  | -func GetNetworkEgressInfo(network models.NetworkID, acls []models.Acl) (egressNodes map[string]models.Node) {
 | 
	
		
			
				|  |  | -	eli, _ := (&schema.Egress{Network: network.String()}).ListByNetwork(db.WithContext(context.TODO()))
 | 
	
		
			
				|  |  | -	egressNodes = make(map[string]models.Node)
 | 
	
		
			
				|  |  | -	var err error
 | 
	
		
			
				|  |  | -	for _, e := range eli {
 | 
	
		
			
				|  |  | -		if !e.Status || e.Nodes == nil {
 | 
	
		
			
				|  |  | -			continue
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		for nodeID, metric := range e.Nodes {
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -			targetNode, ok := egressNodes[nodeID]
 | 
	
		
			
				|  |  | -			if !ok {
 | 
	
		
			
				|  |  | -				targetNode, err = GetNodeByID(nodeID)
 | 
	
		
			
				|  |  | -				if err != nil {
 | 
	
		
			
				|  |  | -					continue
 | 
	
		
			
				|  |  | -				}
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -			req := models.EgressGatewayRequest{
 | 
	
		
			
				|  |  | -				NodeID: targetNode.ID.String(),
 | 
	
		
			
				|  |  | -				NetID:  targetNode.Network,
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -			IsNodeUsingInternetGw(&targetNode, acls)
 | 
	
		
			
				|  |  | -			if e.IsInetGw {
 | 
	
		
			
				|  |  | -				targetNode.EgressDetails.IsInternetGateway = true
 | 
	
		
			
				|  |  | -				targetNode.EgressDetails.InetNodeReq = models.InetNodeReq{
 | 
	
		
			
				|  |  | -					InetNodeClientIDs: GetInetClientsFromAclPolicies(e.ID),
 | 
	
		
			
				|  |  | -				}
 | 
	
		
			
				|  |  | -				req.Ranges = append(req.Ranges, "0.0.0.0/0")
 | 
	
		
			
				|  |  | -				req.RangesWithMetric = append(req.RangesWithMetric, models.EgressRangeMetric{
 | 
	
		
			
				|  |  | -					Network:     "0.0.0.0/0",
 | 
	
		
			
				|  |  | -					Nat:         true,
 | 
	
		
			
				|  |  | -					RouteMetric: 256,
 | 
	
		
			
				|  |  | -				})
 | 
	
		
			
				|  |  | -				req.Ranges = append(req.Ranges, "::/0")
 | 
	
		
			
				|  |  | -				req.RangesWithMetric = append(req.RangesWithMetric, models.EgressRangeMetric{
 | 
	
		
			
				|  |  | -					Network:     "::/0",
 | 
	
		
			
				|  |  | -					Nat:         true,
 | 
	
		
			
				|  |  | -					RouteMetric: 256,
 | 
	
		
			
				|  |  | -				})
 | 
	
		
			
				|  |  | -			} else {
 | 
	
		
			
				|  |  | -				m64, err := metric.(json.Number).Int64()
 | 
	
		
			
				|  |  | -				if err != nil {
 | 
	
		
			
				|  |  | -					m64 = 256
 | 
	
		
			
				|  |  | -				}
 | 
	
		
			
				|  |  | -				m := uint32(m64)
 | 
	
		
			
				|  |  | -				req.Ranges = append(req.Ranges, e.Range)
 | 
	
		
			
				|  |  | -				req.RangesWithMetric = append(req.RangesWithMetric, models.EgressRangeMetric{
 | 
	
		
			
				|  |  | -					Network:     e.Range,
 | 
	
		
			
				|  |  | -					Nat:         e.Nat,
 | 
	
		
			
				|  |  | -					RouteMetric: m,
 | 
	
		
			
				|  |  | -				})
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -			if targetNode.Mutex != nil {
 | 
	
		
			
				|  |  | -				targetNode.Mutex.Lock()
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -			if len(req.Ranges) > 0 {
 | 
	
		
			
				|  |  | -				targetNode.EgressDetails.IsEgressGateway = true
 | 
	
		
			
				|  |  | -				targetNode.EgressDetails.EgressGatewayRanges = append(targetNode.EgressDetails.EgressGatewayRanges, req.Ranges...)
 | 
	
		
			
				|  |  | -				targetNode.EgressDetails.EgressGatewayRequest.Ranges = append(targetNode.EgressDetails.EgressGatewayRequest.Ranges, req.Ranges...)
 | 
	
		
			
				|  |  | -				targetNode.EgressDetails.EgressGatewayRequest.RangesWithMetric = append(targetNode.EgressDetails.EgressGatewayRequest.RangesWithMetric,
 | 
	
		
			
				|  |  | -					req.RangesWithMetric...)
 | 
	
		
			
				|  |  | -				targetNode.EgressDetails.EgressGatewayRequest = req
 | 
	
		
			
				|  |  | -				egressNodes[targetNode.ID.String()] = targetNode
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -			if targetNode.Mutex != nil {
 | 
	
		
			
				|  |  | -				targetNode.Mutex.Unlock()
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -	}
 | 
	
		
			
				|  |  | -	return
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  func GetNodeEgressInfo(targetNode *models.Node, eli []schema.Egress, acls []models.Acl) {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	req := models.EgressGatewayRequest{
 | 
	
		
			
				|  |  |  		NodeID: targetNode.ID.String(),
 | 
	
		
			
				|  |  |  		NetID:  targetNode.Network,
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  | -	defer func() {
 | 
	
		
			
				|  |  | -		if targetNode.Mutex != nil {
 | 
	
		
			
				|  |  | -			targetNode.Mutex.Lock()
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -		IsNodeUsingInternetGw(targetNode, acls)
 | 
	
		
			
				|  |  | -		if targetNode.Mutex != nil {
 | 
	
		
			
				|  |  | -			targetNode.Mutex.Unlock()
 | 
	
		
			
				|  |  | -		}
 | 
	
		
			
				|  |  | -	}()
 | 
	
		
			
				|  |  |  	for _, e := range eli {
 | 
	
		
			
				|  |  |  		if !e.Status || e.Network != targetNode.Network {
 | 
	
		
			
				|  |  |  			continue
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  		if metric, ok := e.Nodes[targetNode.ID.String()]; ok {
 | 
	
		
			
				|  |  | -			if e.IsInetGw {
 | 
	
		
			
				|  |  | -				targetNode.EgressDetails.IsInternetGateway = true
 | 
	
		
			
				|  |  | -				targetNode.EgressDetails.InetNodeReq = models.InetNodeReq{
 | 
	
		
			
				|  |  | -					InetNodeClientIDs: GetInetClientsFromAclPolicies(e.ID),
 | 
	
		
			
				|  |  | -				}
 | 
	
		
			
				|  |  | -				req.Ranges = append(req.Ranges, "0.0.0.0/0")
 | 
	
		
			
				|  |  | -				req.RangesWithMetric = append(req.RangesWithMetric, models.EgressRangeMetric{
 | 
	
		
			
				|  |  | -					Network:     "0.0.0.0/0",
 | 
	
		
			
				|  |  | -					Nat:         true,
 | 
	
		
			
				|  |  | -					RouteMetric: 256,
 | 
	
		
			
				|  |  | -				})
 | 
	
		
			
				|  |  | -				req.Ranges = append(req.Ranges, "::/0")
 | 
	
		
			
				|  |  | -				req.RangesWithMetric = append(req.RangesWithMetric, models.EgressRangeMetric{
 | 
	
		
			
				|  |  | -					Network:     "::/0",
 | 
	
		
			
				|  |  | -					Nat:         true,
 | 
	
		
			
				|  |  | -					RouteMetric: 256,
 | 
	
		
			
				|  |  | -				})
 | 
	
		
			
				|  |  | -			} else {
 | 
	
		
			
				|  |  | -				m64, err := metric.(json.Number).Int64()
 | 
	
		
			
				|  |  | -				if err != nil {
 | 
	
		
			
				|  |  | -					m64 = 256
 | 
	
		
			
				|  |  | -				}
 | 
	
		
			
				|  |  | -				m := uint32(m64)
 | 
	
		
			
				|  |  | -				req.Ranges = append(req.Ranges, e.Range)
 | 
	
		
			
				|  |  | -				req.RangesWithMetric = append(req.RangesWithMetric, models.EgressRangeMetric{
 | 
	
		
			
				|  |  | -					Network:     e.Range,
 | 
	
		
			
				|  |  | -					Nat:         e.Nat,
 | 
	
		
			
				|  |  | -					RouteMetric: m,
 | 
	
		
			
				|  |  | -				})
 | 
	
		
			
				|  |  | -			}
 | 
	
		
			
				|  |  | +			m64, err := metric.(json.Number).Int64()
 | 
	
		
			
				|  |  | +			if err != nil {
 | 
	
		
			
				|  |  | +				m64 = 256
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +			m := uint32(m64)
 | 
	
		
			
				|  |  | +			req.Ranges = append(req.Ranges, e.Range)
 | 
	
		
			
				|  |  | +			req.RangesWithMetric = append(req.RangesWithMetric, models.EgressRangeMetric{
 | 
	
		
			
				|  |  | +				Network:     e.Range,
 | 
	
		
			
				|  |  | +				Nat:         e.Nat,
 | 
	
		
			
				|  |  | +				RouteMetric: m,
 | 
	
		
			
				|  |  | +			})
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  	}
 |