radvd: announce link-local ipv6 address for DNS

This commit is contained in:
Michael Stapelberg 2018-06-26 09:04:05 +02:00
parent 10df129c1f
commit 8e95e25442
2 changed files with 31 additions and 12 deletions

View File

@ -89,7 +89,7 @@ Neighbor discovery proxy : No
Router lifetime : 1800 (0x00000708) seconds Router lifetime : 1800 (0x00000708) seconds
Reachable time : unspecified (0x00000000) Reachable time : unspecified (0x00000000)
Retransmit time : unspecified (0x00000000) Retransmit time : unspecified (0x00000000)
Recursive DNS server : 2a02:168:4a00::1 Recursive DNS server : fe80::73:53ff:fe00:cafe
DNS server lifetime : 1800 (0x00000708) seconds DNS server lifetime : 1800 (0x00000708) seconds
Prefix : 2a02:168:4a00::/64 Prefix : 2a02:168:4a00::/64
On-link : Yes On-link : Yes

View File

@ -143,7 +143,7 @@ func (o prefixInfo) Marshal() layers.ICMPv6Option {
type rdnss struct { type rdnss struct {
lifetime uint32 // seconds lifetime uint32 // seconds
server [16]byte server []byte
} }
func (o rdnss) Marshal() layers.ICMPv6Option { func (o rdnss) Marshal() layers.ICMPv6Option {
@ -157,6 +157,14 @@ func (o rdnss) Marshal() layers.ICMPv6Option {
} }
} }
var ipv6LinkLocal = func(cidr string) *net.IPNet {
_, net, err := net.ParseCIDR(cidr)
if err != nil {
panic(err)
}
return net
}("fe80::/10")
func (s *Server) sendAdvertisement(addr net.Addr) error { func (s *Server) sendAdvertisement(addr net.Addr) error {
if s.prefixes == nil { if s.prefixes == nil {
return nil // nothing to do return nil // nothing to do
@ -196,16 +204,27 @@ func (s *Server) sendAdvertisement(addr net.Addr) error {
}).Marshal()) }).Marshal())
} }
if len(s.prefixes) > 0 { if len(s.prefixes) > 0 {
prefix := s.prefixes[0] addrs, err := s.iface.Addrs()
var server [16]byte if err != nil {
copy(server[:], prefix.IP) return err
// pick the first address of the prefix, e.g. address 2a02:168:4a00::1 }
// for prefix 2a02:168:4a00::/48 var linkLocal net.IP
server[len(server)-1] = 1 for _, addr := range addrs {
options = append(options, (rdnss{ ipnet, ok := addr.(*net.IPNet)
lifetime: 1800, // seconds if !ok {
server: server, continue
}).Marshal()) }
if ipv6LinkLocal.Contains(ipnet.IP) {
linkLocal = ipnet.IP
break
}
}
if !linkLocal.Equal(net.IPv6zero) {
options = append(options, (rdnss{
lifetime: 1800, // seconds
server: linkLocal,
}).Marshal())
}
} }
s.mu.Unlock() s.mu.Unlock()