Browse Source

Merge pull request #1998 from gravitl/GRA-1054/egress_route_manager

Gra 1054/egress route manager
dcarns 2 years ago
parent
commit
35455ba7b3
9 changed files with 129 additions and 95 deletions
  1. 3 5
      cli/cmd/node/create_egress.go
  2. 0 1
      cli/cmd/node/flags.go
  3. 50 47
      controllers/node.go
  4. 0 11
      controllers/node_test.go
  5. 10 12
      logic/gateway.go
  6. 39 10
      logic/peers.go
  7. 18 7
      models/mqtt.go
  8. 9 1
      models/node.go
  9. 0 1
      models/structs.go

+ 3 - 5
cli/cmd/node/create_egress.go

@@ -15,10 +15,9 @@ var nodeCreateEgressCmd = &cobra.Command{
 	Long:  `Turn a Node into a Egress`,
 	Long:  `Turn a Node into a Egress`,
 	Run: func(cmd *cobra.Command, args []string) {
 	Run: func(cmd *cobra.Command, args []string) {
 		egress := &models.EgressGatewayRequest{
 		egress := &models.EgressGatewayRequest{
-			NetID:     args[0],
-			NodeID:    args[1],
-			Interface: networkInterface,
-			Ranges:    strings.Split(args[2], ","),
+			NetID:  args[0],
+			NodeID: args[1],
+			Ranges: strings.Split(args[2], ","),
 		}
 		}
 		if natEnabled {
 		if natEnabled {
 			egress.NatEnabled = "yes"
 			egress.NatEnabled = "yes"
@@ -28,7 +27,6 @@ var nodeCreateEgressCmd = &cobra.Command{
 }
 }
 
 
 func init() {
 func init() {
-	nodeCreateEgressCmd.Flags().StringVar(&networkInterface, "interface", "", "Network interface name (ex:- eth0)")
 	nodeCreateEgressCmd.Flags().BoolVar(&natEnabled, "nat", false, "Enable NAT for Egress Traffic ?")
 	nodeCreateEgressCmd.Flags().BoolVar(&natEnabled, "nat", false, "Enable NAT for Egress Traffic ?")
 	rootCmd.AddCommand(nodeCreateEgressCmd)
 	rootCmd.AddCommand(nodeCreateEgressCmd)
 }
 }

+ 0 - 1
cli/cmd/node/flags.go

@@ -1,7 +1,6 @@
 package node
 package node
 
 
 var (
 var (
-	networkInterface       string
 	natEnabled             bool
 	natEnabled             bool
 	failover               bool
 	failover               bool
 	networkName            string
 	networkName            string

+ 50 - 47
controllers/node.go

@@ -687,33 +687,34 @@ func createNode(w http.ResponseWriter, r *http.Request) {
 //			Responses:
 //			Responses:
 //				200: nodeResponse
 //				200: nodeResponse
 func createEgressGateway(w http.ResponseWriter, r *http.Request) {
 func createEgressGateway(w http.ResponseWriter, r *http.Request) {
-	logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("currently unimplemented"), "internal"))
-	// var gateway models.EgressGatewayRequest
-	// var params = mux.Vars(r)
-	// w.Header().Set("Content-Type", "application/json")
-	// err := json.NewDecoder(r.Body).Decode(&gateway)
-	//	if err != nil {
-	//		logger.Log(0, r.Header.Get("user"), "error decoding request body: ", err.Error())
-	//		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
-	//		return
-	//	}
-	// gateway.NetID = params["network"]
-	// gateway.NodeID = params["nodeid"]
-	// node, err := logic.CreateEgressGateway(gateway)
-	//	if err != nil {
-	//		logger.Log(0, r.Header.Get("user"),
-	//			fmt.Sprintf("failed to create egress gateway on node [%s] on network [%s]: %v",
-	//				gateway.NodeID, gateway.NetID, err))
-	//		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
-	//		return
-	//	}
-	//
-	// apiNode := node.ConvertToAPINode()
-	// logger.Log(1, r.Header.Get("user"), "created egress gateway on node", gateway.NodeID, "on network", gateway.NetID)
-	// w.WriteHeader(http.StatusOK)
-	// json.NewEncoder(w).Encode(apiNode)
-	//
-	// runUpdates(&node, true)
+	var gateway models.EgressGatewayRequest
+	var params = mux.Vars(r)
+	w.Header().Set("Content-Type", "application/json")
+	err := json.NewDecoder(r.Body).Decode(&gateway)
+	if err != nil {
+		logger.Log(0, r.Header.Get("user"), "error decoding request body: ", err.Error())
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
+		return
+	}
+	gateway.NetID = params["network"]
+	gateway.NodeID = params["nodeid"]
+	node, err := logic.CreateEgressGateway(gateway)
+	if err != nil {
+		logger.Log(0, r.Header.Get("user"),
+			fmt.Sprintf("failed to create egress gateway on node [%s] on network [%s]: %v",
+				gateway.NodeID, gateway.NetID, err))
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
+		return
+	}
+
+	apiNode := node.ConvertToAPINode()
+	logger.Log(1, r.Header.Get("user"), "created egress gateway on node", gateway.NodeID, "on network", gateway.NetID)
+	w.WriteHeader(http.StatusOK)
+	json.NewEncoder(w).Encode(apiNode)
+	go func() {
+		mq.PublishPeerUpdate()
+	}()
+	runUpdates(&node, true)
 }
 }
 
 
 // swagger:route DELETE /api/nodes/{network}/{nodeid}/deletegateway nodes deleteEgressGateway
 // swagger:route DELETE /api/nodes/{network}/{nodeid}/deletegateway nodes deleteEgressGateway
@@ -728,26 +729,28 @@ func createEgressGateway(w http.ResponseWriter, r *http.Request) {
 //			Responses:
 //			Responses:
 //				200: nodeResponse
 //				200: nodeResponse
 func deleteEgressGateway(w http.ResponseWriter, r *http.Request) {
 func deleteEgressGateway(w http.ResponseWriter, r *http.Request) {
-	logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("currently unimplemented"), "internal"))
-	//w.Header().Set("Content-Type", "application/json")
-	// var params = mux.Vars(r)
-	// nodeid := params["nodeid"]
-	// netid := params["network"]
-	// node, err := logic.DeleteEgressGateway(netid, nodeid)
-	//	if err != nil {
-	//		logger.Log(0, r.Header.Get("user"),
-	//			fmt.Sprintf("failed to delete egress gateway on node [%s] on network [%s]: %v",
-	//				nodeid, netid, err))
-	//		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
-	//		return
-	//	}
-	//
-	// apiNode := node.ConvertToAPINode()
-	// logger.Log(1, r.Header.Get("user"), "deleted egress gateway on node", nodeid, "on network", netid)
-	// w.WriteHeader(http.StatusOK)
-	// json.NewEncoder(w).Encode(apiNode)
-	//
-	// runUpdates(&node, true)
+
+	w.Header().Set("Content-Type", "application/json")
+	var params = mux.Vars(r)
+	nodeid := params["nodeid"]
+	netid := params["network"]
+	node, err := logic.DeleteEgressGateway(netid, nodeid)
+	if err != nil {
+		logger.Log(0, r.Header.Get("user"),
+			fmt.Sprintf("failed to delete egress gateway on node [%s] on network [%s]: %v",
+				nodeid, netid, err))
+		logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
+		return
+	}
+
+	apiNode := node.ConvertToAPINode()
+	logger.Log(1, r.Header.Get("user"), "deleted egress gateway on node", nodeid, "on network", netid)
+	w.WriteHeader(http.StatusOK)
+	json.NewEncoder(w).Encode(apiNode)
+	go func() {
+		mq.PublishPeerUpdate()
+	}()
+	runUpdates(&node, true)
 }
 }
 
 
 // == INGRESS ==
 // == INGRESS ==

+ 0 - 11
controllers/node_test.go

@@ -19,7 +19,6 @@ var linuxHost models.Host
 
 
 func TestCreateEgressGateway(t *testing.T) {
 func TestCreateEgressGateway(t *testing.T) {
 	var gateway models.EgressGatewayRequest
 	var gateway models.EgressGatewayRequest
-	gateway.Interface = "eth0"
 	gateway.Ranges = []string{"10.100.100.0/24"}
 	gateway.Ranges = []string{"10.100.100.0/24"}
 	gateway.NetID = "skynet"
 	gateway.NetID = "skynet"
 	database.InitializeDatabase()
 	database.InitializeDatabase()
@@ -63,7 +62,6 @@ func TestCreateEgressGateway(t *testing.T) {
 	})
 	})
 	t.Run("Success", func(t *testing.T) {
 	t.Run("Success", func(t *testing.T) {
 		var gateway models.EgressGatewayRequest
 		var gateway models.EgressGatewayRequest
-		gateway.Interface = "eth0"
 		gateway.Ranges = []string{"10.100.100.0/24"}
 		gateway.Ranges = []string{"10.100.100.0/24"}
 		gateway.NetID = "skynet"
 		gateway.NetID = "skynet"
 		deleteAllNodes()
 		deleteAllNodes()
@@ -84,7 +82,6 @@ func TestDeleteEgressGateway(t *testing.T) {
 	deleteAllNetworks()
 	deleteAllNetworks()
 	createNet()
 	createNet()
 	testnode := createTestNode()
 	testnode := createTestNode()
-	gateway.Interface = "eth0"
 	gateway.Ranges = []string{"10.100.100.0/24"}
 	gateway.Ranges = []string{"10.100.100.0/24"}
 	gateway.NetID = "skynet"
 	gateway.NetID = "skynet"
 	gateway.NodeID = testnode.ID.String()
 	gateway.NodeID = testnode.ID.String()
@@ -138,19 +135,11 @@ func TestGetNetworkNodes(t *testing.T) {
 func TestValidateEgressGateway(t *testing.T) {
 func TestValidateEgressGateway(t *testing.T) {
 	var gateway models.EgressGatewayRequest
 	var gateway models.EgressGatewayRequest
 	t.Run("EmptyRange", func(t *testing.T) {
 	t.Run("EmptyRange", func(t *testing.T) {
-		gateway.Interface = "eth0"
 		gateway.Ranges = []string{}
 		gateway.Ranges = []string{}
 		err := logic.ValidateEgressGateway(gateway)
 		err := logic.ValidateEgressGateway(gateway)
 		assert.EqualError(t, err, "IP Ranges Cannot Be Empty")
 		assert.EqualError(t, err, "IP Ranges Cannot Be Empty")
 	})
 	})
-	t.Run("EmptyInterface", func(t *testing.T) {
-		gateway.Interface = ""
-		err := logic.ValidateEgressGateway(gateway)
-		assert.NotNil(t, err)
-		assert.Equal(t, "interface cannot be empty", err.Error())
-	})
 	t.Run("Success", func(t *testing.T) {
 	t.Run("Success", func(t *testing.T) {
-		gateway.Interface = "eth0"
 		gateway.Ranges = []string{"10.100.100.0/24"}
 		gateway.Ranges = []string{"10.100.100.0/24"}
 		err := logic.ValidateEgressGateway(gateway)
 		err := logic.ValidateEgressGateway(gateway)
 		assert.Nil(t, err)
 		assert.Nil(t, err)

+ 10 - 12
logic/gateway.go

@@ -22,20 +22,22 @@ func CreateEgressGateway(gateway models.EgressGatewayRequest) (models.Node, erro
 	if err != nil {
 	if err != nil {
 		return models.Node{}, err
 		return models.Node{}, err
 	}
 	}
-	for i, cidr := range gateway.Ranges {
-		normalized, err := NormalizeCIDR(cidr)
+	if host.OS != "linux" { // support for other OS to be added
+		return models.Node{}, errors.New(host.OS + " is unsupported for egress gateways")
+	}
+	for i := len(gateway.Ranges) - 1; i >= 0; i-- {
+		if gateway.Ranges[i] == "0.0.0.0/0" || gateway.Ranges[i] == "::/0" {
+			logger.Log(0, "currently internet gateways are not supported", gateway.Ranges[i])
+			gateway.Ranges = append(gateway.Ranges[:i], gateway.Ranges[i+1:]...)
+			continue
+		}
+		normalized, err := NormalizeCIDR(gateway.Ranges[i])
 		if err != nil {
 		if err != nil {
 			return models.Node{}, err
 			return models.Node{}, err
 		}
 		}
 		gateway.Ranges[i] = normalized
 		gateway.Ranges[i] = normalized
 
 
 	}
 	}
-	if host.OS != "linux" && host.OS != "freebsd" { // add in darwin later
-		return models.Node{}, errors.New(host.OS + " is unsupported for egress gateways")
-	}
-	if host.OS == "linux" && host.FirewallInUse == models.FIREWALL_NONE {
-		return models.Node{}, errors.New("firewall is not supported for egress gateways")
-	}
 	if gateway.NatEnabled == "" {
 	if gateway.NatEnabled == "" {
 		gateway.NatEnabled = "yes"
 		gateway.NatEnabled = "yes"
 	}
 	}
@@ -66,10 +68,6 @@ func ValidateEgressGateway(gateway models.EgressGatewayRequest) error {
 	if empty {
 	if empty {
 		err = errors.New("IP Ranges Cannot Be Empty")
 		err = errors.New("IP Ranges Cannot Be Empty")
 	}
 	}
-	empty = gateway.Interface == ""
-	if empty {
-		err = errors.New("interface cannot be empty")
-	}
 	return err
 	return err
 }
 }
 
 

+ 39 - 10
logic/peers.go

@@ -308,6 +308,7 @@ func GetPeerUpdateForHost(host *models.Host) (models.HostPeerUpdate, error) {
 		IngressInfo: models.IngressInfo{
 		IngressInfo: models.IngressInfo{
 			ExtPeers: make(map[string]models.ExtClientInfo),
 			ExtPeers: make(map[string]models.ExtClientInfo),
 		},
 		},
+		EgressInfo: make(map[string]models.EgressInfo),
 	}
 	}
 	logger.Log(1, "peer update for host ", host.ID.String())
 	logger.Log(1, "peer update for host ", host.ID.String())
 	peerIndexMap := make(map[string]int)
 	peerIndexMap := make(map[string]int)
@@ -328,9 +329,9 @@ func GetPeerUpdateForHost(host *models.Host) (models.HostPeerUpdate, error) {
 			log.Println("no network nodes")
 			log.Println("no network nodes")
 			return models.HostPeerUpdate{}, err
 			return models.HostPeerUpdate{}, err
 		}
 		}
-		var extClientPeerMap map[string]models.PeerExtInfo
-		if node.IsIngressGateway {
-			extClientPeerMap = make(map[string]models.PeerExtInfo)
+		var nodePeerMap map[string]models.PeerRouteInfo
+		if node.IsIngressGateway || node.IsEgressGateway {
+			nodePeerMap = make(map[string]models.PeerRouteInfo)
 		}
 		}
 		for _, peer := range currentPeers {
 		for _, peer := range currentPeers {
 			if peer.ID == node.ID {
 			if peer.ID == node.ID {
@@ -393,9 +394,9 @@ func GetPeerUpdateForHost(host *models.Host) (models.HostPeerUpdate, error) {
 				allowedips = append(allowedips, getEgressIPs(&node, &peer)...)
 				allowedips = append(allowedips, getEgressIPs(&node, &peer)...)
 			}
 			}
 			peerConfig.AllowedIPs = allowedips
 			peerConfig.AllowedIPs = allowedips
-			if node.IsIngressGateway {
+			if node.IsIngressGateway || node.IsEgressGateway {
 
 
-				extClientPeerMap[peerHost.PublicKey.String()] = models.PeerExtInfo{
+				nodePeerMap[peerHost.PublicKey.String()] = models.PeerRouteInfo{
 					PeerAddr: net.IPNet{
 					PeerAddr: net.IPNet{
 						IP:   net.ParseIP(peer.PrimaryAddress()),
 						IP:   net.ParseIP(peer.PrimaryAddress()),
 						Mask: getCIDRMaskFromAddr(peer.PrimaryAddress()),
 						Mask: getCIDRMaskFromAddr(peer.PrimaryAddress()),
@@ -428,8 +429,10 @@ func GetPeerUpdateForHost(host *models.Host) (models.HostPeerUpdate, error) {
 			}
 			}
 
 
 		}
 		}
+		var extPeers []wgtypes.PeerConfig
+		var extPeerIDAndAddrs []models.IDandAddr
 		if node.IsIngressGateway {
 		if node.IsIngressGateway {
-			extPeers, extPeerIDAndAddrs, err := getExtPeers(&node)
+			extPeers, extPeerIDAndAddrs, err = getExtPeers(&node)
 			if err == nil {
 			if err == nil {
 				hostPeerUpdate.Peers = append(hostPeerUpdate.Peers, extPeers...)
 				hostPeerUpdate.Peers = append(hostPeerUpdate.Peers, extPeers...)
 				for _, extPeerIdAndAddr := range extPeerIDAndAddrs {
 				for _, extPeerIdAndAddr := range extPeerIDAndAddrs {
@@ -446,12 +449,13 @@ func GetPeerUpdateForHost(host *models.Host) (models.HostPeerUpdate, error) {
 							IP:   net.ParseIP(node.PrimaryAddress()),
 							IP:   net.ParseIP(node.PrimaryAddress()),
 							Mask: getCIDRMaskFromAddr(node.PrimaryAddress()),
 							Mask: getCIDRMaskFromAddr(node.PrimaryAddress()),
 						},
 						},
+						Network: node.PrimaryNetworkRange(),
 						ExtPeerAddr: net.IPNet{
 						ExtPeerAddr: net.IPNet{
 							IP:   net.ParseIP(extPeerIdAndAddr.Address),
 							IP:   net.ParseIP(extPeerIdAndAddr.Address),
 							Mask: getCIDRMaskFromAddr(extPeerIdAndAddr.Address),
 							Mask: getCIDRMaskFromAddr(extPeerIdAndAddr.Address),
 						},
 						},
 						ExtPeerKey: extPeerIdAndAddr.ID,
 						ExtPeerKey: extPeerIdAndAddr.ID,
-						Peers:      extClientPeerMap,
+						Peers:      nodePeerMap,
 					}
 					}
 				}
 				}
 
 
@@ -459,6 +463,31 @@ func GetPeerUpdateForHost(host *models.Host) (models.HostPeerUpdate, error) {
 				logger.Log(1, "error retrieving external clients:", err.Error())
 				logger.Log(1, "error retrieving external clients:", err.Error())
 			}
 			}
 		}
 		}
+		if node.IsEgressGateway {
+			if node.IsIngressGateway {
+				for _, extPeerIdAndAddr := range extPeerIDAndAddrs {
+					nodePeerMap[extPeerIdAndAddr.ID] = models.PeerRouteInfo{
+						PeerAddr: net.IPNet{
+							IP:   net.ParseIP(extPeerIdAndAddr.Address),
+							Mask: getCIDRMaskFromAddr(extPeerIdAndAddr.Address),
+						},
+						PeerKey: extPeerIdAndAddr.ID,
+						Allow:   true,
+					}
+				}
+
+			}
+			hostPeerUpdate.EgressInfo[node.ID.String()] = models.EgressInfo{
+				EgressID: node.ID.String(),
+				Network:  node.PrimaryNetworkRange(),
+				EgressGwAddr: net.IPNet{
+					IP:   net.ParseIP(node.PrimaryAddress()),
+					Mask: getCIDRMaskFromAddr(node.PrimaryAddress()),
+				},
+				GwPeers:     nodePeerMap,
+				EgressGWCfg: node.EgressGatewayRequest,
+			}
+		}
 	}
 	}
 
 
 	return hostPeerUpdate, nil
 	return hostPeerUpdate, nil
@@ -1108,13 +1137,13 @@ func getEgressIPs(node, peer *models.Node) []net.IPNet {
 			logger.Log(1, "could not parse gateway IP range. Not adding ", iprange)
 			logger.Log(1, "could not parse gateway IP range. Not adding ", iprange)
 			continue // if can't parse CIDR
 			continue // if can't parse CIDR
 		}
 		}
-		nodeEndpointArr := strings.Split(peerHost.EndpointIP.String(), ":")      // getting the public ip of node
-		if ipnet.Contains(net.ParseIP(nodeEndpointArr[0])) && !internetGateway { // ensuring egress gateway range does not contain endpoint of node
+		// getting the public ip of node
+		if ipnet.Contains(peerHost.EndpointIP) && !internetGateway { // ensuring egress gateway range does not contain endpoint of node
 			logger.Log(2, "egress IP range of ", iprange, " overlaps with ", host.EndpointIP.String(), ", omitting")
 			logger.Log(2, "egress IP range of ", iprange, " overlaps with ", host.EndpointIP.String(), ", omitting")
 			continue // skip adding egress range if overlaps with node's ip
 			continue // skip adding egress range if overlaps with node's ip
 		}
 		}
 		// TODO: Could put in a lot of great logic to avoid conflicts / bad routes
 		// TODO: Could put in a lot of great logic to avoid conflicts / bad routes
-		if ipnet.Contains(net.ParseIP(node.LocalAddress.String())) && !internetGateway { // ensuring egress gateway range does not contain public ip of node
+		if ipnet.Contains(node.LocalAddress.IP) && !internetGateway { // ensuring egress gateway range does not contain public ip of node
 			logger.Log(2, "egress IP range of ", iprange, " overlaps with ", node.LocalAddress.String(), ", omitting")
 			logger.Log(2, "egress IP range of ", iprange, " overlaps with ", node.LocalAddress.String(), ", omitting")
 			continue // skip adding egress range if overlaps with node's local ip
 			continue // skip adding egress range if overlaps with node's local ip
 		}
 		}

+ 18 - 7
models/mqtt.go

@@ -27,6 +27,7 @@ type HostPeerUpdate struct {
 	Peers         []wgtypes.PeerConfig   `json:"peers" bson:"peers" yaml:"peers"`
 	Peers         []wgtypes.PeerConfig   `json:"peers" bson:"peers" yaml:"peers"`
 	PeerIDs       HostPeerMap            `json:"peerids" bson:"peerids" yaml:"peerids"`
 	PeerIDs       HostPeerMap            `json:"peerids" bson:"peerids" yaml:"peerids"`
 	ProxyUpdate   ProxyManagerPayload    `json:"proxy_update" bson:"proxy_update" yaml:"proxy_update"`
 	ProxyUpdate   ProxyManagerPayload    `json:"proxy_update" bson:"proxy_update" yaml:"proxy_update"`
+	EgressInfo    map[string]EgressInfo  `json:"egress_info" bson:"egress_info" yaml:"egress_info"` // map key is node ID
 	IngressInfo   IngressInfo            `json:"ingress_info" bson:"ext_peers" yaml:"ext_peers"`
 	IngressInfo   IngressInfo            `json:"ingress_info" bson:"ext_peers" yaml:"ext_peers"`
 }
 }
 
 
@@ -35,8 +36,17 @@ type IngressInfo struct {
 	ExtPeers map[string]ExtClientInfo `json:"ext_peers" yaml:"ext_peers"`
 	ExtPeers map[string]ExtClientInfo `json:"ext_peers" yaml:"ext_peers"`
 }
 }
 
 
-// PeerExtInfo - struct for peer info for an ext. client
-type PeerExtInfo struct {
+// EgressInfo - struct for egress info
+type EgressInfo struct {
+	EgressID     string                   `json:"egress_id" yaml:"egress_id"`
+	Network      net.IPNet                `json:"network" yaml:"network"`
+	EgressGwAddr net.IPNet                `json:"egress_gw_addr" yaml:"egress_gw_addr"`
+	GwPeers      map[string]PeerRouteInfo `json:"gateway_peers" yaml:"gateway_peers"`
+	EgressGWCfg  EgressGatewayRequest     `json:"egress_gateway_cfg" yaml:"egress_gateway_cfg"`
+}
+
+// PeerRouteInfo - struct for peer info for an ext. client
+type PeerRouteInfo struct {
 	PeerAddr net.IPNet `json:"peer_addr" yaml:"peer_addr"`
 	PeerAddr net.IPNet `json:"peer_addr" yaml:"peer_addr"`
 	PeerKey  string    `json:"peer_key" yaml:"peer_key"`
 	PeerKey  string    `json:"peer_key" yaml:"peer_key"`
 	Allow    bool      `json:"allow" yaml:"allow"`
 	Allow    bool      `json:"allow" yaml:"allow"`
@@ -44,11 +54,12 @@ type PeerExtInfo struct {
 
 
 // ExtClientInfo - struct for ext. client and it's peers
 // ExtClientInfo - struct for ext. client and it's peers
 type ExtClientInfo struct {
 type ExtClientInfo struct {
-	IngGwAddr   net.IPNet              `json:"ingress_gw_addr" yaml:"ingress_gw_addr"`
-	Masquerade  bool                   `json:"masquerade" yaml:"masquerade"`
-	ExtPeerAddr net.IPNet              `json:"ext_peer_addr" yaml:"ext_peer_addr"`
-	ExtPeerKey  string                 `json:"ext_peer_key" yaml:"ext_peer_key"`
-	Peers       map[string]PeerExtInfo `json:"peers" yaml:"peers"`
+	IngGwAddr   net.IPNet                `json:"ingress_gw_addr" yaml:"ingress_gw_addr"`
+	Network     net.IPNet                `json:"network" yaml:"network"`
+	Masquerade  bool                     `json:"masquerade" yaml:"masquerade"`
+	ExtPeerAddr net.IPNet                `json:"ext_peer_addr" yaml:"ext_peer_addr"`
+	ExtPeerKey  string                   `json:"ext_peer_key" yaml:"ext_peer_key"`
+	Peers       map[string]PeerRouteInfo `json:"peers" yaml:"peers"`
 }
 }
 
 
 // NetworkInfo - struct for network info
 // NetworkInfo - struct for network info

+ 9 - 1
models/node.go

@@ -70,6 +70,7 @@ type CommonNode struct {
 	LocalAddress        net.IPNet     `json:"localaddress" yaml:"localaddress"`
 	LocalAddress        net.IPNet     `json:"localaddress" yaml:"localaddress"`
 	IsLocal             bool          `json:"islocal" yaml:"islocal"`
 	IsLocal             bool          `json:"islocal" yaml:"islocal"`
 	IsEgressGateway     bool          `json:"isegressgateway" yaml:"isegressgateway"`
 	IsEgressGateway     bool          `json:"isegressgateway" yaml:"isegressgateway"`
+	EgressGatewayRanges []string      `json:"egressgatewayranges" bson:"egressgatewayranges" yaml:"egressgatewayranges"`
 	IsIngressGateway    bool          `json:"isingressgateway" yaml:"isingressgateway"`
 	IsIngressGateway    bool          `json:"isingressgateway" yaml:"isingressgateway"`
 	DNSOn               bool          `json:"dnson" yaml:"dnson"`
 	DNSOn               bool          `json:"dnson" yaml:"dnson"`
 	PersistentKeepalive time.Duration `json:"persistentkeepalive" yaml:"persistentkeepalive"`
 	PersistentKeepalive time.Duration `json:"persistentkeepalive" yaml:"persistentkeepalive"`
@@ -83,7 +84,6 @@ type Node struct {
 	LastCheckIn             time.Time            `json:"lastcheckin" bson:"lastcheckin" yaml:"lastcheckin"`
 	LastCheckIn             time.Time            `json:"lastcheckin" bson:"lastcheckin" yaml:"lastcheckin"`
 	LastPeerUpdate          time.Time            `json:"lastpeerupdate" bson:"lastpeerupdate" yaml:"lastpeerupdate"`
 	LastPeerUpdate          time.Time            `json:"lastpeerupdate" bson:"lastpeerupdate" yaml:"lastpeerupdate"`
 	ExpirationDateTime      time.Time            `json:"expdatetime" bson:"expdatetime" yaml:"expdatetime"`
 	ExpirationDateTime      time.Time            `json:"expdatetime" bson:"expdatetime" yaml:"expdatetime"`
-	EgressGatewayRanges     []string             `json:"egressgatewayranges" bson:"egressgatewayranges" yaml:"egressgatewayranges"`
 	EgressGatewayNatEnabled bool                 `json:"egressgatewaynatenabled" bson:"egressgatewaynatenabled" yaml:"egressgatewaynatenabled"`
 	EgressGatewayNatEnabled bool                 `json:"egressgatewaynatenabled" bson:"egressgatewaynatenabled" yaml:"egressgatewaynatenabled"`
 	EgressGatewayRequest    EgressGatewayRequest `json:"egressgatewayrequest" bson:"egressgatewayrequest" yaml:"egressgatewayrequest"`
 	EgressGatewayRequest    EgressGatewayRequest `json:"egressgatewayrequest" bson:"egressgatewayrequest" yaml:"egressgatewayrequest"`
 	IngressGatewayRange     string               `json:"ingressgatewayrange" bson:"ingressgatewayrange" yaml:"ingressgatewayrange"`
 	IngressGatewayRange     string               `json:"ingressgatewayrange" bson:"ingressgatewayrange" yaml:"ingressgatewayrange"`
@@ -191,6 +191,14 @@ func (node *Node) PrimaryAddress() string {
 	return node.Address6.IP.String()
 	return node.Address6.IP.String()
 }
 }
 
 
+// Node.PrimaryNetworkRange - returns node's parent network, returns ipv4 address if present, else return ipv6
+func (node *Node) PrimaryNetworkRange() net.IPNet {
+	if node.NetworkRange.IP != nil {
+		return node.NetworkRange
+	}
+	return node.NetworkRange6
+}
+
 // Node.SetDefaultConnected
 // Node.SetDefaultConnected
 func (node *Node) SetDefaultConnected() {
 func (node *Node) SetDefaultConnected() {
 	node.Connected = true
 	node.Connected = true

+ 0 - 1
models/structs.go

@@ -160,7 +160,6 @@ type EgressGatewayRequest struct {
 	NetID      string   `json:"netid" bson:"netid"`
 	NetID      string   `json:"netid" bson:"netid"`
 	NatEnabled string   `json:"natenabled" bson:"natenabled"`
 	NatEnabled string   `json:"natenabled" bson:"natenabled"`
 	Ranges     []string `json:"ranges" bson:"ranges"`
 	Ranges     []string `json:"ranges" bson:"ranges"`
-	Interface  string   `json:"interface" bson:"interface"`
 }
 }
 
 
 // RelayRequest - relay request struct
 // RelayRequest - relay request struct