mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-03-25 23:30:41 +01:00
So with clients which only use SLAAC, ctrld could see client's new ip as soon as its state changes to REACHABLE. Moreover, the NDP listener is also changed to listen on all possible ipv6 link local interfaces. That would allow ctrld to get all NDP events happening in local network. SLAAC RFC: https://datatracker.ietf.org/doc/html/rfc4862
65 lines
1.5 KiB
Go
65 lines
1.5 KiB
Go
package clientinfo
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/vishvananda/netlink"
|
|
"golang.org/x/sys/unix"
|
|
|
|
"github.com/Control-D-Inc/ctrld"
|
|
)
|
|
|
|
// scan populates NDP table using information from system mappings.
|
|
func (nd *ndpDiscover) scan() {
|
|
neighs, err := netlink.NeighList(0, netlink.FAMILY_V6)
|
|
if err != nil {
|
|
ctrld.ProxyLogger.Load().Warn().Err(err).Msg("could not get neigh list")
|
|
return
|
|
}
|
|
|
|
for _, n := range neighs {
|
|
// Skipping non-reachable neighbors.
|
|
if n.State&netlink.NUD_REACHABLE == 0 {
|
|
continue
|
|
}
|
|
ip := n.IP.String()
|
|
mac := n.HardwareAddr.String()
|
|
nd.saveInfo(ip, mac, false)
|
|
}
|
|
}
|
|
|
|
// subscribe watches NDP table changes and update new information to local table.
|
|
func (nd *ndpDiscover) subscribe(ctx context.Context) {
|
|
ch := make(chan netlink.NeighUpdate)
|
|
done := make(chan struct{})
|
|
defer close(done)
|
|
if err := netlink.NeighSubscribe(ch, done); err != nil {
|
|
ctrld.ProxyLogger.Load().Err(err).Msg("could not perform neighbor subscribing")
|
|
return
|
|
}
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
return
|
|
case nu := <-ch:
|
|
if nu.Family != netlink.FAMILY_V6 {
|
|
continue
|
|
}
|
|
ip := normalizeIP(nu.IP.String())
|
|
if nu.Type == unix.RTM_DELNEIGH {
|
|
ctrld.ProxyLogger.Load().Debug().Msgf("removing NDP neighbor: %s", ip)
|
|
nd.mac.Delete(ip)
|
|
continue
|
|
}
|
|
mac := nu.HardwareAddr.String()
|
|
switch nu.State {
|
|
case netlink.NUD_REACHABLE:
|
|
nd.saveInfo(ip, mac, false)
|
|
case netlink.NUD_FAILED:
|
|
ctrld.ProxyLogger.Load().Debug().Msgf("removing NDP neighbor with failed state: %s", ip)
|
|
nd.mac.Delete(ip)
|
|
}
|
|
}
|
|
}
|
|
}
|