+ DHCP: add ra_slaac_only, ra_allow_slaac config settings

Close # 2076

Squashed commit of the following:

commit 7a938fc6ffa0adc1e705f59778d7e7442b83d4b9
Merge: 3db2605e 6222d17d
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Thu Sep 24 16:34:23 2020 +0300

    Merge remote-tracking branch 'origin/master' into 2076-dhcp-ra-slaac

commit 3db2605efda79e8d361fb46c32bb9ec753de0e02
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Thu Sep 24 16:21:36 2020 +0300

    minor

commit de31c6aeebd78dce54ca54fbff010f3dd50ce974
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Thu Sep 24 12:23:09 2020 +0300

    don't initialize DHCPv6 server if we must force the clients to use SLAAC

commit 7c4239899c85880641dc5b4826ae34386bc5ee94
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Tue Sep 22 19:34:27 2020 +0300

    minor

commit 2b57688ce4c31d45d2236bd397e0b3041dac68c1
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Mon Sep 21 19:50:11 2020 +0300

    + DHCP: add ra_slaac_only, ra_allow_slaac config settings
This commit is contained in:
Simon Zolin
2020-09-24 18:33:11 +03:00
parent 6222d17d86
commit 990f531f54
6 changed files with 379 additions and 8 deletions

View File

@@ -25,6 +25,8 @@ type v6Server struct {
ipAddrs [256]byte
sid dhcpv6.Duid
ra raCtx // RA module
conf V6ServerConf
}
@@ -557,6 +559,27 @@ func getIfaceIPv6(iface net.Interface) []net.IP {
return res
}
// initialize RA module
func (s *v6Server) initRA(iface *net.Interface) error {
// choose the source IP address - should be link-local-unicast
s.ra.ipAddr = s.conf.dnsIPAddrs[0]
for _, ip := range s.conf.dnsIPAddrs {
if ip.IsLinkLocalUnicast() {
s.ra.ipAddr = ip
break
}
}
s.ra.raAllowSlaac = s.conf.RaAllowSlaac
s.ra.raSlaacOnly = s.conf.RaSlaacOnly
s.ra.dnsIPAddr = s.ra.ipAddr
s.ra.prefixIPAddr = s.conf.ipStart
s.ra.ifaceName = s.conf.InterfaceName
s.ra.iface = iface
s.ra.packetSendPeriod = 1 * time.Second
return s.ra.Init()
}
// Start - start server
func (s *v6Server) Start() error {
if !s.conf.Enabled {
@@ -568,13 +591,25 @@ func (s *v6Server) Start() error {
return wrapErrPrint(err, "Couldn't find interface by name %s", s.conf.InterfaceName)
}
log.Debug("DHCPv6: starting...")
s.conf.dnsIPAddrs = getIfaceIPv6(*iface)
if len(s.conf.dnsIPAddrs) == 0 {
log.Debug("DHCPv6: no IPv6 address for interface %s", iface.Name)
return nil
}
err = s.initRA(iface)
if err != nil {
return err
}
// don't initialize DHCPv6 server if we must force the clients to use SLAAC
if s.conf.RaSlaacOnly {
log.Debug("DHCPv6: not starting DHCPv6 server due to ra_slaac_only=true")
return nil
}
log.Debug("DHCPv6: starting...")
if len(iface.HardwareAddr) != 6 {
return fmt.Errorf("DHCPv6: invalid MAC %s", iface.HardwareAddr)
}
@@ -598,11 +633,15 @@ func (s *v6Server) Start() error {
err = s.srv.Serve()
log.Debug("DHCPv6: srv.Serve: %s", err)
}()
return nil
}
// Stop - stop server
func (s *v6Server) Stop() {
s.ra.Close()
// DHCPv6 server may not be initialized if ra_slaac_only=true
if s.srv == nil {
return
}
@@ -626,7 +665,7 @@ func v6Create(conf V6ServerConf) (DHCPServer, error) {
}
s.conf.ipStart = net.ParseIP(conf.RangeStart)
if s.conf.ipStart == nil {
if s.conf.ipStart == nil || s.conf.ipStart.To16() == nil {
return s, fmt.Errorf("DHCPv6: invalid range-start IP: %s", conf.RangeStart)
}