package lb import ( "fmt" "net" "sort" "strings" "github.com/vishvananda/netlink" "golang.org/x/sys/unix" ) // Local is what this node publishes about itself, read from its interfaces. type Local struct { Addresses []net.IP WeaveIP net.IP WeaveMAC net.HardwareAddr PodNet *net.IPNet // the weave allocation range: the bridge address's network } // overlay- and container-side interfaces: their addresses are never held ones var overlayPrefixes = []string{"weave", "datapath", "vxlan-", "veth", "docker", "cni"} func overlay(name string) bool { for _, p := range overlayPrefixes { if strings.HasPrefix(name, p) { return true } } return false } // ReadLocal lists the global IPv4 addresses on host interfaces, and the weave bridge's address and MAC. func ReadLocal() (Local, error) { var l Local links, err := netlink.LinkList() if err != nil { return l, err } for _, link := range links { name := link.Attrs().Name addrs, err := netlink.AddrList(link, unix.AF_INET) if err != nil { return l, fmt.Errorf("%s: %v", name, err) } if name == bridge { for _, a := range addrs { if a.IPNet != nil && a.IP.To4() != nil { l.WeaveIP = a.IP.To4() l.WeaveMAC = link.Attrs().HardwareAddr l.PodNet = &net.IPNet{IP: a.IP.Mask(a.Mask), Mask: a.Mask} break } } continue } if overlay(name) || link.Attrs().Flags&net.FlagLoopback != 0 { continue } for _, a := range addrs { if a.Scope == unix.RT_SCOPE_UNIVERSE && a.IP.To4() != nil && a.IP.IsGlobalUnicast() { l.Addresses = append(l.Addresses, a.IP.To4()) } } } // an address inside the pod network is never a host one (whatever interface it is on) if l.PodNet != nil { kept := l.Addresses[:0] for _, ip := range l.Addresses { if !l.PodNet.Contains(ip) { kept = append(kept, ip) } } l.Addresses = kept } sort.Slice(l.Addresses, func(i, j int) bool { return l.Addresses[i].String() < l.Addresses[j].String() }) return l, nil } // Annotations is what this node's Node object should carry for l. func (l Local) Annotations() map[string]string { a := map[string]string{AnnAddresses: FormatAddresses(l.Addresses)} if l.WeaveIP != nil && l.WeaveMAC != nil { a[AnnWeave] = l.WeaveIP.String() + "," + l.WeaveMAC.String() } return a }