Bladeren bron

NET-2061: revert Inet gws, fix extclient comms with user policies (#3482)

* revert inet gws from acl policies

* add egress range with metric for inet gw

* link pro inet funcs

* fix extclient comms with users

* remove TODO comments
Abhishek K 3 maanden geleden
bovenliggende
commit
0f884d4f36

+ 0 - 2
controllers/acls.go

@@ -181,12 +181,10 @@ func aclDebug(w http.ResponseWriter, r *http.Request) {
 
 	allowed, ps := logic.IsNodeAllowedToCommunicate(node, peer, true)
 	isallowed := logic.IsPeerAllowed(node, peer, true)
-	acls, _ := logic.ListAclsByNetwork(models.NetworkID(node.Network))
 	re := resp{
 		IsNodeAllowed: allowed,
 		IsPeerAllowed: isallowed,
 		Policies:      ps,
-		EgressNets:    logic.GetNetworkEgressInfo(models.NetworkID(node.Network), acls),
 	}
 	if peerIsStatic == "true" {
 		ingress, err := logic.GetNodeByID(peer.StaticNode.IngressGatewayID)

+ 0 - 27
controllers/egress.go

@@ -62,7 +62,6 @@ func createEgress(w http.ResponseWriter, r *http.Request) {
 		Description: req.Description,
 		Range:       egressRange,
 		Nat:         req.Nat,
-		IsInetGw:    req.IsInetGw,
 		Nodes:       make(datatypes.JSONMap),
 		Tags:        make(datatypes.JSONMap),
 		Status:      true,
@@ -85,23 +84,6 @@ func createEgress(w http.ResponseWriter, r *http.Request) {
 		)
 		return
 	}
-	if e.IsInetGw {
-		for nodeID := range req.Nodes {
-			node, err := logic.GetNodeByID(nodeID)
-			if err == nil && !node.IsGw {
-				node.IsGw = true
-				node.IsIngressGateway = true
-				node.IsRelay = true
-				if node.Address.IP != nil {
-					node.IngressDNS = node.Address.IP.String()
-				} else {
-					node.IngressDNS = node.Address6.IP.String()
-				}
-
-				logic.UpsertNode(&node)
-			}
-		}
-	}
 	logic.LogEvent(&models.Event{
 		Action: models.Create,
 		Source: models.Subject{
@@ -196,14 +178,10 @@ func updateEgress(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 	var updateNat bool
-	var updateInetGw bool
 	var updateStatus bool
 	if req.Nat != e.Nat {
 		updateNat = true
 	}
-	if req.IsInetGw != e.IsInetGw {
-		updateInetGw = true
-	}
 	if req.Status != e.Status {
 		updateStatus = true
 	}
@@ -236,7 +214,6 @@ func updateEgress(w http.ResponseWriter, r *http.Request) {
 	e.Name = req.Name
 	e.Nat = req.Nat
 	e.Status = req.Status
-	e.IsInetGw = req.IsInetGw
 	e.UpdatedAt = time.Now().UTC()
 	if err := logic.ValidateEgressReq(&e); err != nil {
 		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
@@ -255,10 +232,6 @@ func updateEgress(w http.ResponseWriter, r *http.Request) {
 		e.Nat = req.Nat
 		e.UpdateNatStatus(db.WithContext(context.TODO()))
 	}
-	if updateInetGw {
-		e.IsInetGw = req.IsInetGw
-		e.UpdateINetGwStatus(db.WithContext(context.TODO()))
-	}
 	if updateStatus {
 		e.Status = req.Status
 		e.UpdateEgressStatus(db.WithContext(context.TODO()))

+ 1 - 1
controllers/ext_client.go

@@ -546,7 +546,7 @@ func getExtClientHAConf(w http.ResponseWriter, r *http.Request) {
 		keepalive = "PersistentKeepalive = " + strconv.Itoa(int(gwnode.IngressPersistentKeepalive))
 	}
 	var newAllowedIPs string
-	if logic.IsInternetGw(gwnode) || gwnode.EgressDetails.InternetGwID != "" {
+	if logic.IsInternetGw(gwnode) || gwnode.InternetGwID != "" {
 		egressrange := "0.0.0.0/0"
 		if gwnode.Address6.IP != nil && client.Address6 != "" {
 			egressrange += "," + "::/0"

+ 0 - 70
logic/acls.go

@@ -608,35 +608,6 @@ func checkIfAclTagisValid(a models.Acl, t models.AclPolicyTag, isSrc bool) (err
 		if err != nil {
 			return errors.New("invalid egress")
 		}
-		if e.IsInetGw {
-			req := models.InetNodeReq{}
-			for _, srcI := range a.Src {
-				if srcI.ID == models.NodeID {
-					_, nodeErr := GetNodeByID(srcI.Value)
-					if nodeErr != nil {
-						_, staticNodeErr := GetExtClient(srcI.Value, a.NetworkID.String())
-						if staticNodeErr != nil {
-							return errors.New("invalid node " + srcI.Value)
-						}
-					} else {
-						req.InetNodeClientIDs = append(req.InetNodeClientIDs, srcI.Value)
-					}
-
-				}
-			}
-			if len(e.Nodes) > 0 {
-				for k := range e.Nodes {
-					inetNode, err := GetNodeByID(k)
-					if err != nil {
-						return errors.New("invalid node " + k)
-					}
-					if err = ValidateInetGwReq(inetNode, req, false); err != nil {
-						return err
-					}
-				}
-			}
-
-		}
 	default:
 		return errors.New("invalid policy")
 	}
@@ -846,47 +817,6 @@ var GetInetClientsFromAclPolicies = func(eID string) (inetClientIDs []string) {
 	return
 
 }
-var IsNodeUsingInternetGw = func(node *models.Node, acls []models.Acl) {
-	host, err := GetHost(node.HostID.String())
-	if err != nil {
-		return
-	}
-	if host.IsDefault || node.IsFailOver {
-		return
-	}
-	var isUsing bool
-	for _, acl := range acls {
-		if !acl.Enabled {
-			continue
-		}
-		srcVal := ConvAclTagToValueMap(acl.Src)
-		for _, dstI := range acl.Dst {
-			if dstI.ID == models.EgressID {
-				e := schema.Egress{ID: dstI.Value}
-				err := e.Get(db.WithContext(context.TODO()))
-				if err != nil || !e.Status {
-					continue
-				}
-
-				if e.IsInetGw {
-					if _, ok := srcVal[node.ID.String()]; ok {
-						for nodeID := range e.Nodes {
-							if nodeID == node.ID.String() {
-								continue
-							}
-							node.EgressDetails.InternetGwID = nodeID
-							isUsing = true
-							return
-						}
-					}
-				}
-			}
-		}
-	}
-	if !isUsing {
-		node.EgressDetails.InternetGwID = ""
-	}
-}
 
 var (
 	CreateDefaultTags = func(netID models.NetworkID) {}

+ 28 - 202
logic/egress.go

@@ -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,
+			})
 
 		}
 	}

+ 1 - 11
logic/extpeers.go

@@ -84,17 +84,7 @@ func GetEgressRangesOnNetwork(client *models.ExtClient) ([]string, error) {
 		GetNodeEgressInfo(&currentNode, eli, acls)
 		if currentNode.EgressDetails.IsEgressGateway { // add the egress gateway range(s) to the result
 			if len(currentNode.EgressDetails.EgressGatewayRanges) > 0 {
-				if currentNode.EgressDetails.IsInternetGateway && client.IngressGatewayID != currentNode.ID.String() {
-					for _, rangeI := range currentNode.EgressDetails.EgressGatewayRanges {
-						if rangeI == "0.0.0.0/0" || rangeI == "::/0" {
-							continue
-						} else {
-							result = append(result, rangeI)
-						}
-					}
-				} else {
-					result = append(result, currentNode.EgressDetails.EgressGatewayRanges...)
-				}
+				result = append(result, currentNode.EgressDetails.EgressGatewayRanges...)
 			}
 		}
 	}

+ 5 - 19
logic/gateway.go

@@ -1,7 +1,6 @@
 package logic
 
 import (
-	"context"
 	"errors"
 	"fmt"
 	"slices"
@@ -9,27 +8,14 @@ import (
 	"time"
 
 	"github.com/gravitl/netmaker/database"
-	"github.com/gravitl/netmaker/db"
 	"github.com/gravitl/netmaker/logger"
 	"github.com/gravitl/netmaker/models"
-	"github.com/gravitl/netmaker/schema"
 	"github.com/gravitl/netmaker/servercfg"
 )
 
 // IsInternetGw - checks if node is acting as internet gw
 func IsInternetGw(node models.Node) bool {
-	e := schema.Egress{
-		Network: node.Network,
-	}
-	egList, _ := e.ListByNetwork(db.WithContext(context.TODO()))
-	for _, egI := range egList {
-		if egI.IsInetGw {
-			if _, ok := egI.Nodes[node.ID.String()]; ok {
-				return true
-			}
-		}
-	}
-	return false
+	return node.IsInternetGateway
 }
 
 // GetInternetGateways - gets all the nodes that are internet gateways
@@ -40,7 +26,7 @@ func GetInternetGateways() ([]models.Node, error) {
 	}
 	igs := make([]models.Node, 0)
 	for _, node := range nodes {
-		if node.EgressDetails.IsInternetGateway {
+		if node.IsInternetGateway {
 			igs = append(igs, node)
 		}
 	}
@@ -205,12 +191,12 @@ func CreateIngressGateway(netid string, nodeid string, ingress models.IngressReq
 	node.IsIngressGateway = true
 	node.IsGw = true
 	if !servercfg.IsPro {
-		node.EgressDetails.IsInternetGateway = ingress.IsInternetGateway
+		node.IsInternetGateway = ingress.IsInternetGateway
 	}
 	node.IngressGatewayRange = network.AddressRange
 	node.IngressGatewayRange6 = network.AddressRange6
 	node.IngressDNS = ingress.ExtclientDNS
-	if node.EgressDetails.IsInternetGateway && node.IngressDNS == "" {
+	if node.IsInternetGateway && node.IngressDNS == "" {
 		node.IngressDNS = "1.1.1.1"
 	}
 	node.IngressPersistentKeepalive = 20
@@ -284,7 +270,7 @@ func DeleteIngressGateway(nodeid string) (models.Node, []models.ExtClient, error
 	node.LastModified = time.Now().UTC()
 	node.IsIngressGateway = false
 	if !servercfg.IsPro {
-		node.EgressDetails.IsInternetGateway = false
+		node.IsInternetGateway = false
 	}
 	delete(node.Tags, models.TagID(fmt.Sprintf("%s.%s", node.Network, models.GwTagName)))
 	node.IngressGatewayRange = ""

+ 5 - 161
logic/nodes.go

@@ -30,8 +30,6 @@ var (
 	nodeNetworkCacheMutex = &sync.RWMutex{}
 	nodesCacheMap         = make(map[string]models.Node)
 	nodesNetworkCacheMap  = make(map[string]map[string]models.Node)
-	IPv4Network           = "0.0.0.0/0"
-	IPv6Network           = "::/0"
 )
 
 func getNodeFromCache(nodeID string) (node models.Node, ok bool) {
@@ -283,21 +281,21 @@ func DeleteNode(node *models.Node, purge bool) error {
 		// unset all the relayed nodes
 		SetRelayedNodes(false, node.ID.String(), node.RelayedNodes)
 	}
-	if node.EgressDetails.InternetGwID != "" {
-		inetNode, err := GetNodeByID(node.EgressDetails.InternetGwID)
+	if node.InternetGwID != "" {
+		inetNode, err := GetNodeByID(node.InternetGwID)
 		if err == nil {
 			clientNodeIDs := []string{}
-			for _, inetNodeClientID := range inetNode.EgressDetails.InetNodeReq.InetNodeClientIDs {
+			for _, inetNodeClientID := range inetNode.InetNodeReq.InetNodeClientIDs {
 				if inetNodeClientID == node.ID.String() {
 					continue
 				}
 				clientNodeIDs = append(clientNodeIDs, inetNodeClientID)
 			}
-			inetNode.EgressDetails.InetNodeReq.InetNodeClientIDs = clientNodeIDs
+			inetNode.InetNodeReq.InetNodeClientIDs = clientNodeIDs
 			UpsertNode(&inetNode)
 		}
 	}
-	if node.EgressDetails.IsInternetGateway {
+	if node.IsInternetGateway {
 		UnsetInternetGw(node)
 	}
 	if !purge && !alreadyDeleted {
@@ -826,157 +824,3 @@ func GetAllFailOvers() ([]models.Node, error) {
 	}
 	return igs, nil
 }
-
-func ValidateInetGwReq(inetNode models.Node, req models.InetNodeReq, update bool) error {
-	inetHost, err := GetHost(inetNode.HostID.String())
-	if err != nil {
-		return err
-	}
-	if inetHost.FirewallInUse == models.FIREWALL_NONE {
-		return errors.New("iptables or nftables needs to be installed")
-	}
-	if inetNode.EgressDetails.InternetGwID != "" {
-		return fmt.Errorf("node %s is using a internet gateway already", inetHost.Name)
-	}
-	if inetNode.IsRelayed {
-		return fmt.Errorf("node %s is being relayed", inetHost.Name)
-	}
-
-	for _, clientNodeID := range req.InetNodeClientIDs {
-		clientNode, err := GetNodeByID(clientNodeID)
-		if err != nil {
-			return err
-		}
-		if clientNode.IsFailOver {
-			return errors.New("failover node cannot be set to use internet gateway")
-		}
-		clientHost, err := GetHost(clientNode.HostID.String())
-		if err != nil {
-			return err
-		}
-		if clientHost.IsDefault {
-			return errors.New("default host cannot be set to use internet gateway")
-		}
-		if clientHost.OS != models.OS_Types.Linux && clientHost.OS != models.OS_Types.Windows {
-			return errors.New("can only attach linux or windows machine to a internet gateway")
-		}
-		if clientNode.EgressDetails.IsInternetGateway {
-			return fmt.Errorf("node %s acting as internet gateway cannot use another internet gateway", clientHost.Name)
-		}
-		if update {
-			if clientNode.EgressDetails.InternetGwID != "" && clientNode.EgressDetails.InternetGwID != inetNode.ID.String() {
-				return fmt.Errorf("node %s is already using a internet gateway", clientHost.Name)
-			}
-		} else {
-			if clientNode.EgressDetails.InternetGwID != "" {
-				return fmt.Errorf("node %s is already using a internet gateway", clientHost.Name)
-			}
-		}
-		if clientNode.FailedOverBy != uuid.Nil {
-			ResetFailedOverPeer(&clientNode)
-		}
-
-		if clientNode.IsRelayed && clientNode.RelayedBy != inetNode.ID.String() {
-			return fmt.Errorf("node %s is being relayed", clientHost.Name)
-		}
-
-		for _, nodeID := range clientHost.Nodes {
-			node, err := GetNodeByID(nodeID)
-			if err != nil {
-				continue
-			}
-			if node.EgressDetails.InternetGwID != "" && node.EgressDetails.InternetGwID != inetNode.ID.String() {
-				return errors.New("nodes on same host cannot use different internet gateway")
-			}
-
-		}
-	}
-	return nil
-}
-
-// SetInternetGw - sets the node as internet gw based on flag bool
-func SetInternetGw(node *models.Node, req models.InetNodeReq) {
-	node.EgressDetails.IsInternetGateway = true
-	node.EgressDetails.InetNodeReq = req
-	for _, clientNodeID := range req.InetNodeClientIDs {
-		clientNode, err := GetNodeByID(clientNodeID)
-		if err != nil {
-			continue
-		}
-		clientNode.EgressDetails.InternetGwID = node.ID.String()
-		UpsertNode(&clientNode)
-	}
-
-}
-
-func UnsetInternetGw(node *models.Node) {
-	nodes, err := GetNetworkNodes(node.Network)
-	if err != nil {
-		slog.Error("failed to get network nodes", "network", node.Network, "error", err)
-		return
-	}
-	for _, clientNode := range nodes {
-		if node.ID.String() == clientNode.EgressDetails.InternetGwID {
-			clientNode.EgressDetails.InternetGwID = ""
-			UpsertNode(&clientNode)
-		}
-
-	}
-	node.EgressDetails.IsInternetGateway = false
-	node.EgressDetails.InetNodeReq = models.InetNodeReq{}
-
-}
-
-func SetDefaultGwForRelayedUpdate(relayed, relay models.Node, peerUpdate models.HostPeerUpdate) models.HostPeerUpdate {
-	if relay.EgressDetails.InternetGwID != "" {
-		relayedHost, err := GetHost(relayed.HostID.String())
-		if err != nil {
-			return peerUpdate
-		}
-		peerUpdate.ChangeDefaultGw = true
-		peerUpdate.DefaultGwIp = relay.Address.IP
-		if peerUpdate.DefaultGwIp == nil || relayedHost.EndpointIP == nil {
-			peerUpdate.DefaultGwIp = relay.Address6.IP
-		}
-
-	}
-	return peerUpdate
-}
-
-func SetDefaultGw(node models.Node, peerUpdate models.HostPeerUpdate) models.HostPeerUpdate {
-	if node.EgressDetails.InternetGwID != "" {
-
-		inetNode, err := GetNodeByID(node.EgressDetails.InternetGwID)
-		if err != nil {
-			return peerUpdate
-		}
-		host, err := GetHost(node.HostID.String())
-		if err != nil {
-			return peerUpdate
-		}
-
-		peerUpdate.ChangeDefaultGw = true
-		peerUpdate.DefaultGwIp = inetNode.Address.IP
-		if peerUpdate.DefaultGwIp == nil || host.EndpointIP == nil {
-			peerUpdate.DefaultGwIp = inetNode.Address6.IP
-		}
-	}
-	return peerUpdate
-}
-
-// GetAllowedIpForInetNodeClient - get inet cidr for node using a inet gw
-func GetAllowedIpForInetNodeClient(node, peer *models.Node) []net.IPNet {
-	var allowedips = []net.IPNet{}
-
-	if peer.Address.IP != nil {
-		_, ipnet, _ := net.ParseCIDR(IPv4Network)
-		allowedips = append(allowedips, *ipnet)
-	}
-
-	if peer.Address6.IP != nil {
-		_, ipnet, _ := net.ParseCIDR(IPv6Network)
-		allowedips = append(allowedips, *ipnet)
-	}
-
-	return allowedips
-}

+ 36 - 8
logic/peers.go

@@ -42,6 +42,25 @@ var (
 	CreateFailOver = func(node models.Node) error {
 		return nil
 	}
+	// SetDefaulGw
+	SetDefaultGw = func(node models.Node, peerUpdate models.HostPeerUpdate) models.HostPeerUpdate {
+		return peerUpdate
+	}
+	SetDefaultGwForRelayedUpdate = func(relayed, relay models.Node, peerUpdate models.HostPeerUpdate) models.HostPeerUpdate {
+		return peerUpdate
+	}
+	// UnsetInternetGw
+	UnsetInternetGw = func(node *models.Node) {
+		node.IsInternetGateway = false
+	}
+	// SetInternetGw
+	SetInternetGw = func(node *models.Node, req models.InetNodeReq) {
+		node.IsInternetGateway = true
+	}
+	// GetAllowedIpForInetNodeClient
+	GetAllowedIpForInetNodeClient = func(node, peer *models.Node) []net.IPNet {
+		return []net.IPNet{}
+	}
 )
 
 // GetHostPeerInfo - fetches required peer info per network
@@ -468,6 +487,14 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
 			if node.Address6.IP != nil {
 				egressrange = append(egressrange, "::/0")
 			}
+			rangeWithMetric := []models.EgressRangeMetric{}
+			for _, rangeI := range egressrange {
+				rangeWithMetric = append(rangeWithMetric, models.EgressRangeMetric{
+					Network:     rangeI,
+					RouteMetric: 256,
+					Nat:         true,
+				})
+			}
 			hostPeerUpdate.FwUpdate.EgressInfo[fmt.Sprintf("%s-%s", node.ID.String(), "inet")] = models.EgressInfo{
 				EgressID: fmt.Sprintf("%s-%s", node.ID.String(), "inet"),
 				Network:  node.PrimaryAddressIPNet(),
@@ -481,10 +508,11 @@ func GetPeerUpdateForHost(network string, host *models.Host, allNodes []models.N
 					Mask: getCIDRMaskFromAddr(node.Address6.IP.String()),
 				},
 				EgressGWCfg: models.EgressGatewayRequest{
-					NodeID:     fmt.Sprintf("%s-%s", node.ID.String(), "inet"),
-					NetID:      node.Network,
-					NatEnabled: "yes",
-					Ranges:     egressrange,
+					NodeID:           fmt.Sprintf("%s-%s", node.ID.String(), "inet"),
+					NetID:            node.Network,
+					NatEnabled:       "yes",
+					Ranges:           egressrange,
+					RangesWithMetric: rangeWithMetric,
 				},
 			}
 		}
@@ -583,15 +611,15 @@ func filterConflictingEgressRoutesWithMetric(node, peer models.Node) []models.Eg
 func GetAllowedIPs(node, peer *models.Node, metrics *models.Metrics) []net.IPNet {
 	var allowedips []net.IPNet
 	allowedips = getNodeAllowedIPs(peer, node)
-	if peer.EgressDetails.IsInternetGateway && node.EgressDetails.InternetGwID == peer.ID.String() {
+	if peer.IsInternetGateway && node.InternetGwID == peer.ID.String() {
 		allowedips = append(allowedips, GetAllowedIpForInetNodeClient(node, peer)...)
 		return allowedips
 	}
 	if node.IsRelayed && node.RelayedBy == peer.ID.String() {
 		allowedips = append(allowedips, GetAllowedIpsForRelayed(node, peer)...)
-		// if peer.EgressDetails.InternetGwID != "" {
-		// 	return allowedips
-		// }
+		if peer.InternetGwID != "" {
+			return allowedips
+		}
 	}
 
 	// handle ingress gateway peers

+ 5 - 5
logic/relay.go

@@ -123,10 +123,10 @@ func ValidateRelay(relay models.RelayRequest, update bool) error {
 		if relayedNode.IsIngressGateway {
 			return errors.New("cannot relay an ingress gateway (" + relayedNodeID + ")")
 		}
-		if relayedNode.EgressDetails.IsInternetGateway {
+		if relayedNode.IsInternetGateway {
 			return errors.New("cannot relay an internet gateway (" + relayedNodeID + ")")
 		}
-		if relayedNode.EgressDetails.InternetGwID != "" && relayedNode.EgressDetails.InternetGwID != relay.NodeID {
+		if relayedNode.InternetGwID != "" && relayedNode.InternetGwID != relay.NodeID {
 			return errors.New("cannot relay an internet client (" + relayedNodeID + ")")
 		}
 		if relayedNode.IsFailOver {
@@ -217,9 +217,9 @@ func GetAllowedIpsForRelayed(relayed, relay *models.Node) (allowedIPs []net.IPNe
 		logger.Log(0, "RelayedByRelay called with invalid parameters")
 		return
 	}
-	// if relay.EgressDetails.InternetGwID != "" {
-	// 	return GetAllowedIpForInetNodeClient(relayed, relay)
-	// }
+	if relay.InternetGwID != "" {
+		return GetAllowedIpForInetNodeClient(relayed, relay)
+	}
 	peers, err := GetNetworkNodes(relay.Network)
 	if err != nil {
 		logger.Log(0, "error getting network clients", err.Error())

+ 0 - 99
migrate/migrate.go

@@ -570,105 +570,6 @@ func migrateToEgressV1() {
 			logic.UpsertNode(&node)
 
 		}
-
-		if node.IsInternetGateway {
-			inetHost, err := logic.GetHost(node.HostID.String())
-			if err != nil {
-				continue
-			}
-			e := schema.Egress{
-				ID:          uuid.New().String(),
-				Name:        fmt.Sprintf("%s inet gw", inetHost.Name),
-				Description: "add description",
-				Network:     node.Network,
-				Nodes: datatypes.JSONMap{
-					node.ID.String(): 256,
-				},
-				Tags:      make(datatypes.JSONMap),
-				Range:     "*",
-				IsInetGw:  true,
-				Nat:       true,
-				Status:    true,
-				CreatedBy: user.UserName,
-				CreatedAt: time.Now().UTC(),
-			}
-			err = e.Create(db.WithContext(context.TODO()))
-			if err == nil {
-				node.IsEgressGateway = false
-				node.EgressGatewayRequest = models.EgressGatewayRequest{}
-				node.EgressGatewayNatEnabled = false
-				node.EgressGatewayRanges = []string{}
-				node.IsInternetGateway = false
-				src := []models.AclPolicyTag{}
-				for _, inetClientID := range node.InetNodeReq.InetNodeClientIDs {
-					_, err := logic.GetNodeByID(inetClientID)
-					if err == nil {
-						src = append(src, models.AclPolicyTag{
-							ID:    models.NodeID,
-							Value: inetClientID,
-						})
-					}
-				}
-				acl := models.Acl{
-					ID:          uuid.New().String(),
-					Name:        "exit node policy",
-					MetaData:    "all traffic on source nodes will pass through the destination node in the policy",
-					Default:     false,
-					ServiceType: models.Any,
-					NetworkID:   models.NetworkID(node.Network),
-					Proto:       models.ALL,
-					RuleType:    models.DevicePolicy,
-					Src:         src,
-					Dst: []models.AclPolicyTag{
-						{
-							ID:    models.EgressID,
-							Value: e.ID,
-						},
-					},
-
-					AllowedDirection: models.TrafficDirectionBi,
-					Enabled:          true,
-					CreatedBy:        "auto",
-					CreatedAt:        time.Now().UTC(),
-				}
-				logic.InsertAcl(acl)
-
-				acl = models.Acl{
-					ID:          uuid.New().String(),
-					Name:        "exit node policy",
-					MetaData:    "all traffic will pass through the destination node in the policy",
-					Default:     false,
-					ServiceType: models.Any,
-					NetworkID:   models.NetworkID(node.Network),
-					Proto:       models.ALL,
-					RuleType:    models.UserPolicy,
-					Src: []models.AclPolicyTag{
-						{
-							ID:    models.UserAclID,
-							Value: "*",
-						},
-					},
-					Dst: []models.AclPolicyTag{
-						{
-							ID:    models.EgressID,
-							Value: e.ID,
-						},
-					},
-
-					AllowedDirection: models.TrafficDirectionBi,
-					Enabled:          true,
-					CreatedBy:        "auto",
-					CreatedAt:        time.Now().UTC(),
-				}
-				logic.InsertAcl(acl)
-				node.InetNodeReq = models.InetNodeReq{}
-				logic.UpsertNode(&node)
-			}
-		}
-		if node.InternetGwID != "" {
-			node.InternetGwID = ""
-			logic.UpsertNode(&node)
-		}
 	}
 }
 

+ 6 - 6
models/api_node.go

@@ -86,9 +86,9 @@ func (a *ApiNode) ConvertToServerNode(currentNode *Node) *Node {
 	convertedNode.IngressDNS = a.IngressDns
 	convertedNode.IngressPersistentKeepalive = a.IngressPersistentKeepalive
 	convertedNode.IngressMTU = a.IngressMTU
-	convertedNode.EgressDetails.IsInternetGateway = a.IsInternetGateway
-	convertedNode.EgressDetails.InternetGwID = currentNode.EgressDetails.InternetGwID
-	convertedNode.EgressDetails.InetNodeReq = currentNode.EgressDetails.InetNodeReq
+	convertedNode.IsInternetGateway = a.IsInternetGateway
+	convertedNode.InternetGwID = currentNode.InternetGwID
+	convertedNode.InetNodeReq = currentNode.InetNodeReq
 	convertedNode.RelayedNodes = a.RelayedNodes
 	convertedNode.DefaultACL = a.DefaultACL
 	convertedNode.OwnerID = currentNode.OwnerID
@@ -196,9 +196,9 @@ func (nm *Node) ConvertToAPINode() *ApiNode {
 	apiNode.Connected = nm.Connected
 	apiNode.PendingDelete = nm.PendingDelete
 	apiNode.DefaultACL = nm.DefaultACL
-	apiNode.IsInternetGateway = nm.EgressDetails.IsInternetGateway
-	apiNode.InternetGwID = nm.EgressDetails.InternetGwID
-	apiNode.InetNodeReq = nm.EgressDetails.InetNodeReq
+	apiNode.IsInternetGateway = nm.IsInternetGateway
+	apiNode.InternetGwID = nm.InternetGwID
+	apiNode.InetNodeReq = nm.InetNodeReq
 	apiNode.IsFailOver = nm.IsFailOver
 	apiNode.FailOverPeers = nm.FailOverPeers
 	apiNode.FailedOverBy = nm.FailedOverBy

+ 3 - 3
models/node.go

@@ -127,9 +127,9 @@ type EgressDetails struct {
 	EgressGatewayRequest    EgressGatewayRequest
 	IsEgressGateway         bool
 	EgressGatewayRanges     []string
-	IsInternetGateway       bool        `json:"isinternetgateway"                                      yaml:"isinternetgateway"`
-	InetNodeReq             InetNodeReq `json:"inet_node_req"                                          yaml:"inet_node_req"`
-	InternetGwID            string      `json:"internetgw_node_id"                                     yaml:"internetgw_node_id"`
+	// IsInternetGateway       bool        `json:"isinternetgateway"                                      yaml:"isinternetgateway"`
+	// InetNodeReq             InetNodeReq `json:"inet_node_req"                                          yaml:"inet_node_req"`
+	// InternetGwID            string      `json:"internetgw_node_id"                                     yaml:"internetgw_node_id"`
 }
 
 // LegacyNode - legacy struct for node model

+ 8 - 8
pro/controllers/failover.go

@@ -253,8 +253,8 @@ func failOverME(w http.ResponseWriter, r *http.Request) {
 		)
 		return
 	}
-	if (node.EgressDetails.InternetGwID != "" && failOverNode.EgressDetails.IsInternetGateway && node.EgressDetails.InternetGwID != failOverNode.ID.String()) ||
-		(peerNode.EgressDetails.InternetGwID != "" && failOverNode.EgressDetails.IsInternetGateway && peerNode.EgressDetails.InternetGwID != failOverNode.ID.String()) {
+	if (node.InternetGwID != "" && failOverNode.IsInternetGateway && node.InternetGwID != failOverNode.ID.String()) ||
+		(peerNode.InternetGwID != "" && failOverNode.IsInternetGateway && peerNode.InternetGwID != failOverNode.ID.String()) {
 		logic.ReturnErrorResponse(
 			w,
 			r,
@@ -265,7 +265,7 @@ func failOverME(w http.ResponseWriter, r *http.Request) {
 		)
 		return
 	}
-	if node.EgressDetails.IsInternetGateway && peerNode.EgressDetails.InternetGwID == node.ID.String() {
+	if node.IsInternetGateway && peerNode.InternetGwID == node.ID.String() {
 		logic.ReturnErrorResponse(
 			w,
 			r,
@@ -276,7 +276,7 @@ func failOverME(w http.ResponseWriter, r *http.Request) {
 		)
 		return
 	}
-	if node.EgressDetails.InternetGwID != "" && node.EgressDetails.InternetGwID == peerNode.ID.String() {
+	if node.InternetGwID != "" && node.InternetGwID == peerNode.ID.String() {
 		logic.ReturnErrorResponse(
 			w,
 			r,
@@ -414,8 +414,8 @@ func checkfailOverCtx(w http.ResponseWriter, r *http.Request) {
 		)
 		return
 	}
-	if (node.EgressDetails.InternetGwID != "" && failOverNode.EgressDetails.IsInternetGateway && node.EgressDetails.InternetGwID != failOverNode.ID.String()) ||
-		(peerNode.EgressDetails.InternetGwID != "" && failOverNode.EgressDetails.IsInternetGateway && peerNode.EgressDetails.InternetGwID != failOverNode.ID.String()) {
+	if (node.InternetGwID != "" && failOverNode.IsInternetGateway && node.InternetGwID != failOverNode.ID.String()) ||
+		(peerNode.InternetGwID != "" && failOverNode.IsInternetGateway && peerNode.InternetGwID != failOverNode.ID.String()) {
 		logic.ReturnErrorResponse(
 			w,
 			r,
@@ -426,7 +426,7 @@ func checkfailOverCtx(w http.ResponseWriter, r *http.Request) {
 		)
 		return
 	}
-	if node.EgressDetails.IsInternetGateway && peerNode.EgressDetails.InternetGwID == node.ID.String() {
+	if node.IsInternetGateway && peerNode.InternetGwID == node.ID.String() {
 		logic.ReturnErrorResponse(
 			w,
 			r,
@@ -437,7 +437,7 @@ func checkfailOverCtx(w http.ResponseWriter, r *http.Request) {
 		)
 		return
 	}
-	if node.EgressDetails.InternetGwID != "" && node.EgressDetails.InternetGwID == peerNode.ID.String() {
+	if node.InternetGwID != "" && node.InternetGwID == peerNode.ID.String() {
 		logic.ReturnErrorResponse(
 			w,
 			r,

+ 4 - 4
pro/controllers/inet_gws.go

@@ -44,7 +44,7 @@ func createInternetGw(w http.ResponseWriter, r *http.Request) {
 		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
 		return
 	}
-	if node.EgressDetails.IsInternetGateway {
+	if node.IsInternetGateway {
 		logic.ReturnSuccessResponse(w, r, "node is already acting as internet gateway")
 		return
 	}
@@ -70,7 +70,7 @@ func createInternetGw(w http.ResponseWriter, r *http.Request) {
 		)
 		return
 	}
-	err = logic.ValidateInetGwReq(node, request, false)
+	err = proLogic.ValidateInetGwReq(node, request, false)
 	if err != nil {
 		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
 		return
@@ -132,7 +132,7 @@ func updateInternetGw(w http.ResponseWriter, r *http.Request) {
 		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
 		return
 	}
-	if !node.EgressDetails.IsInternetGateway {
+	if !node.IsInternetGateway {
 		logic.ReturnErrorResponse(
 			w,
 			r,
@@ -140,7 +140,7 @@ func updateInternetGw(w http.ResponseWriter, r *http.Request) {
 		)
 		return
 	}
-	err = logic.ValidateInetGwReq(node, request, true)
+	err = proLogic.ValidateInetGwReq(node, request, true)
 	if err != nil {
 		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
 		return

+ 4 - 4
pro/controllers/users.go

@@ -1092,7 +1092,7 @@ func getUserRemoteAccessNetworkGateways(w http.ResponseWriter, r *http.Request)
 			GwID:              node.ID.String(),
 			GWName:            host.Name,
 			Network:           node.Network,
-			IsInternetGateway: node.EgressDetails.IsInternetGateway,
+			IsInternetGateway: node.IsInternetGateway,
 			Metadata:          node.Metadata,
 		})
 
@@ -1219,7 +1219,7 @@ func getRemoteAccessGatewayConf(w http.ResponseWriter, r *http.Request) {
 		Network:           node.Network,
 		GwClient:          userConf,
 		Connected:         true,
-		IsInternetGateway: node.EgressDetails.IsInternetGateway,
+		IsInternetGateway: node.IsInternetGateway,
 		GwPeerPublicKey:   host.PublicKey.String(),
 		GwListenPort:      logic.GetPeerListenPort(host),
 		Metadata:          node.Metadata,
@@ -1311,7 +1311,7 @@ func getUserRemoteAccessGwsV1(w http.ResponseWriter, r *http.Request) {
 				Network:           node.Network,
 				GwClient:          extClient,
 				Connected:         true,
-				IsInternetGateway: node.EgressDetails.IsInternetGateway,
+				IsInternetGateway: node.IsInternetGateway,
 				GwPeerPublicKey:   host.PublicKey.String(),
 				GwListenPort:      logic.GetPeerListenPort(host),
 				Metadata:          node.Metadata,
@@ -1355,7 +1355,7 @@ func getUserRemoteAccessGwsV1(w http.ResponseWriter, r *http.Request) {
 			GwID:              node.ID.String(),
 			GWName:            host.Name,
 			Network:           node.Network,
-			IsInternetGateway: node.EgressDetails.IsInternetGateway,
+			IsInternetGateway: node.IsInternetGateway,
 			GwPeerPublicKey:   host.PublicKey.String(),
 			GwListenPort:      logic.GetPeerListenPort(host),
 			Metadata:          node.Metadata,

+ 5 - 1
pro/initialize.go

@@ -113,6 +113,11 @@ func InitPro() {
 	logic.UpdateMetrics = proLogic.UpdateMetrics
 	logic.DeleteMetrics = proLogic.DeleteMetrics
 	logic.GetTrialEndDate = getTrialEndDate
+	logic.SetDefaultGw = proLogic.SetDefaultGw
+	logic.SetDefaultGwForRelayedUpdate = proLogic.SetDefaultGwForRelayedUpdate
+	logic.UnsetInternetGw = proLogic.UnsetInternetGw
+	logic.SetInternetGw = proLogic.SetInternetGw
+	logic.GetAllowedIpForInetNodeClient = proLogic.GetAllowedIpForInetNodeClient
 	mq.UpdateMetrics = proLogic.MQUpdateMetrics
 	mq.UpdateMetricsFallBack = proLogic.MQUpdateMetricsFallBack
 	logic.GetFilteredNodesByUserAccess = proLogic.GetFilteredNodesByUserAccess
@@ -145,7 +150,6 @@ func InitPro() {
 	logic.IsUserAllowedToCommunicate = proLogic.IsUserAllowedToCommunicate
 	logic.DeleteAllNetworkTags = proLogic.DeleteAllNetworkTags
 	logic.CreateDefaultTags = proLogic.CreateDefaultTags
-	logic.IsNodeUsingInternetGw = proLogic.IsNodeUsingInternetGw
 	logic.GetInetClientsFromAclPolicies = proLogic.GetInetClientsFromAclPolicies
 	logic.IsPeerAllowed = proLogic.IsPeerAllowed
 	logic.IsAclPolicyValid = proLogic.IsAclPolicyValid

+ 36 - 134
pro/logic/acls.go

@@ -6,24 +6,12 @@ import (
 	"maps"
 	"net"
 
-	"github.com/google/uuid"
 	"github.com/gravitl/netmaker/db"
 	"github.com/gravitl/netmaker/logic"
 	"github.com/gravitl/netmaker/models"
 	"github.com/gravitl/netmaker/schema"
 )
 
-/*
-TODO: EGRESS
-1. allow only selection of egress ranges in a policy
-ranges should be replaced by egress identifier
-
-2. check logic required for MAC exit node
-
-3.
-
-*/
-
 func GetFwRulesForUserNodesOnGw(node models.Node, nodes []models.Node) (rules []models.FwRule) {
 	defaultUserPolicy, _ := logic.GetDefaultPolicy(models.NetworkID(node.Network), models.UserPolicy)
 	userNodes := logic.GetStaticUserNodesByNetwork(models.NetworkID(node.Network))
@@ -313,43 +301,6 @@ func checkIfAclTagisValid(a models.Acl, t models.AclPolicyTag, isSrc bool) (err
 		if err != nil {
 			return errors.New("invalid egress")
 		}
-		if e.IsInetGw {
-			req := models.InetNodeReq{}
-			for _, srcI := range a.Src {
-				if srcI.ID == models.NodeTagID {
-					nodesMap := GetNodesWithTag(models.TagID(srcI.Value))
-					for _, node := range nodesMap {
-						if node.ID != uuid.Nil {
-							req.InetNodeClientIDs = append(req.InetNodeClientIDs, node.ID.String())
-						}
-					}
-				} else if srcI.ID == models.NodeID {
-					_, nodeErr := logic.GetNodeByID(srcI.Value)
-					if nodeErr != nil {
-						_, staticNodeErr := logic.GetExtClient(srcI.Value, a.NetworkID.String())
-						if staticNodeErr != nil {
-							return errors.New("invalid node " + srcI.Value)
-						}
-					} else {
-						req.InetNodeClientIDs = append(req.InetNodeClientIDs, srcI.Value)
-					}
-
-				}
-			}
-			if len(e.Nodes) > 0 {
-				for k := range e.Nodes {
-					inetNode, err := logic.GetNodeByID(k)
-					if err != nil {
-						return errors.New("invalid node " + t.Value)
-					}
-					if err = logic.ValidateInetGwReq(inetNode, req, false); err != nil {
-						return err
-					}
-				}
-
-			}
-
-		}
 
 	case models.UserAclID:
 		if a.RuleType == models.DevicePolicy {
@@ -966,8 +917,18 @@ func getEgressUserRulesForNode(targetnode *models.Node,
 	acls := listUserPolicies(models.NetworkID(targetnode.Network))
 	var targetNodeTags = make(map[models.TagID]struct{})
 	targetNodeTags["*"] = struct{}{}
-	for _, rangeI := range targetnode.EgressDetails.EgressGatewayRanges {
-		targetNodeTags[models.TagID(rangeI)] = struct{}{}
+	egs, _ := (&schema.Egress{Network: targetnode.Network}).ListByNetwork(db.WithContext(context.TODO()))
+	if len(egs) == 0 {
+		return rules
+	}
+	for _, egI := range egs {
+		if !egI.Status {
+			continue
+		}
+		if _, ok := egI.Nodes[targetnode.ID.String()]; ok {
+			targetNodeTags[models.TagID(egI.Range)] = struct{}{}
+			targetNodeTags[models.TagID(egI.ID)] = struct{}{}
+		}
 	}
 	for _, acl := range acls {
 		if !acl.Enabled {
@@ -1051,26 +1012,15 @@ func getEgressUserRulesForNode(targetnode *models.Node,
 					if err != nil {
 						continue
 					}
-					if e.IsInetGw {
-						r.Dst = append(r.Dst, net.IPNet{
-							IP:   net.IPv4zero,
-							Mask: net.CIDRMask(0, 32),
-						})
-						r.Dst6 = append(r.Dst6, net.IPNet{
-							IP:   net.IPv6zero,
-							Mask: net.CIDRMask(0, 128),
-						})
-
-					} else {
-						ip, cidr, err := net.ParseCIDR(e.Range)
-						if err == nil {
-							if ip.To4() != nil {
-								r.Dst = append(r.Dst, *cidr)
-							} else {
-								r.Dst6 = append(r.Dst6, *cidr)
-							}
 
+					ip, cidr, err := net.ParseCIDR(e.Range)
+					if err == nil {
+						if ip.To4() != nil {
+							r.Dst = append(r.Dst, *cidr)
+						} else {
+							r.Dst6 = append(r.Dst6, *cidr)
 						}
+
 					}
 
 				}
@@ -1530,12 +1480,7 @@ func GetEgressRulesForNode(targetnode models.Node) (rules map[string]models.AclR
 			continue
 		}
 		if _, ok := egI.Nodes[targetnode.ID.String()]; ok {
-			if egI.IsInetGw {
-				targetNodeTags[models.TagID("0.0.0.0/0")] = struct{}{}
-				targetNodeTags[models.TagID("::/0")] = struct{}{}
-			} else {
-				targetNodeTags[models.TagID(egI.Range)] = struct{}{}
-			}
+			targetNodeTags[models.TagID(egI.Range)] = struct{}{}
 			targetNodeTags[models.TagID(egI.ID)] = struct{}{}
 		}
 	}
@@ -1597,6 +1542,10 @@ func GetEgressRulesForNode(targetnode models.Node) (rules map[string]models.AclR
 							if err == nil {
 								nodes = append(nodes, node)
 							}
+							extclient, err := logic.GetExtClient(dst, targetnode.Network)
+							if err == nil {
+								nodes = append(nodes, extclient.ConvertToStaticNode())
+							}
 						}
 
 						for _, node := range nodes {
@@ -1631,6 +1580,10 @@ func GetEgressRulesForNode(targetnode models.Node) (rules map[string]models.AclR
 							if err == nil {
 								nodes = append(nodes, node)
 							}
+							extclient, err := logic.GetExtClient(src, targetnode.Network)
+							if err == nil {
+								nodes = append(nodes, extclient.ConvertToStaticNode())
+							}
 						}
 						for _, node := range nodes {
 							if node.ID == targetnode.ID {
@@ -1661,6 +1614,10 @@ func GetEgressRulesForNode(targetnode models.Node) (rules map[string]models.AclR
 						if err == nil {
 							nodes = append(nodes, node)
 						}
+						extclient, err := logic.GetExtClient(srcID, targetnode.Network)
+						if err == nil {
+							nodes = append(nodes, extclient.ConvertToStaticNode())
+						}
 					}
 					for dstID := range dstTags {
 						if dstID == targetnode.ID.String() {
@@ -1670,6 +1627,10 @@ func GetEgressRulesForNode(targetnode models.Node) (rules map[string]models.AclR
 						if err == nil {
 							nodes = append(nodes, node)
 						}
+						extclient, err := logic.GetExtClient(dstID, targetnode.Network)
+						if err == nil {
+							nodes = append(nodes, extclient.ConvertToStaticNode())
+						}
 					}
 					for _, node := range nodes {
 						if node.ID == targetnode.ID {
@@ -1768,62 +1729,3 @@ func GetInetClientsFromAclPolicies(eID string) (inetClientIDs []string) {
 	}
 	return
 }
-
-func IsNodeUsingInternetGw(node *models.Node, acls []models.Acl) {
-	host, err := logic.GetHost(node.HostID.String())
-	if err != nil {
-		return
-	}
-	if host.IsDefault || node.IsFailOver {
-		return
-	}
-	nodeTags := maps.Clone(node.Tags)
-	if nodeTags == nil {
-		nodeTags = make(map[models.TagID]struct{})
-	}
-	nodeTags[models.TagID(node.ID.String())] = struct{}{}
-	var isUsing bool
-	for _, acl := range acls {
-		if !acl.Enabled {
-			continue
-		}
-		srcVal := logic.ConvAclTagToValueMap(acl.Src)
-		for _, dstI := range acl.Dst {
-			if dstI.ID == models.EgressID {
-				e := schema.Egress{ID: dstI.Value}
-				err := e.Get(db.WithContext(context.TODO()))
-				if err != nil || !e.Status {
-					continue
-				}
-
-				if e.IsInetGw {
-					if _, ok := srcVal[node.ID.String()]; ok {
-						for nodeID := range e.Nodes {
-							if nodeID == node.ID.String() {
-								continue
-							}
-							node.EgressDetails.InternetGwID = nodeID
-							isUsing = true
-							return
-						}
-					}
-					for tagID := range nodeTags {
-						if _, ok := srcVal[tagID.String()]; ok {
-							for nodeID := range e.Nodes {
-								if nodeID == node.ID.String() {
-									continue
-								}
-								node.EgressDetails.InternetGwID = nodeID
-								isUsing = true
-								return
-							}
-						}
-					}
-				}
-			}
-		}
-	}
-	if !isUsing {
-		node.EgressDetails.InternetGwID = ""
-	}
-}

+ 165 - 0
pro/logic/nodes.go

@@ -1,8 +1,19 @@
 package logic
 
 import (
+	"errors"
+	"fmt"
+	"net"
+
+	"github.com/google/uuid"
 	"github.com/gravitl/netmaker/logic"
 	"github.com/gravitl/netmaker/models"
+	"golang.org/x/exp/slog"
+)
+
+var (
+	IPv4Network = "0.0.0.0/0"
+	IPv6Network = "::/0"
 )
 
 // GetNetworkIngresses - gets the gateways of a network
@@ -223,3 +234,157 @@ func GetStaticNodeWithTag(tagID models.TagID) map[string]models.Node {
 	}
 	return nMap
 }
+
+func ValidateInetGwReq(inetNode models.Node, req models.InetNodeReq, update bool) error {
+	inetHost, err := logic.GetHost(inetNode.HostID.String())
+	if err != nil {
+		return err
+	}
+	if inetHost.FirewallInUse == models.FIREWALL_NONE {
+		return errors.New("iptables or nftables needs to be installed")
+	}
+	if inetNode.InternetGwID != "" {
+		return fmt.Errorf("node %s is using a internet gateway already", inetHost.Name)
+	}
+	if inetNode.IsRelayed {
+		return fmt.Errorf("node %s is being relayed", inetHost.Name)
+	}
+
+	for _, clientNodeID := range req.InetNodeClientIDs {
+		clientNode, err := logic.GetNodeByID(clientNodeID)
+		if err != nil {
+			return err
+		}
+		if clientNode.IsFailOver {
+			return errors.New("failover node cannot be set to use internet gateway")
+		}
+		clientHost, err := logic.GetHost(clientNode.HostID.String())
+		if err != nil {
+			return err
+		}
+		if clientHost.IsDefault {
+			return errors.New("default host cannot be set to use internet gateway")
+		}
+		if clientHost.OS != models.OS_Types.Linux && clientHost.OS != models.OS_Types.Windows {
+			return errors.New("can only attach linux or windows machine to a internet gateway")
+		}
+		if clientNode.IsInternetGateway {
+			return fmt.Errorf("node %s acting as internet gateway cannot use another internet gateway", clientHost.Name)
+		}
+		if update {
+			if clientNode.InternetGwID != "" && clientNode.InternetGwID != inetNode.ID.String() {
+				return fmt.Errorf("node %s is already using a internet gateway", clientHost.Name)
+			}
+		} else {
+			if clientNode.InternetGwID != "" {
+				return fmt.Errorf("node %s is already using a internet gateway", clientHost.Name)
+			}
+		}
+		if clientNode.FailedOverBy != uuid.Nil {
+			ResetFailedOverPeer(&clientNode)
+		}
+
+		if clientNode.IsRelayed && clientNode.RelayedBy != inetNode.ID.String() {
+			return fmt.Errorf("node %s is being relayed", clientHost.Name)
+		}
+
+		for _, nodeID := range clientHost.Nodes {
+			node, err := logic.GetNodeByID(nodeID)
+			if err != nil {
+				continue
+			}
+			if node.InternetGwID != "" && node.InternetGwID != inetNode.ID.String() {
+				return errors.New("nodes on same host cannot use different internet gateway")
+			}
+
+		}
+	}
+	return nil
+}
+
+// SetInternetGw - sets the node as internet gw based on flag bool
+func SetInternetGw(node *models.Node, req models.InetNodeReq) {
+	node.IsInternetGateway = true
+	node.InetNodeReq = req
+	for _, clientNodeID := range req.InetNodeClientIDs {
+		clientNode, err := logic.GetNodeByID(clientNodeID)
+		if err != nil {
+			continue
+		}
+		clientNode.InternetGwID = node.ID.String()
+		logic.UpsertNode(&clientNode)
+	}
+
+}
+
+func UnsetInternetGw(node *models.Node) {
+	nodes, err := logic.GetNetworkNodes(node.Network)
+	if err != nil {
+		slog.Error("failed to get network nodes", "network", node.Network, "error", err)
+		return
+	}
+	for _, clientNode := range nodes {
+		if node.ID.String() == clientNode.InternetGwID {
+			clientNode.InternetGwID = ""
+			logic.UpsertNode(&clientNode)
+		}
+
+	}
+	node.IsInternetGateway = false
+	node.InetNodeReq = models.InetNodeReq{}
+
+}
+
+func SetDefaultGwForRelayedUpdate(relayed, relay models.Node, peerUpdate models.HostPeerUpdate) models.HostPeerUpdate {
+	if relay.InternetGwID != "" {
+		relayedHost, err := logic.GetHost(relayed.HostID.String())
+		if err != nil {
+			return peerUpdate
+		}
+		peerUpdate.ChangeDefaultGw = true
+		peerUpdate.DefaultGwIp = relay.Address.IP
+		if peerUpdate.DefaultGwIp == nil || relayedHost.EndpointIP == nil {
+			peerUpdate.DefaultGwIp = relay.Address6.IP
+		}
+
+	}
+	return peerUpdate
+}
+
+func SetDefaultGw(node models.Node, peerUpdate models.HostPeerUpdate) models.HostPeerUpdate {
+	if node.InternetGwID != "" {
+
+		inetNode, err := logic.GetNodeByID(node.InternetGwID)
+		if err != nil {
+			return peerUpdate
+		}
+		host, err := logic.GetHost(node.HostID.String())
+		if err != nil {
+			return peerUpdate
+		}
+
+		peerUpdate.ChangeDefaultGw = true
+		peerUpdate.DefaultGwIp = inetNode.Address.IP
+		if peerUpdate.DefaultGwIp == nil || host.EndpointIP == nil {
+			peerUpdate.DefaultGwIp = inetNode.Address6.IP
+		}
+	}
+	return peerUpdate
+}
+
+// GetAllowedIpForInetNodeClient - get inet cidr for node using a inet gw
+func GetAllowedIpForInetNodeClient(node, peer *models.Node) []net.IPNet {
+	var allowedips = []net.IPNet{}
+
+	if peer.Address.IP != nil {
+		_, ipnet, _ := net.ParseCIDR(IPv4Network)
+		allowedips = append(allowedips, *ipnet)
+	}
+
+	if peer.Address6.IP != nil {
+		_, ipnet, _ := net.ParseCIDR(IPv6Network)
+		allowedips = append(allowedips, *ipnet)
+	}
+
+	return allowedips
+}

+ 5 - 11
schema/egress.go

@@ -19,11 +19,11 @@ type Egress struct {
 	Tags        datatypes.JSONMap `gorm:"tags" json:"tags"`
 	Range       string            `gorm:"range" json:"range"`
 	Nat         bool              `gorm:"nat" json:"nat"`
-	IsInetGw    bool              `gorm:"is_inet_gw" json:"is_internet_gateway"`
-	Status      bool              `gorm:"status" json:"status"`
-	CreatedBy   string            `gorm:"created_by" json:"created_by"`
-	CreatedAt   time.Time         `gorm:"created_at" json:"created_at"`
-	UpdatedAt   time.Time         `gorm:"updated_at" json:"updated_at"`
+	//IsInetGw    bool              `gorm:"is_inet_gw" json:"is_internet_gateway"`
+	Status    bool      `gorm:"status" json:"status"`
+	CreatedBy string    `gorm:"created_by" json:"created_by"`
+	CreatedAt time.Time `gorm:"created_at" json:"created_at"`
+	UpdatedAt time.Time `gorm:"updated_at" json:"updated_at"`
 }
 
 func (e *Egress) Table() string {
@@ -44,12 +44,6 @@ func (e *Egress) UpdateNatStatus(ctx context.Context) error {
 	}).Error
 }
 
-func (e *Egress) UpdateINetGwStatus(ctx context.Context) error {
-	return db.FromContext(ctx).Table(e.Table()).Where("id = ?", e.ID).Updates(map[string]any{
-		"is_inet_gw": e.IsInetGw,
-	}).Error
-}
-
 func (e *Egress) UpdateEgressStatus(ctx context.Context) error {
 	return db.FromContext(ctx).Table(e.Table()).Where("id = ?", e.ID).Updates(map[string]any{
 		"status": e.Status,