From f5a50e2bc36e360a33cbdcf63682090dceb0d5ad Mon Sep 17 00:00:00 2001
From: Simon Zolin <s.zolin@adguard.com>
Date: Thu, 30 Apr 2020 13:24:40 +0300
Subject: [PATCH] http status, set config

---
 AGHTechDoc.md      | 26 +++++++++++++++++++-------
 dhcpd/dhcp_http.go | 33 ++++++++++++++++++++++++++++++++-
 dhcpd/dhcpd.go     |  8 +++-----
 dhcpd/v6.go        |  5 +++++
 4 files changed, 59 insertions(+), 13 deletions(-)

diff --git a/AGHTechDoc.md b/AGHTechDoc.md
index 5a3b001c..08624100 100644
--- a/AGHTechDoc.md
+++ b/AGHTechDoc.md
@@ -405,6 +405,11 @@ Response:
 			"lease_duration":60,
 			"icmp_timeout_msec":0
 		},
+		"config_v6":{
+			"enabled":false,
+			"range_start":"...",
+			"lease_duration":60,
+		}
 		"leases":[
 			{"ip":"...","mac":"...","hostname":"...","expires":"..."}
 			...
@@ -463,14 +468,21 @@ Request:
 	POST /control/dhcp/set_config
 
 	{
-		"enabled":true,
-		"interface_name":"vboxnet0",
-		"gateway_ip":"192.169.56.1",
-		"subnet_mask":"255.255.255.0",
-		"range_start":"192.169.56.3",
-		"range_end":"192.169.56.3",
+	"enabled":true,
+	"interface_name":"vboxnet0",
+
+	"gateway_ip":"192.169.56.1",
+	"subnet_mask":"255.255.255.0",
+	"range_start":"192.169.56.100",
+	"range_end":"192.169.56.200",
+	"lease_duration":60,
+	"icmp_timeout_msec":0,
+
+	"v6":{
+		"enabled":false,
+		"range_start":"...",
 		"lease_duration":60,
-		"icmp_timeout_msec":0
+	}
 	}
 
 Response:
diff --git a/dhcpd/dhcp_http.go b/dhcpd/dhcp_http.go
index d6926e08..26c23a45 100644
--- a/dhcpd/dhcp_http.go
+++ b/dhcpd/dhcp_http.go
@@ -40,11 +40,34 @@ func convertLeases(inputLeases []Lease, includeExpires bool) []map[string]string
 	return leases
 }
 
+type v6ServerConfJSON struct {
+	Enabled       bool   `json:"enabled"`
+	RangeStart    string `json:"range_start"`
+	LeaseDuration uint32 `json:"lease_duration"`
+}
+
+func v6ServerConfToJSON(c V6ServerConf) v6ServerConfJSON {
+	return v6ServerConfJSON{
+		Enabled:       c.Enabled,
+		RangeStart:    c.RangeStart,
+		LeaseDuration: c.LeaseDuration,
+	}
+}
+
+func v6JSONToServerConf(c v6ServerConfJSON) V6ServerConf {
+	return V6ServerConf{
+		Enabled:       c.Enabled,
+		RangeStart:    c.RangeStart,
+		LeaseDuration: c.LeaseDuration,
+	}
+}
+
 func (s *Server) handleDHCPStatus(w http.ResponseWriter, r *http.Request) {
 	leases := convertLeases(s.Leases(LeasesDynamic), true)
 	staticLeases := convertLeases(s.Leases(LeasesStatic), false)
 	status := map[string]interface{}{
 		"config":        s.conf,
+		"config_v6":     v6ServerConfToJSON(s.conf.Conf6),
 		"leases":        leases,
 		"static_leases": staticLeases,
 	}
@@ -65,7 +88,7 @@ type staticLeaseJSON struct {
 
 type dhcpServerConfigJSON struct {
 	ServerConfig `json:",inline"`
-	StaticLeases []staticLeaseJSON `json:"static_leases"`
+	V6           v6ServerConfJSON `json:"v6"`
 }
 
 func (s *Server) handleDHCPSetConfig(w http.ResponseWriter, r *http.Request) {
@@ -92,6 +115,14 @@ func (s *Server) handleDHCPSetConfig(w http.ResponseWriter, r *http.Request) {
 		httpError(r, w, http.StatusBadRequest, "Invalid DHCP configuration: %s", err)
 		return
 	}
+
+	s6, err := v6Create(v6JSONToServerConf(newconfig.V6))
+	if s6 == nil {
+		httpError(r, w, http.StatusBadRequest, "Invalid DHCPv6 configuration: %s", err)
+		return
+	}
+	s.srv6 = s6
+
 	s.conf.ConfigModified()
 
 	if newconfig.Enabled {
diff --git a/dhcpd/dhcpd.go b/dhcpd/dhcpd.go
index 0d215f39..d90e4754 100644
--- a/dhcpd/dhcpd.go
+++ b/dhcpd/dhcpd.go
@@ -269,11 +269,9 @@ func (s *Server) Start() error {
 		}()
 	}
 
-	if s.conf.Conf6.Enabled {
-		err := s.srv6.Start(*iface)
-		if err != nil {
-			return err
-		}
+	err = s.srv6.Start(*iface)
+	if err != nil {
+		return err
 	}
 
 	return nil
diff --git a/dhcpd/v6.go b/dhcpd/v6.go
index 9d4acfd7..1b95cd08 100644
--- a/dhcpd/v6.go
+++ b/dhcpd/v6.go
@@ -284,6 +284,11 @@ func getIfaceIPv6(iface net.Interface) []net.IP {
 
 // Start - start server
 func (s *V6Server) Start(iface net.Interface) error {
+	if !s.conf.Enabled {
+		return nil
+	}
+
+	log.Debug("DHCPv6: starting...")
 	s.conf.dnsIPAddrs = getIfaceIPv6(iface)
 	if len(s.conf.dnsIPAddrs) == 0 {
 		return fmt.Errorf("DHCPv6: no IPv6 address for interface %s", iface.Name)