+ dhcp: /dhcp/add_static_lease, /dhcp/remove_static_lease: control static lease table
This commit is contained in:
parent
564a41d598
commit
725aeeb910
|
@ -993,6 +993,8 @@ func registerControlHandlers() {
|
|||
http.HandleFunc("/control/dhcp/interfaces", postInstall(optionalAuth(ensureGET(handleDHCPInterfaces))))
|
||||
http.HandleFunc("/control/dhcp/set_config", postInstall(optionalAuth(ensurePOST(handleDHCPSetConfig))))
|
||||
http.HandleFunc("/control/dhcp/find_active_dhcp", postInstall(optionalAuth(ensurePOST(handleDHCPFindActiveServer))))
|
||||
http.HandleFunc("/control/dhcp/add_static_lease", postInstall(optionalAuth(ensurePOST(handleDHCPAddStaticLease))))
|
||||
http.HandleFunc("/control/dhcp/remove_static_lease", postInstall(optionalAuth(ensurePOST(handleDHCPRemoveStaticLease))))
|
||||
|
||||
RegisterTLSHandlers()
|
||||
RegisterClientsHandlers()
|
||||
|
|
69
dhcp.go
69
dhcp.go
|
@ -47,8 +47,15 @@ func handleDHCPStatus(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
}
|
||||
|
||||
type leaseJSON struct {
|
||||
HWAddr string `json:"mac"`
|
||||
IP string `json:"ip"`
|
||||
Hostname string `json:"hostname"`
|
||||
}
|
||||
|
||||
type dhcpServerConfigJSON struct {
|
||||
dhcpd.ServerConfig `json:",inline"`
|
||||
StaticLeases []leaseJSON `json:"static_leases"`
|
||||
}
|
||||
|
||||
func handleDHCPSetConfig(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -349,6 +356,68 @@ func setStaticIP(ifaceName string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func handleDHCPAddStaticLease(w http.ResponseWriter, r *http.Request) {
|
||||
log.Tracef("%s %v", r.Method, r.URL)
|
||||
|
||||
lj := leaseJSON{}
|
||||
err := json.NewDecoder(r.Body).Decode(&lj)
|
||||
if err != nil {
|
||||
httpError(w, http.StatusBadRequest, "json.Decode: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
ip := parseIPv4(lj.IP)
|
||||
if ip == nil {
|
||||
httpError(w, http.StatusBadRequest, "invalid IP")
|
||||
return
|
||||
}
|
||||
|
||||
mac, _ := net.ParseMAC(lj.HWAddr)
|
||||
|
||||
lease := dhcpd.Lease{
|
||||
IP: ip,
|
||||
HWAddr: mac,
|
||||
Hostname: lj.Hostname,
|
||||
}
|
||||
err = dhcpServer.AddStaticLease(lease)
|
||||
if err != nil {
|
||||
httpError(w, http.StatusBadRequest, "%s", err)
|
||||
return
|
||||
}
|
||||
returnOK(w)
|
||||
}
|
||||
|
||||
func handleDHCPRemoveStaticLease(w http.ResponseWriter, r *http.Request) {
|
||||
log.Tracef("%s %v", r.Method, r.URL)
|
||||
|
||||
lj := leaseJSON{}
|
||||
err := json.NewDecoder(r.Body).Decode(&lj)
|
||||
if err != nil {
|
||||
httpError(w, http.StatusBadRequest, "json.Decode: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
ip := parseIPv4(lj.IP)
|
||||
if ip == nil {
|
||||
httpError(w, http.StatusBadRequest, "invalid IP")
|
||||
return
|
||||
}
|
||||
|
||||
mac, _ := net.ParseMAC(lj.HWAddr)
|
||||
|
||||
lease := dhcpd.Lease{
|
||||
IP: ip,
|
||||
HWAddr: mac,
|
||||
Hostname: lj.Hostname,
|
||||
}
|
||||
err = dhcpServer.RemoveStaticLease(lease)
|
||||
if err != nil {
|
||||
httpError(w, http.StatusBadRequest, "%s", err)
|
||||
return
|
||||
}
|
||||
returnOK(w)
|
||||
}
|
||||
|
||||
func startDHCPServer() error {
|
||||
if !config.DHCP.Enabled {
|
||||
// not enabled, don't do anything
|
||||
|
|
|
@ -14,6 +14,7 @@ import (
|
|||
)
|
||||
|
||||
const defaultDiscoverTime = time.Second * 3
|
||||
const leaseExpireStatic = 1
|
||||
|
||||
// Lease contains the necessary information about a DHCP lease
|
||||
// field ordering is important -- yaml fields will mirror ordering from here
|
||||
|
@ -21,7 +22,10 @@ type Lease struct {
|
|||
HWAddr net.HardwareAddr `json:"mac" yaml:"hwaddr"`
|
||||
IP net.IP `json:"ip"`
|
||||
Hostname string `json:"hostname"`
|
||||
Expiry time.Time `json:"expires"`
|
||||
|
||||
// Lease expiration time
|
||||
// 1: static lease
|
||||
Expiry time.Time `json:"expires"`
|
||||
}
|
||||
|
||||
// ServerConfig - DHCP server configuration
|
||||
|
@ -274,7 +278,7 @@ func (s *Server) findLease(p dhcp4.Packet) *Lease {
|
|||
func (s *Server) findExpiredLease() int {
|
||||
now := time.Now().Unix()
|
||||
for i, lease := range s.leases {
|
||||
if lease.Expiry.Unix() <= now {
|
||||
if lease.Expiry.Unix() <= now && lease.Expiry.Unix() != leaseExpireStatic {
|
||||
return i
|
||||
}
|
||||
}
|
||||
|
@ -529,6 +533,69 @@ func (s *Server) handleDecline(p dhcp4.Packet, options dhcp4.Options) dhcp4.Pack
|
|||
return nil
|
||||
}
|
||||
|
||||
// AddStaticLease adds a static lease (thread-safe)
|
||||
func (s *Server) AddStaticLease(l Lease) error {
|
||||
if s.IPpool == nil {
|
||||
return fmt.Errorf("DHCP server isn't started")
|
||||
}
|
||||
|
||||
if len(l.IP) != 4 {
|
||||
return fmt.Errorf("Invalid IP")
|
||||
}
|
||||
if len(l.HWAddr) != 6 {
|
||||
return fmt.Errorf("Invalid MAC")
|
||||
}
|
||||
l.Expiry = time.Unix(leaseExpireStatic, 0)
|
||||
|
||||
s.leasesLock.Lock()
|
||||
defer s.leasesLock.Unlock()
|
||||
|
||||
if s.findReservedHWaddr(l.IP) != nil {
|
||||
return fmt.Errorf("IP is already used")
|
||||
}
|
||||
s.leases = append(s.leases, &l)
|
||||
s.reserveIP(l.IP, l.HWAddr)
|
||||
s.dbStore()
|
||||
return nil
|
||||
}
|
||||
|
||||
// RemoveStaticLease removes a static lease (thread-safe)
|
||||
func (s *Server) RemoveStaticLease(l Lease) error {
|
||||
if s.IPpool == nil {
|
||||
return fmt.Errorf("DHCP server isn't started")
|
||||
}
|
||||
|
||||
if len(l.IP) != 4 {
|
||||
return fmt.Errorf("Invalid IP")
|
||||
}
|
||||
if len(l.HWAddr) != 6 {
|
||||
return fmt.Errorf("Invalid MAC")
|
||||
}
|
||||
|
||||
s.leasesLock.Lock()
|
||||
defer s.leasesLock.Unlock()
|
||||
|
||||
if s.findReservedHWaddr(l.IP) == nil {
|
||||
return fmt.Errorf("Lease not found")
|
||||
}
|
||||
|
||||
var newLeases []*Lease
|
||||
for _, lease := range s.leases {
|
||||
if bytes.Equal(lease.IP.To4(), l.IP) {
|
||||
if !bytes.Equal(lease.HWAddr, l.HWAddr) ||
|
||||
lease.Hostname != l.Hostname {
|
||||
return fmt.Errorf("Lease not found")
|
||||
}
|
||||
continue
|
||||
}
|
||||
newLeases = append(newLeases, lease)
|
||||
}
|
||||
s.leases = newLeases
|
||||
s.unreserveIP(l.IP)
|
||||
s.dbStore()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Leases returns the list of current DHCP leases (thread-safe)
|
||||
func (s *Server) Leases() []Lease {
|
||||
var result []Lease
|
||||
|
|
Loading…
Reference in New Issue