Browse Source

route changes + primary addr on node

0xdcarns 3 years ago
parent
commit
dc12b1e418

+ 25 - 25
controllers/dns_test.go

@@ -21,14 +21,14 @@ func TestGetAllDNS(t *testing.T) {
 		assert.Equal(t, []models.DNSEntry(nil), entries)
 		assert.Equal(t, []models.DNSEntry(nil), entries)
 	})
 	})
 	t.Run("OneEntry", func(t *testing.T) {
 	t.Run("OneEntry", func(t *testing.T) {
-		entry := models.DNSEntry{"10.0.0.3", "newhost", "skynet"}
+		entry := models.DNSEntry{"10.0.0.3", "", "newhost", "skynet"}
 		CreateDNS(entry)
 		CreateDNS(entry)
 		entries, err := logic.GetAllDNS()
 		entries, err := logic.GetAllDNS()
 		assert.Nil(t, err)
 		assert.Nil(t, err)
 		assert.Equal(t, 1, len(entries))
 		assert.Equal(t, 1, len(entries))
 	})
 	})
 	t.Run("MultipleEntry", func(t *testing.T) {
 	t.Run("MultipleEntry", func(t *testing.T) {
-		entry := models.DNSEntry{"10.0.0.7", "anotherhost", "skynet"}
+		entry := models.DNSEntry{"10.0.0.7", "", "anotherhost", "skynet"}
 		CreateDNS(entry)
 		CreateDNS(entry)
 		entries, err := logic.GetAllDNS()
 		entries, err := logic.GetAllDNS()
 		assert.Nil(t, err)
 		assert.Nil(t, err)
@@ -83,14 +83,14 @@ func TestGetCustomDNS(t *testing.T) {
 		assert.Equal(t, 0, len(dns))
 		assert.Equal(t, 0, len(dns))
 	})
 	})
 	t.Run("EntryExist", func(t *testing.T) {
 	t.Run("EntryExist", func(t *testing.T) {
-		entry := models.DNSEntry{"10.0.0.3", "newhost", "skynet"}
+		entry := models.DNSEntry{"10.0.0.3", "", "newhost", "skynet"}
 		CreateDNS(entry)
 		CreateDNS(entry)
 		dns, err := logic.GetCustomDNS("skynet")
 		dns, err := logic.GetCustomDNS("skynet")
 		assert.Nil(t, err)
 		assert.Nil(t, err)
 		assert.Equal(t, 1, len(dns))
 		assert.Equal(t, 1, len(dns))
 	})
 	})
 	t.Run("MultipleEntries", func(t *testing.T) {
 	t.Run("MultipleEntries", func(t *testing.T) {
-		entry := models.DNSEntry{"10.0.0.4", "host4", "skynet"}
+		entry := models.DNSEntry{"10.0.0.4", "", "host4", "skynet"}
 		CreateDNS(entry)
 		CreateDNS(entry)
 		dns, err := logic.GetCustomDNS("skynet")
 		dns, err := logic.GetCustomDNS("skynet")
 		assert.Nil(t, err)
 		assert.Nil(t, err)
@@ -109,7 +109,7 @@ func TestGetDNSEntryNum(t *testing.T) {
 		assert.Equal(t, 0, num)
 		assert.Equal(t, 0, num)
 	})
 	})
 	t.Run("NodeExists", func(t *testing.T) {
 	t.Run("NodeExists", func(t *testing.T) {
-		entry := models.DNSEntry{"10.0.0.2", "newhost", "skynet"}
+		entry := models.DNSEntry{"10.0.0.2", "", "newhost", "skynet"}
 		_, err := CreateDNS(entry)
 		_, err := CreateDNS(entry)
 		assert.Nil(t, err)
 		assert.Nil(t, err)
 		num, err := logic.GetDNSEntryNum("newhost", "skynet")
 		num, err := logic.GetDNSEntryNum("newhost", "skynet")
@@ -128,7 +128,7 @@ func TestGetDNS(t *testing.T) {
 		assert.Nil(t, dns)
 		assert.Nil(t, dns)
 	})
 	})
 	t.Run("CustomDNSExists", func(t *testing.T) {
 	t.Run("CustomDNSExists", func(t *testing.T) {
-		entry := models.DNSEntry{"10.0.0.2", "newhost", "skynet"}
+		entry := models.DNSEntry{"10.0.0.2", "", "newhost", "skynet"}
 		_, err := CreateDNS(entry)
 		_, err := CreateDNS(entry)
 		assert.Nil(t, err)
 		assert.Nil(t, err)
 		dns, err := logic.GetDNS("skynet")
 		dns, err := logic.GetDNS("skynet")
@@ -148,7 +148,7 @@ func TestGetDNS(t *testing.T) {
 		assert.Equal(t, 1, len(dns))
 		assert.Equal(t, 1, len(dns))
 	})
 	})
 	t.Run("NodeAndCustomDNS", func(t *testing.T) {
 	t.Run("NodeAndCustomDNS", func(t *testing.T) {
-		entry := models.DNSEntry{"10.0.0.2", "newhost", "skynet"}
+		entry := models.DNSEntry{"10.0.0.2", "", "newhost", "skynet"}
 		_, err := CreateDNS(entry)
 		_, err := CreateDNS(entry)
 		dns, err := logic.GetDNS("skynet")
 		dns, err := logic.GetDNS("skynet")
 		t.Log(dns)
 		t.Log(dns)
@@ -165,7 +165,7 @@ func TestCreateDNS(t *testing.T) {
 	deleteAllDNS(t)
 	deleteAllDNS(t)
 	deleteAllNetworks()
 	deleteAllNetworks()
 	createNet()
 	createNet()
-	entry := models.DNSEntry{"10.0.0.2", "newhost", "skynet"}
+	entry := models.DNSEntry{"10.0.0.2", "", "newhost", "skynet"}
 	dns, err := CreateDNS(entry)
 	dns, err := CreateDNS(entry)
 	assert.Nil(t, err)
 	assert.Nil(t, err)
 	assert.Equal(t, "newhost", dns.Name)
 	assert.Equal(t, "newhost", dns.Name)
@@ -204,7 +204,7 @@ func TestSetDNS(t *testing.T) {
 		assert.Contains(t, string(content), "testnode.skynet")
 		assert.Contains(t, string(content), "testnode.skynet")
 	})
 	})
 	t.Run("EntryExists", func(t *testing.T) {
 	t.Run("EntryExists", func(t *testing.T) {
-		entry := models.DNSEntry{"10.0.0.3", "newhost", "skynet"}
+		entry := models.DNSEntry{"10.0.0.3", "", "newhost", "skynet"}
 		CreateDNS(entry)
 		CreateDNS(entry)
 		err := logic.SetDNS()
 		err := logic.SetDNS()
 		assert.Nil(t, err)
 		assert.Nil(t, err)
@@ -224,7 +224,7 @@ func TestGetDNSEntry(t *testing.T) {
 	deleteAllNetworks()
 	deleteAllNetworks()
 	createNet()
 	createNet()
 	createTestNode()
 	createTestNode()
-	entry := models.DNSEntry{"10.0.0.2", "newhost", "skynet"}
+	entry := models.DNSEntry{"10.0.0.2", "", "newhost", "skynet"}
 	CreateDNS(entry)
 	CreateDNS(entry)
 	t.Run("wrong net", func(t *testing.T) {
 	t.Run("wrong net", func(t *testing.T) {
 		entry, err := GetDNSEntry("newhost", "w286 Toronto Street South, Uxbridge, ONirecat")
 		entry, err := GetDNSEntry("newhost", "w286 Toronto Street South, Uxbridge, ONirecat")
@@ -280,7 +280,7 @@ func TestDeleteDNS(t *testing.T) {
 	deleteAllDNS(t)
 	deleteAllDNS(t)
 	deleteAllNetworks()
 	deleteAllNetworks()
 	createNet()
 	createNet()
-	entry := models.DNSEntry{"10.0.0.2", "newhost", "skynet"}
+	entry := models.DNSEntry{"10.0.0.2", "", "newhost", "skynet"}
 	CreateDNS(entry)
 	CreateDNS(entry)
 	t.Run("EntryExists", func(t *testing.T) {
 	t.Run("EntryExists", func(t *testing.T) {
 		err := logic.DeleteDNS("newhost", "skynet")
 		err := logic.DeleteDNS("newhost", "skynet")
@@ -302,36 +302,36 @@ func TestValidateDNSUpdate(t *testing.T) {
 	deleteAllDNS(t)
 	deleteAllDNS(t)
 	deleteAllNetworks()
 	deleteAllNetworks()
 	createNet()
 	createNet()
-	entry := models.DNSEntry{"10.0.0.2", "myhost", "skynet"}
+	entry := models.DNSEntry{"10.0.0.2", "", "myhost", "skynet"}
 	t.Run("BadNetwork", func(t *testing.T) {
 	t.Run("BadNetwork", func(t *testing.T) {
-		change := models.DNSEntry{"10.0.0.2", "myhost", "badnet"}
+		change := models.DNSEntry{"10.0.0.2", "", "myhost", "badnet"}
 		err := logic.ValidateDNSUpdate(change, entry)
 		err := logic.ValidateDNSUpdate(change, entry)
 		assert.NotNil(t, err)
 		assert.NotNil(t, err)
 		assert.Contains(t, err.Error(), "Field validation for 'Network' failed on the 'network_exists' tag")
 		assert.Contains(t, err.Error(), "Field validation for 'Network' failed on the 'network_exists' tag")
 	})
 	})
 	t.Run("EmptyNetwork", func(t *testing.T) {
 	t.Run("EmptyNetwork", func(t *testing.T) {
 		//this can't actually happen as change.Network is populated if is blank
 		//this can't actually happen as change.Network is populated if is blank
-		change := models.DNSEntry{"10.0.0.2", "myhost", ""}
+		change := models.DNSEntry{"10.0.0.2", "", "myhost", ""}
 		err := logic.ValidateDNSUpdate(change, entry)
 		err := logic.ValidateDNSUpdate(change, entry)
 		assert.NotNil(t, err)
 		assert.NotNil(t, err)
 		assert.Contains(t, err.Error(), "Field validation for 'Network' failed on the 'network_exists' tag")
 		assert.Contains(t, err.Error(), "Field validation for 'Network' failed on the 'network_exists' tag")
 	})
 	})
 	t.Run("EmptyAddress", func(t *testing.T) {
 	t.Run("EmptyAddress", func(t *testing.T) {
 		//this can't actually happen as change.Address is populated if is blank
 		//this can't actually happen as change.Address is populated if is blank
-		change := models.DNSEntry{"", "myhost", "skynet"}
+		change := models.DNSEntry{"", "", "myhost", "skynet"}
 		err := logic.ValidateDNSUpdate(change, entry)
 		err := logic.ValidateDNSUpdate(change, entry)
 		assert.NotNil(t, err)
 		assert.NotNil(t, err)
 		assert.Contains(t, err.Error(), "Field validation for 'Address' failed on the 'required' tag")
 		assert.Contains(t, err.Error(), "Field validation for 'Address' failed on the 'required' tag")
 	})
 	})
 	t.Run("BadAddress", func(t *testing.T) {
 	t.Run("BadAddress", func(t *testing.T) {
-		change := models.DNSEntry{"10.0.256.1", "myhost", "skynet"}
+		change := models.DNSEntry{"10.0.256.1", "", "myhost", "skynet"}
 		err := logic.ValidateDNSUpdate(change, entry)
 		err := logic.ValidateDNSUpdate(change, entry)
 		assert.NotNil(t, err)
 		assert.NotNil(t, err)
 		assert.Contains(t, err.Error(), "Field validation for 'Address' failed on the 'ip' tag")
 		assert.Contains(t, err.Error(), "Field validation for 'Address' failed on the 'ip' tag")
 	})
 	})
 	t.Run("EmptyName", func(t *testing.T) {
 	t.Run("EmptyName", func(t *testing.T) {
 		//this can't actually happen as change.Name is populated if is blank
 		//this can't actually happen as change.Name is populated if is blank
-		change := models.DNSEntry{"10.0.0.2", "", "skynet"}
+		change := models.DNSEntry{"10.0.0.2", "", "", "skynet"}
 		err := logic.ValidateDNSUpdate(change, entry)
 		err := logic.ValidateDNSUpdate(change, entry)
 		assert.NotNil(t, err)
 		assert.NotNil(t, err)
 		assert.Contains(t, err.Error(), "Field validation for 'Name' failed on the 'required' tag")
 		assert.Contains(t, err.Error(), "Field validation for 'Name' failed on the 'required' tag")
@@ -341,13 +341,13 @@ func TestValidateDNSUpdate(t *testing.T) {
 		for i := 1; i < 194; i++ {
 		for i := 1; i < 194; i++ {
 			name = name + "a"
 			name = name + "a"
 		}
 		}
-		change := models.DNSEntry{"10.0.0.2", name, "skynet"}
+		change := models.DNSEntry{"10.0.0.2", "", name, "skynet"}
 		err := logic.ValidateDNSUpdate(change, entry)
 		err := logic.ValidateDNSUpdate(change, entry)
 		assert.NotNil(t, err)
 		assert.NotNil(t, err)
 		assert.Contains(t, err.Error(), "Field validation for 'Name' failed on the 'max' tag")
 		assert.Contains(t, err.Error(), "Field validation for 'Name' failed on the 'max' tag")
 	})
 	})
 	t.Run("NameUnique", func(t *testing.T) {
 	t.Run("NameUnique", func(t *testing.T) {
-		change := models.DNSEntry{"10.0.0.2", "myhost", "wirecat"}
+		change := models.DNSEntry{"10.0.0.2", "", "myhost", "wirecat"}
 		CreateDNS(entry)
 		CreateDNS(entry)
 		CreateDNS(change)
 		CreateDNS(change)
 		err := logic.ValidateDNSUpdate(change, entry)
 		err := logic.ValidateDNSUpdate(change, entry)
@@ -363,25 +363,25 @@ func TestValidateDNSCreate(t *testing.T) {
 	database.InitializeDatabase()
 	database.InitializeDatabase()
 	_ = logic.DeleteDNS("mynode", "skynet")
 	_ = logic.DeleteDNS("mynode", "skynet")
 	t.Run("NoNetwork", func(t *testing.T) {
 	t.Run("NoNetwork", func(t *testing.T) {
-		entry := models.DNSEntry{"10.0.0.2", "myhost", "badnet"}
+		entry := models.DNSEntry{"10.0.0.2", "", "myhost", "badnet"}
 		err := logic.ValidateDNSCreate(entry)
 		err := logic.ValidateDNSCreate(entry)
 		assert.NotNil(t, err)
 		assert.NotNil(t, err)
 		assert.Contains(t, err.Error(), "Field validation for 'Network' failed on the 'network_exists' tag")
 		assert.Contains(t, err.Error(), "Field validation for 'Network' failed on the 'network_exists' tag")
 	})
 	})
 	t.Run("EmptyAddress", func(t *testing.T) {
 	t.Run("EmptyAddress", func(t *testing.T) {
-		entry := models.DNSEntry{"", "myhost", "skynet"}
+		entry := models.DNSEntry{"", "", "myhost", "skynet"}
 		err := logic.ValidateDNSCreate(entry)
 		err := logic.ValidateDNSCreate(entry)
 		assert.NotNil(t, err)
 		assert.NotNil(t, err)
 		assert.Contains(t, err.Error(), "Field validation for 'Address' failed on the 'required' tag")
 		assert.Contains(t, err.Error(), "Field validation for 'Address' failed on the 'required' tag")
 	})
 	})
 	t.Run("BadAddress", func(t *testing.T) {
 	t.Run("BadAddress", func(t *testing.T) {
-		entry := models.DNSEntry{"10.0.256.1", "myhost", "skynet"}
+		entry := models.DNSEntry{"10.0.256.1", "", "myhost", "skynet"}
 		err := logic.ValidateDNSCreate(entry)
 		err := logic.ValidateDNSCreate(entry)
 		assert.NotNil(t, err)
 		assert.NotNil(t, err)
 		assert.Contains(t, err.Error(), "Field validation for 'Address' failed on the 'ip' tag")
 		assert.Contains(t, err.Error(), "Field validation for 'Address' failed on the 'ip' tag")
 	})
 	})
 	t.Run("EmptyName", func(t *testing.T) {
 	t.Run("EmptyName", func(t *testing.T) {
-		entry := models.DNSEntry{"10.0.0.2", "", "skynet"}
+		entry := models.DNSEntry{"10.0.0.2", "", "", "skynet"}
 		err := logic.ValidateDNSCreate(entry)
 		err := logic.ValidateDNSCreate(entry)
 		assert.NotNil(t, err)
 		assert.NotNil(t, err)
 		assert.Contains(t, err.Error(), "Field validation for 'Name' failed on the 'required' tag")
 		assert.Contains(t, err.Error(), "Field validation for 'Name' failed on the 'required' tag")
@@ -391,13 +391,13 @@ func TestValidateDNSCreate(t *testing.T) {
 		for i := 1; i < 194; i++ {
 		for i := 1; i < 194; i++ {
 			name = name + "a"
 			name = name + "a"
 		}
 		}
-		entry := models.DNSEntry{"10.0.0.2", name, "skynet"}
+		entry := models.DNSEntry{"10.0.0.2", "", name, "skynet"}
 		err := logic.ValidateDNSCreate(entry)
 		err := logic.ValidateDNSCreate(entry)
 		assert.NotNil(t, err)
 		assert.NotNil(t, err)
 		assert.Contains(t, err.Error(), "Field validation for 'Name' failed on the 'max' tag")
 		assert.Contains(t, err.Error(), "Field validation for 'Name' failed on the 'max' tag")
 	})
 	})
 	t.Run("NameUnique", func(t *testing.T) {
 	t.Run("NameUnique", func(t *testing.T) {
-		entry := models.DNSEntry{"10.0.0.2", "myhost", "skynet"}
+		entry := models.DNSEntry{"10.0.0.2", "", "myhost", "skynet"}
 		_, _ = CreateDNS(entry)
 		_, _ = CreateDNS(entry)
 		err := logic.ValidateDNSCreate(entry)
 		err := logic.ValidateDNSCreate(entry)
 		assert.NotNil(t, err)
 		assert.NotNil(t, err)

+ 13 - 1
controllers/ext_client.go

@@ -135,6 +135,18 @@ func getExtClientConf(w http.ResponseWriter, r *http.Request) {
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		returnErrorResponse(w, r, formatError(err, "internal"))
 		return
 		return
 	}
 	}
+
+	addrString := client.Address
+	if addrString != "" {
+		addrString += "/32"
+	}
+	if client.Address6 != "" {
+		if addrString != "" {
+			addrString += ","
+		}
+		addrString += client.Address6 + "/128"
+	}
+
 	keepalive := ""
 	keepalive := ""
 	if network.DefaultKeepalive != 0 {
 	if network.DefaultKeepalive != 0 {
 		keepalive = "PersistentKeepalive = " + strconv.Itoa(int(network.DefaultKeepalive))
 		keepalive = "PersistentKeepalive = " + strconv.Itoa(int(network.DefaultKeepalive))
@@ -167,7 +179,7 @@ AllowedIPs = %s
 Endpoint = %s
 Endpoint = %s
 %s
 %s
 
 
-`, client.Address+"/32",
+`, addrString,
 		client.PrivateKey,
 		client.PrivateKey,
 		defaultMTU,
 		defaultMTU,
 		defaultDNS,
 		defaultDNS,

+ 33 - 0
controllers/network_test.go

@@ -284,6 +284,26 @@ func TestValidateNetworkUpdate(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func TestIpv6Network(t *testing.T) {
+	//these seem to work but not sure it the tests are really testing the functionality
+
+	database.InitializeDatabase()
+	os.Setenv("MASTER_KEY", "secretkey")
+	createNet()
+	createNetDualStack()
+	network, err := logic.GetNetwork("skynet6")
+	t.Run("Test Network Create IPv6", func(t *testing.T) {
+		assert.Nil(t, err)
+		assert.Equal(t, network.AddressRange6, "fde6:be04:fa5e:d076::/64")
+	})
+	node1 := models.Node{PublicKey: "DM5qhLAE20PG9BbfBCger+Ac9D2NDOwCtY1rbYDLf34=", Name: "testnode", Endpoint: "10.0.0.50", MacAddress: "01:02:03:04:05:06", Password: "password", Network: "skynet6", OS: "linux"}
+	nodeErr := logic.CreateNode(&node1)
+	t.Run("Test node on network IPv6", func(t *testing.T) {
+		assert.Nil(t, nodeErr)
+		assert.Equal(t, node1.Address6, "fde6:be04:fa5e:d076::")
+	})
+}
+
 func deleteAllNetworks() {
 func deleteAllNetworks() {
 	deleteAllNodes()
 	deleteAllNodes()
 	nets, _ := logic.GetNetworks()
 	nets, _ := logic.GetNetworks()
@@ -301,3 +321,16 @@ func createNet() {
 		logic.CreateNetwork(network)
 		logic.CreateNetwork(network)
 	}
 	}
 }
 }
+
+func createNetDualStack() {
+	var network models.Network
+	network.NetID = "skynet6"
+	network.AddressRange = "10.1.2.0/24"
+	network.AddressRange6 = "fde6:be04:fa5e:d076::/64"
+	network.IsIPv4 = "yes"
+	network.IsIPv6 = "yes"
+	_, err := logic.GetNetwork("skynet6")
+	if err != nil {
+		logic.CreateNetwork(network)
+	}
+}

+ 2 - 2
controllers/relay.go

@@ -31,7 +31,7 @@ func createRelay(w http.ResponseWriter, r *http.Request) {
 	for _, relayedNode := range updatenodes {
 	for _, relayedNode := range updatenodes {
 		err = mq.NodeUpdate(&relayedNode)
 		err = mq.NodeUpdate(&relayedNode)
 		if err != nil {
 		if err != nil {
-			logger.Log(1, "error sending update to relayed node ", relayedNode.Address, "on network", relay.NetID, ": ", err.Error())
+			logger.Log(1, "error sending update to relayed node ", relayedNode.Name, "on network", relay.NetID, ": ", err.Error())
 		}
 		}
 	}
 	}
 	w.WriteHeader(http.StatusOK)
 	w.WriteHeader(http.StatusOK)
@@ -53,7 +53,7 @@ func deleteRelay(w http.ResponseWriter, r *http.Request) {
 	for _, relayedNode := range updatenodes {
 	for _, relayedNode := range updatenodes {
 		err = mq.NodeUpdate(&relayedNode)
 		err = mq.NodeUpdate(&relayedNode)
 		if err != nil {
 		if err != nil {
-			logger.Log(1, "error sending update to relayed node ", relayedNode.Address, "on network", netid, ": ", err.Error())
+			logger.Log(1, "error sending update to relayed node ", relayedNode.Name, "on network", netid, ": ", err.Error())
 		}
 		}
 	}
 	}
 	w.WriteHeader(http.StatusOK)
 	w.WriteHeader(http.StatusOK)

+ 0 - 1
logic/dns.go

@@ -50,7 +50,6 @@ func SetDNS() error {
 // GetDNS - gets the DNS of a current network
 // GetDNS - gets the DNS of a current network
 func GetDNS(network string) ([]models.DNSEntry, error) {
 func GetDNS(network string) ([]models.DNSEntry, error) {
 
 
-	var dns []models.DNSEntry
 	dns, err := GetNodeDNS(network)
 	dns, err := GetNodeDNS(network)
 	if err != nil && !database.IsEmptyRecord(err) {
 	if err != nil && !database.IsEmptyRecord(err) {
 		return dns, err
 		return dns, err

+ 5 - 3
models/dnsEntry.go

@@ -1,8 +1,10 @@
 //TODO:  Either add a returnNetwork and returnKey, or delete this
 //TODO:  Either add a returnNetwork and returnKey, or delete this
 package models
 package models
 
 
+// DNSEntry - a DNS entry represented as struct
 type DNSEntry struct {
 type DNSEntry struct {
-	Address string `json:"address" bson:"address" validate:"required,ip"`
-	Name    string `json:"name" bson:"name" validate:"required,name_unique,min=1,max=192"`
-	Network string `json:"network" bson:"network" validate:"network_exists"`
+	Address  string `json:"address" bson:"address" validate:"ip"`
+	Address6 string `json:"address6" bson:"address6"`
+	Name     string `json:"name" bson:"name" validate:"required,name_unique,min=1,max=192"`
+	Network  string `json:"network" bson:"network" validate:"network_exists"`
 }
 }

+ 8 - 0
models/node.go

@@ -100,6 +100,14 @@ func isLess(ipA string, ipB string) bool {
 	return bytes.Compare(ipNetA, ipNetB) < 0
 	return bytes.Compare(ipNetA, ipNetB) < 0
 }
 }
 
 
+// Node.PrimaryAddress - return ipv4 address if present, else return ipv6
+func (node *Node) PrimaryAddress() string {
+	if node.Address != "" {
+		return node.Address
+	}
+	return node.Address6
+}
+
 // Node.SetDefaultMTU - sets default MTU of a node
 // Node.SetDefaultMTU - sets default MTU of a node
 func (node *Node) SetDefaultMTU() {
 func (node *Node) SetDefaultMTU() {
 	if node.MTU == 0 {
 	if node.MTU == 0 {

+ 1 - 1
netclient/config/config.go

@@ -232,7 +232,7 @@ func GetCLIConfig(c *cli.Context) (ClientConfig, string, error) {
 	cfg.Node.MacAddress = c.String("macaddress")
 	cfg.Node.MacAddress = c.String("macaddress")
 	cfg.Node.LocalAddress = c.String("localaddress")
 	cfg.Node.LocalAddress = c.String("localaddress")
 	cfg.Node.Address = c.String("address")
 	cfg.Node.Address = c.String("address")
-	cfg.Node.Address6 = c.String("addressIPV6")
+	cfg.Node.Address6 = c.String("address6")
 	//cfg.Node.Roaming = c.String("roaming")
 	//cfg.Node.Roaming = c.String("roaming")
 	cfg.Node.DNSOn = c.String("dnson")
 	cfg.Node.DNSOn = c.String("dnson")
 	cfg.Node.IsLocal = c.String("islocal")
 	cfg.Node.IsLocal = c.String("islocal")

+ 4 - 3
netclient/functions/common.go

@@ -177,9 +177,10 @@ func LeaveNetwork(network string, force bool) error {
 	wgClient, wgErr := wgctrl.New()
 	wgClient, wgErr := wgctrl.New()
 	if wgErr == nil {
 	if wgErr == nil {
 		removeIface := cfg.Node.Interface
 		removeIface := cfg.Node.Interface
+		queryAddr := cfg.Node.PrimaryAddress()
 		if ncutils.IsMac() {
 		if ncutils.IsMac() {
 			var macIface string
 			var macIface string
-			macIface, wgErr = local.GetMacIface(cfg.Node.Address)
+			macIface, wgErr = local.GetMacIface(queryAddr)
 			if wgErr == nil && removeIface != "" {
 			if wgErr == nil && removeIface != "" {
 				removeIface = macIface
 				removeIface = macIface
 			}
 			}
@@ -187,10 +188,10 @@ func LeaveNetwork(network string, force bool) error {
 		}
 		}
 		dev, devErr := wgClient.Device(removeIface)
 		dev, devErr := wgClient.Device(removeIface)
 		if devErr == nil {
 		if devErr == nil {
-			local.FlushPeerRoutes(removeIface, cfg.Node.Address, dev.Peers[:])
+			local.FlushPeerRoutes(removeIface, queryAddr, dev.Peers[:])
 			_, cidr, cidrErr := net.ParseCIDR(cfg.NetworkSettings.AddressRange)
 			_, cidr, cidrErr := net.ParseCIDR(cfg.NetworkSettings.AddressRange)
 			if cidrErr == nil {
 			if cidrErr == nil {
-				local.RemoveCIDRRoute(removeIface, cfg.Node.Address, cidr)
+				local.RemoveCIDRRoute(removeIface, queryAddr, cidr)
 			}
 			}
 		} else {
 		} else {
 			logger.Log(1, "could not flush peer routes when leaving network, ", cfg.Node.Network)
 			logger.Log(1, "could not flush peer routes when leaving network, ", cfg.Node.Network)

+ 3 - 1
netclient/functions/mqhandlers.go

@@ -188,10 +188,12 @@ func UpdatePeers(client mqtt.Client, msg mqtt.Message) {
 		logger.Log(0, "error updating wireguard peers"+err.Error())
 		logger.Log(0, "error updating wireguard peers"+err.Error())
 		return
 		return
 	}
 	}
+	queryAddr := cfg.Node.PrimaryAddress()
+
 	//err = wireguard.SyncWGQuickConf(cfg.Node.Interface, file)
 	//err = wireguard.SyncWGQuickConf(cfg.Node.Interface, file)
 	var iface = cfg.Node.Interface
 	var iface = cfg.Node.Interface
 	if ncutils.IsMac() {
 	if ncutils.IsMac() {
-		iface, err = local.GetMacIface(cfg.Node.Address)
+		iface, err = local.GetMacIface(queryAddr)
 		if err != nil {
 		if err != nil {
 			logger.Log(0, "error retrieving mac iface: "+err.Error())
 			logger.Log(0, "error retrieving mac iface: "+err.Error())
 			return
 			return

+ 1 - 1
netclient/local/routes.go

@@ -11,7 +11,7 @@ import (
 // TODO handle ipv6 in future
 // TODO handle ipv6 in future
 
 
 // SetPeerRoutes - sets/removes ip routes for each peer on a network
 // SetPeerRoutes - sets/removes ip routes for each peer on a network
-func SetPeerRoutes(iface, currentNodeAddr string, oldPeers map[string][]net.IPNet, newPeers []wgtypes.PeerConfig) {
+func SetPeerRoutes(iface string, oldPeers map[string][]net.IPNet, newPeers []wgtypes.PeerConfig) {
 	// traverse through all recieved peers
 	// traverse through all recieved peers
 	for _, peer := range newPeers {
 	for _, peer := range newPeers {
 		// if pubkey found in existing peers, check against existing peer
 		// if pubkey found in existing peers, check against existing peer

+ 8 - 1
netclient/local/routes_darwin.go

@@ -33,7 +33,14 @@ func deleteRoute(iface string, addr *net.IPNet, address string) error {
 }
 }
 
 
 func setCidr(iface, address string, addr *net.IPNet) {
 func setCidr(iface, address string, addr *net.IPNet) {
-	ncutils.RunCmd("route -q -n add -net "+addr.String()+" "+address, false)
+	cidr := ipaddr.NewIPAddressString(addr.String()).GetAddress()
+	if cidr.IsIPv4() {
+		ncutils.RunCmd("route -q -n add -net "+addr.String()+" "+address, false)
+	} else if cidr.IsIPv6() {
+		ncutils.RunCmd("route -A inet6 -q -n add -net "+addr.String()+" "+address, false)
+	} else {
+		logger.Log(1, "could not parse address: "+addr.String())
+	}
 }
 }
 
 
 func removeCidr(iface string, addr *net.IPNet, address string) {
 func removeCidr(iface string, addr *net.IPNet, address string) {

+ 8 - 0
netclient/local/routes_freebsd.go

@@ -19,6 +19,14 @@ func deleteRoute(iface string, addr *net.IPNet, address string) error {
 }
 }
 
 
 func setCidr(iface, address string, addr *net.IPNet) {
 func setCidr(iface, address string, addr *net.IPNet) {
+	cidr := ipaddr.NewIPAddressString(addr.String()).GetAddress()
+	if cidr.IsIPv4() {
+		ncutils.RunCmd("route add -net "+addr.String()+" -interface "+iface, false)
+	} else if cidr.IsIPv6() {
+		ncutils.RunCmd("route add -net -inet6 "+addr.String()+" -interface "+iface, false)
+	} else {
+		logger.Log(1, "could not parse address: "+addr.String())
+	}
 	ncutils.RunCmd("route add -net "+addr.String()+" -interface "+iface, false)
 	ncutils.RunCmd("route add -net "+addr.String()+" -interface "+iface, false)
 }
 }
 
 

+ 10 - 1
netclient/local/routes_linux.go

@@ -7,7 +7,9 @@ import (
 	"net"
 	"net"
 	"strings"
 	"strings"
 
 
+	"github.com/gravitl/netmaker/logger"
 	"github.com/gravitl/netmaker/netclient/ncutils"
 	"github.com/gravitl/netmaker/netclient/ncutils"
+	"github.com/seancfoley/ipaddress-go/ipaddr"
 )
 )
 
 
 func setRoute(iface string, addr *net.IPNet, address string) error {
 func setRoute(iface string, addr *net.IPNet, address string) error {
@@ -28,7 +30,14 @@ func deleteRoute(iface string, addr *net.IPNet, address string) error {
 }
 }
 
 
 func setCidr(iface, address string, addr *net.IPNet) {
 func setCidr(iface, address string, addr *net.IPNet) {
-	ncutils.RunCmd("ip -4 route add "+addr.String()+" dev "+iface, false)
+	cidr := ipaddr.NewIPAddressString(addr.String()).GetAddress()
+	if cidr.IsIPv4() {
+		ncutils.RunCmd("ip -4 route add "+addr.String()+" dev "+iface, false)
+	} else if cidr.IsIPv6() {
+		ncutils.RunCmd("ip -6 route add "+addr.String()+" dev "+iface, false)
+	} else {
+		logger.Log(1, "could not parse address: "+addr.String())
+	}
 }
 }
 
 
 func removeCidr(iface string, addr *net.IPNet, address string) {
 func removeCidr(iface string, addr *net.IPNet, address string) {

+ 33 - 17
netclient/wireguard/common.go

@@ -28,7 +28,6 @@ const (
 // SetPeers - sets peers on a given WireGuard interface
 // SetPeers - sets peers on a given WireGuard interface
 func SetPeers(iface string, node *models.Node, peers []wgtypes.PeerConfig) error {
 func SetPeers(iface string, node *models.Node, peers []wgtypes.PeerConfig) error {
 	var devicePeers []wgtypes.Peer
 	var devicePeers []wgtypes.Peer
-	var currentNodeAddr = node.Address
 	var keepalive = node.PersistentKeepalive
 	var keepalive = node.PersistentKeepalive
 	var oldPeerAllowedIps = make(map[string][]net.IPNet, len(peers))
 	var oldPeerAllowedIps = make(map[string][]net.IPNet, len(peers))
 	var err error
 	var err error
@@ -115,7 +114,7 @@ func SetPeers(iface string, node *models.Node, peers []wgtypes.PeerConfig) error
 		err = SetMacPeerRoutes(iface)
 		err = SetMacPeerRoutes(iface)
 		return err
 		return err
 	} else if ncutils.IsLinux() {
 	} else if ncutils.IsLinux() {
-		local.SetPeerRoutes(iface, currentNodeAddr, oldPeerAllowedIps, peers)
+		local.SetPeerRoutes(iface, oldPeerAllowedIps, peers)
 	}
 	}
 
 
 	return nil
 	return nil
@@ -147,9 +146,10 @@ func InitWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig
 	} else {
 	} else {
 		return fmt.Errorf("no interface to configure")
 		return fmt.Errorf("no interface to configure")
 	}
 	}
-	if node.Address == "" {
+	if node.PrimaryAddress() == "" {
 		return fmt.Errorf("no address to configure")
 		return fmt.Errorf("no address to configure")
 	}
 	}
+
 	if node.UDPHolePunch == "yes" {
 	if node.UDPHolePunch == "yes" {
 		node.ListenPort = 0
 		node.ListenPort = 0
 	}
 	}
@@ -161,7 +161,7 @@ func InitWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig
 	confPath := ncutils.GetNetclientPathSpecific() + ifacename + ".conf"
 	confPath := ncutils.GetNetclientPathSpecific() + ifacename + ".conf"
 	var deviceiface = ifacename
 	var deviceiface = ifacename
 	if ncutils.IsMac() { // if node is Mac (Darwin) get the tunnel name first
 	if ncutils.IsMac() { // if node is Mac (Darwin) get the tunnel name first
-		deviceiface, err = local.GetMacIface(node.Address)
+		deviceiface, err = local.GetMacIface(node.PrimaryAddress())
 		if err != nil || deviceiface == "" {
 		if err != nil || deviceiface == "" {
 			deviceiface = ifacename
 			deviceiface = ifacename
 		}
 		}
@@ -175,7 +175,7 @@ func InitWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig
 	ifaceReady := strings.Contains(output, deviceiface)
 	ifaceReady := strings.Contains(output, deviceiface)
 	for !ifaceReady && !(time.Now().After(starttime.Add(time.Second << 4))) {
 	for !ifaceReady && !(time.Now().After(starttime.Add(time.Second << 4))) {
 		if ncutils.IsMac() { // if node is Mac (Darwin) get the tunnel name first
 		if ncutils.IsMac() { // if node is Mac (Darwin) get the tunnel name first
-			deviceiface, err = local.GetMacIface(node.Address)
+			deviceiface, err = local.GetMacIface(node.PrimaryAddress())
 			if err != nil || deviceiface == "" {
 			if err != nil || deviceiface == "" {
 				deviceiface = ifacename
 				deviceiface = ifacename
 			}
 			}
@@ -209,13 +209,27 @@ func InitWireguard(node *models.Node, privkey string, peers []wgtypes.PeerConfig
 		}
 		}
 		time.Sleep(time.Second)
 		time.Sleep(time.Second)
 	}
 	}
-	_, cidr, cidrErr := net.ParseCIDR(modcfg.NetworkSettings.AddressRange)
-	if cidrErr == nil {
-		local.SetCIDRRoute(ifacename, node.Address, cidr)
-	} else {
-		logger.Log(1, "could not set cidr route properly: ", cidrErr.Error())
+
+	//ipv4
+	if node.Address != "" {
+		_, cidr, cidrErr := net.ParseCIDR(modcfg.NetworkSettings.AddressRange)
+		if cidrErr == nil {
+			local.SetCIDRRoute(ifacename, node.Address, cidr)
+		} else {
+			logger.Log(1, "could not set cidr route properly: ", cidrErr.Error())
+		}
+		local.SetCurrentPeerRoutes(ifacename, node.Address, peers)
+	}
+	if node.Address6 != "" {
+		//ipv6
+		_, cidr, cidrErr := net.ParseCIDR(modcfg.NetworkSettings.AddressRange6)
+		if cidrErr == nil {
+			local.SetCIDRRoute(ifacename, node.Address6, cidr)
+		} else {
+			logger.Log(1, "could not set cidr route properly: ", cidrErr.Error())
+		}
+		local.SetCurrentPeerRoutes(ifacename, node.Address6, peers)
 	}
 	}
-	local.SetCurrentPeerRoutes(ifacename, node.Address, peers)
 
 
 	return err
 	return err
 }
 }
@@ -238,12 +252,14 @@ func SetWGConfig(network string, peerupdate bool) error {
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
-	var iface string
-	iface = nodecfg.Interface
-	if ncutils.IsMac() {
-		iface, err = local.GetMacIface(nodecfg.Address)
-		if err != nil {
-			return err
+	if peerupdate && !ncutils.IsFreeBSD() && !(ncutils.IsLinux() && !ncutils.IsKernel()) {
+		var iface string
+		iface = nodecfg.Interface
+		if ncutils.IsMac() {
+			iface, err = local.GetMacIface(nodecfg.PrimaryAddress())
+			if err != nil {
+				return err
+			}
 		}
 		}
 		err = SetPeers(iface, &nodecfg, []wgtypes.PeerConfig{})
 		err = SetPeers(iface, &nodecfg, []wgtypes.PeerConfig{})
 	} else if peerupdate {
 	} else if peerupdate {

+ 15 - 6
netclient/wireguard/noquick.go

@@ -52,13 +52,22 @@ func ApplyWithoutWGQuick(node *models.Node, ifacename string, confPath string) e
 		}
 		}
 	}
 	}
 
 
-	netmaskArr := strings.Split(node.NetworkSettings.AddressRange, "/")
-	var netmask = "32"
-	if len(netmaskArr) == 2 {
-		netmask = netmaskArr[1]
+	if node.Address != "" {
+		netmaskArr := strings.Split(node.NetworkSettings.AddressRange, "/")
+		var netmask = "32"
+		if len(netmaskArr) == 2 {
+			netmask = netmaskArr[1]
+		}
+		setKernelDevice(ifacename, node.Address, netmask)
+	}
+	if node.Address6 != "" {
+		netmaskArr := strings.Split(node.NetworkSettings.AddressRange6, "/")
+		var netmask = "128"
+		if len(netmaskArr) == 2 {
+			netmask = netmaskArr[1]
+		}
+		setKernelDevice(ifacename, node.Address6, netmask)
 	}
 	}
-	setKernelDevice(ifacename, node.Address, netmask)
-
 	_, err = wgclient.Device(ifacename)
 	_, err = wgclient.Device(ifacename)
 	if err != nil {
 	if err != nil {
 		if !os.IsNotExist(err) {
 		if !os.IsNotExist(err) {