nicfinder.go 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. package nicfinder
  2. import (
  3. "context"
  4. "log/slog"
  5. "net"
  6. "net/netip"
  7. "github.com/slackhq/nebula/logging"
  8. )
  9. // Filter decides which interfaces, by name, and which of their addresses Find returns.
  10. type Filter interface {
  11. AllowName(string) bool
  12. Allow(netip.Addr) bool
  13. }
  14. // Find returns the addresses of this host's network interfaces that allowList accepts, with
  15. // loopback and link-local addresses left out. When only some interfaces could be read it returns
  16. // their addresses alongside an error for the rest. allowList must not be nil; it is called as
  17. // given, so a nil pointer of a type whose methods accept a nil receiver is fine.
  18. func Find(ctx context.Context, l *slog.Logger, allowList Filter) ([]netip.Addr, error) {
  19. return localAddrs(ctx, l, allowList)
  20. }
  21. // allowName asks filter about an interface name and traces the answer.
  22. func allowName(ctx context.Context, l *slog.Logger, filter Filter, name string) bool {
  23. allow := filter.AllowName(name)
  24. if l.Enabled(ctx, logging.LevelTrace) {
  25. l.Log(ctx, logging.LevelTrace, "localAllowList.AllowName", "interfaceName", name, "allow", allow)
  26. }
  27. return allow
  28. }
  29. // allowedAddr converts one address a platform reports and says whether to advertise it: it must
  30. // be a *net.IPNet or *net.IPAddr carrying an IP, not be loopback or link-local, and be accepted by
  31. // filter, whose answer is traced. IPv4 comes back unmapped.
  32. func allowedAddr(ctx context.Context, l *slog.Logger, filter Filter, rawAddr net.Addr) (netip.Addr, bool) {
  33. var ip net.IP
  34. switch v := rawAddr.(type) {
  35. case *net.IPNet:
  36. ip = v.IP
  37. case *net.IPAddr:
  38. ip = v.IP
  39. }
  40. addr, ok := netip.AddrFromSlice(ip)
  41. if !ok {
  42. return netip.Addr{}, false
  43. }
  44. addr = addr.Unmap()
  45. if addr.IsLoopback() || addr.IsLinkLocalUnicast() {
  46. return netip.Addr{}, false
  47. }
  48. isAllowed := filter.Allow(addr)
  49. if l.Enabled(ctx, logging.LevelTrace) {
  50. l.Log(ctx, logging.LevelTrace, "localAllowList.Allow", "localAddr", addr, "allowed", isAllowed)
  51. }
  52. return addr, isAllowed
  53. }