func (u *NetLinkProbe) getLinkIPV4Addr(link netlink.Link) string { var ipv4 []string addrs, err := netlink.AddrList(link, netlink.FAMILY_V4) if err != nil { return "" } for _, addr := range addrs { ipv4 = append(ipv4, addr.IPNet.String()) } j, _ := json.Marshal(ipv4) return string(j) }
// sets IP4 addr on link removing any existing ones first func setAddr4(link *netlink.Vxlan, ipn *net.IPNet) error { addrs, err := netlink.AddrList(link, syscall.AF_INET) if err != nil { return err } addr := netlink.Addr{ipn, ""} existing := false for _, old := range addrs { if old.IPNet.String() == addr.IPNet.String() { existing = true continue } if err = netlink.AddrDel(link, &old); err != nil { return fmt.Errorf("failed to delete IPv4 addr %s from %s", old.String(), link.Attrs().Name) } } if !existing { if err = netlink.AddrAdd(link, &addr); err != nil { return fmt.Errorf("failed to add IP address %s to %s: %s", ipn.String(), link.Attrs().Name, err) } } return nil }
// ElectInterfaceAddresses looks for an interface on the OS with the specified name // and returns its IPv4 and IPv6 addresses in CIDR form. If the interface does not exist, // it chooses from a predifined list the first IPv4 address which does not conflict // with other interfaces on the system. func ElectInterfaceAddresses(name string) (*net.IPNet, []*net.IPNet, error) { var ( v4Net *net.IPNet v6Nets []*net.IPNet err error ) link, _ := netlink.LinkByName(name) if link != nil { v4addr, err := netlink.AddrList(link, netlink.FAMILY_V4) if err != nil { return nil, nil, err } v6addr, err := netlink.AddrList(link, netlink.FAMILY_V6) if err != nil { return nil, nil, err } if len(v4addr) > 0 { v4Net = v4addr[0].IPNet } for _, nlAddr := range v6addr { v6Nets = append(v6Nets, nlAddr.IPNet) } } if link == nil || v4Net == nil { // Choose from predifined broad networks v4Net, err = FindAvailableNetwork(PredefinedBroadNetworks) if err != nil { return nil, nil, err } } return v4Net, v6Nets, nil }
func DetachContainer(ns netns.NsHandle, id, ifName string, cidrs []*net.IPNet) error { ipt, err := iptables.New() if err != nil { return err } return WithNetNSLinkUnsafe(ns, ifName, func(veth netlink.Link) error { existingAddrs, err := netlink.AddrList(veth, netlink.FAMILY_V4) if err != nil { return fmt.Errorf("failed to get IP address for %q: %v", veth.Attrs().Name, err) } for _, ipnet := range cidrs { if !contains(existingAddrs, ipnet) { continue } if err := netlink.AddrDel(veth, &netlink.Addr{IPNet: ipnet}); err != nil { return fmt.Errorf("failed to remove IP address from %q: %v", veth.Attrs().Name, err) } } addrs, err := netlink.AddrList(veth, netlink.FAMILY_V4) if err != nil { return fmt.Errorf("failed to get IP address for %q: %v", veth.Attrs().Name, err) } // Remove multicast ACCEPT rules for subnets we no longer have addresses in subnets := subnets(addrs) rules, err := ipt.List("filter", "INPUT") if err != nil { return err } for _, rule := range rules { ps := strings.Split(rule, " ") if len(ps) == 10 && ps[0] == "-A" && ps[2] == "-s" && ps[4] == "-d" && ps[5] == "224.0.0.0/4" && ps[6] == "-i" && ps[7] == ifName && ps[8] == "-j" && ps[9] == "ACCEPT" { if _, found := subnets[ps[3]]; !found { if err := ipt.Delete("filter", "INPUT", ps[2:]...); err != nil { return err } } } } if len(addrs) == 0 { // all addresses gone: remove the interface if err := ipt.Delete("filter", "INPUT", "-i", ifName, "-d", "224.0.0.0/4", "-j", "DROP"); err != nil { return err } if err := netlink.LinkDel(veth); err != nil { return err } } return nil }) }
func main() { lo, _ := netlink.LinkByName("lo") fmt.Println(lo) addr, _ := netlink.ParseAddr("127.0.0.2/8") fmt.Println(addr) netlink.AddrAdd(lo, addr) fmt.Println(netlink.AddrList(lo, netlink.FAMILY_ALL)) req := nl.NewNetlinkRequest(syscall.NLMSG_MIN_TYPE, syscall.NLM_F_REQUEST) data := append([]byte("TASKSTATS"), 0) a := &Attr{ Type: 2, Data: data, } Hdr := []byte{ 3, 0, 0, 0, } m := &Message{ Type: 16, Pid: -1, Seq: -1, Flags: NLM_F_REQUEST, Payload: append(Hdr, a.Dump()...), } req.AddData(m) res, _ := req.Execute(syscall.NETLINK_GENERIC, 0) fmt.Println(res) fmt.Println(parse_attributes(res[0][4:])[1]) }
func firstGlobalV4Addr(intf string) (net.IP, error) { var link netlink.Link var err error if intf != "" && intf != "undefined" { link, err = netlink.LinkByName(intf) if err != nil { return firstGlobalV4Addr("") } } addr, err := netlink.AddrList(link, netlink.FAMILY_V4) if err != nil { return nil, err } for _, a := range addr { if a.Scope == syscall.RT_SCOPE_UNIVERSE { if len(a.IP) < 4 { return nil, ErrIPv4Invalid } return a.IP, nil } } return nil, ErrIPv4NotConfigured }
// Detect and return host-side network configuration. func getNetConfig() (config *netConfig, err error) { eth0, err := netlink.LinkByName("eth0") if err != nil { return nil, fmt.Errorf("LinkByName(eth0): %v", err) } eth0Addrs, err := netlink.AddrList(eth0, syscall.AF_INET) if err != nil { return nil, fmt.Errorf("AddrList(eth0): %v", err) } if len(eth0Addrs) != 1 { return nil, fmt.Errorf("eth0: Expected single IPv4 address") } // TODO Is there a better way than relying on "8.8.8.8" being past // the default router? defaultroute, err := netlink.RouteGet(net.ParseIP("8.8.8.8")) if len(defaultroute) != 1 { return nil, fmt.Errorf("Could not determine single default route (got %v)", len(defaultroute)) } eth0Attrs := eth0.Attrs() dns := dnsReadConfig("/etc/resolv.conf") hostname, _ := os.Hostname() config = &netConfig{ hostname, eth0Addrs[0].IPNet.String(), defaultroute[0].Gw.String(), eth0Attrs.HardwareAddr.String(), dns.servers, dns.search, } return }
// addresses returns a single IPv4 address and all IPv6 addresses for the // bridge interface. func (i *bridgeInterface) addresses() (netlink.Addr, []netlink.Addr, error) { v4addr, err := netlink.AddrList(i.Link, netlink.FAMILY_V4) if err != nil { return netlink.Addr{}, nil, err } v6addr, err := netlink.AddrList(i.Link, netlink.FAMILY_V6) if err != nil { return netlink.Addr{}, nil, err } if len(v4addr) == 0 { return netlink.Addr{}, v6addr, nil } return v4addr[0], v6addr, nil }
// externalIP attempts to find an external IP to be reported as the guest IP func externalIP() string { l, err := netlink.LinkByName("client") if err != nil { log.Warnf("error looking up client interface by name: %s", err) l, err = netlink.LinkByAlias("client") if err != nil { log.Errorf("error looking up client interface by alias: %s", err) return "" } } addrs, err := netlink.AddrList(l, netlink.FAMILY_V4) if err != nil { log.Errorf("error getting address list for client interface: %s", err) return "" } if len(addrs) == 0 { log.Warnf("no addresses set on client interface") return "" } return addrs[0].IP.String() }
// GetNetlinkAddrList returns a list of local IP addresses func GetNetlinkAddrList() ([]string, error) { var addrList []string // get the link list linkList, err := netlink.LinkList() if err != nil { return addrList, err } log.Debugf("Got link list(%d): %+v", len(linkList), linkList) // Loop thru each interface and add its ip addr to list for _, link := range linkList { if strings.HasPrefix(link.Attrs().Name, "docker") || strings.HasPrefix(link.Attrs().Name, "veth") || strings.HasPrefix(link.Attrs().Name, "vport") || strings.HasPrefix(link.Attrs().Name, "lo") { continue } addrs, err := netlink.AddrList(link, netlink.FAMILY_V4) if err != nil { return addrList, err } for _, addr := range addrs { addrList = append(addrList, addr.IP.String()) } } return addrList, err }
func TestSetupBridgeIPv4Fixed(t *testing.T) { defer osl.SetupTestOSContext(t)() ip, netw, err := net.ParseCIDR("192.168.1.1/24") if err != nil { t.Fatalf("Failed to parse bridge IPv4: %v", err) } config, br := setupTestInterface(t) config.AddressIPv4 = &net.IPNet{IP: ip, Mask: netw.Mask} if err := setupBridgeIPv4(config, br); err != nil { t.Fatalf("Failed to setup bridge IPv4: %v", err) } addrsv4, err := netlink.AddrList(br.Link, netlink.FAMILY_V4) if err != nil { t.Fatalf("Failed to list device IPv4 addresses: %v", err) } var found bool for _, addr := range addrsv4 { if config.AddressIPv4.String() == addr.IPNet.String() { found = true break } } if !found { t.Fatalf("Bridge device does not have requested IPv4 address %v", config.AddressIPv4) } }
// Search the network namespace of a process for interfaces matching a predicate func FindNetDevs(procPath string, processID int, match func(string) bool) ([]NetDev, error) { var netDevs []NetDev ns, err := netns.GetFromPath(fmt.Sprintf("%s/%d/ns/net", procPath, processID)) if err != nil { return nil, err } defer ns.Close() err = WithNetNS(ns, func() error { links, err := netlink.LinkList() if err != nil { return err } for _, link := range links { if match(link.Attrs().Name) { addrs, err := netlink.AddrList(link, netlink.FAMILY_V4) if err != nil { return err } netDev := NetDev{MAC: link.Attrs().HardwareAddr} for _, addr := range addrs { netDev.CIDRs = append(netDev.CIDRs, addr.IPNet) } netDevs = append(netDevs, netDev) } } return nil }) return netDevs, err }
func ensureBridgeAddr(br *netlink.Bridge, ipn *net.IPNet, forceAddress bool) error { addrs, err := netlink.AddrList(br, syscall.AF_INET) if err != nil && err != syscall.ENOENT { return fmt.Errorf("could not get list of IP addresses: %v", err) } // if there're no addresses on the bridge, it's ok -- we'll add one if len(addrs) > 0 { ipnStr := ipn.String() for _, a := range addrs { // string comp is actually easiest for doing IPNet comps if a.IPNet.String() == ipnStr { return nil } // If forceAddress is set to true then reconfigure IP address otherwise throw error if forceAddress { if err = deleteBridgeAddr(br, a.IPNet); err != nil { return err } } else { return fmt.Errorf("%q already has an IP address different from %v", br.Name, ipn.String()) } } } addr := &netlink.Addr{IPNet: ipn, Label: ""} if err := netlink.AddrAdd(br, addr); err != nil { return fmt.Errorf("could not add IP address to %q: %v", br.Name, err) } return nil }
func TestSetupIPv6(t *testing.T) { defer netutils.SetupTestNetNS(t)() config, br := setupTestInterface(t) if err := setupBridgeIPv6(config, br); err != nil { t.Fatalf("Failed to setup bridge IPv6: %v", err) } procSetting, err := ioutil.ReadFile(fmt.Sprintf("/proc/sys/net/ipv6/conf/%s/disable_ipv6", config.BridgeName)) if err != nil { t.Fatalf("Failed to read disable_ipv6 kernel setting: %v", err) } if expected := []byte("0\n"); bytes.Compare(expected, procSetting) != 0 { t.Fatalf("Invalid kernel setting disable_ipv6: expected %q, got %q", string(expected), string(procSetting)) } addrsv6, err := netlink.AddrList(br.Link, netlink.FAMILY_V6) if err != nil { t.Fatalf("Failed to list device IPv6 addresses: %v", err) } var found bool for _, addr := range addrsv6 { if bridgeIPv6Str == addr.IPNet.String() { found = true break } } if !found { t.Fatalf("Bridge device does not have requested IPv6 address %v", bridgeIPv6Str) } }
// GetLocalIP obtains the first IP on a local interface on the host. func GetLocalIP() (string, error) { var addrs []netlink.Addr localIPAddr := "" for idx := 0; idx < 3; idx++ { linkName := "eth" + strconv.Itoa(idx) link, err := netlink.LinkByName(linkName) if err != nil { if strings.Contains(err.Error(), "Link not found") { continue } return "", err } addrs, err = netlink.AddrList(link, netlink.FAMILY_V4) if err != nil { if strings.Contains(err.Error(), "Link not found") { continue } return "", err } if len(addrs) > 0 { localIPAddr = addrs[0].IP.String() } } err := core.Errorf("local ip not found") if localIPAddr != "" { err = nil } return localIPAddr, err }
func getSource(dest net.IP) (net.IP, error) { var source net.IP routes, err := netlink.RouteList(nil, netlink.FAMILY_ALL) if err != nil { return nil, fmt.Errorf("Failed to get routes") } var link netlink.Link for _, route := range routes { if route.Dst == nil { link = &netlink.Dummy{netlink.LinkAttrs{Index: route.LinkIndex}} source = route.Src } else if route.Dst.Contains(dest) { link = &netlink.Dummy{netlink.LinkAttrs{Index: route.LinkIndex}} source = route.Src break } } if link == nil { return nil, fmt.Errorf("Failed to find route to target: %s", dest) } if source == nil { // no source in route to target so use the first ip from interface addrs, err := netlink.AddrList(link, netlink.FAMILY_ALL) if err != nil || len(addrs) == 0 { return nil, fmt.Errorf("Failed to find source ip for interface: %s", link) } source = addrs[0].IP } return source, nil }
func TestSetupBridgeIPv4Auto(t *testing.T) { defer osl.SetupTestOSContext(t)() config, br := setupTestInterface(t) if err := setupBridgeIPv4(config, br); err != nil { t.Fatalf("Failed to setup bridge IPv4: %v", err) } addrsv4, err := netlink.AddrList(br.Link, netlink.FAMILY_V4) if err != nil { t.Fatalf("Failed to list device IPv4 addresses: %v", err) } var found bool for _, addr := range addrsv4 { if bridgeNetworks[0].String() == addr.IPNet.String() { found = true break } } if !found { t.Fatalf("Bridge device does not have the automatic IPv4 address %v", bridgeNetworks[0].String()) } }
func GetVips(iface string) ([]netlink.Addr, error) { link, err := netlink.LinkByName(iface) if err != nil { return []netlink.Addr{}, err } return netlink.AddrList(link, netlink.FAMILY_V4) }
func getIfaceAddrs(iface *net.Interface) ([]netlink.Addr, error) { link := &netlink.Device{ netlink.LinkAttrs{ Index: iface.Index, }, } return netlink.AddrList(link, syscall.AF_INET) }
func linkToNetDev(link netlink.Link) (NetDev, error) { addrs, err := netlink.AddrList(link, netlink.FAMILY_V4) if err != nil { return NetDev{}, err } netDev := NetDev{Name: link.Attrs().Name, MAC: link.Attrs().HardwareAddr} for _, addr := range addrs { netDev.CIDRs = append(netDev.CIDRs, addr.IPNet) } return netDev, nil }
// Flush all L3 addresses on link. func flushAddresses(link netlink.Link) (err error) { addrs, err := netlink.AddrList(link, 0) if err != nil { return err } for _, addr := range addrs { if err = netlink.AddrDel(link, &addr); err != nil { return err } } return }
func externalIPv4Addrs() ([]netlink.Addr, error) { l, err := netlink.LinkByName(externalIfaceName) if err != nil { return nil, fmt.Errorf("Could not look up link from client interface name %s due to error %s", externalIfaceName, err.Error()) } ips, err := netlink.AddrList(l, netlink.FAMILY_V4) if err != nil { return nil, fmt.Errorf("Could not get IP addresses of link due to error %s", err.Error()) } return ips, nil }
func GetIpByInterface(iface string) (string, error) { link, err := netlink.LinkByName(iface) if err != nil { return "", err } addrs, err := netlink.AddrList(link, netlink.FAMILY_V4) if err != nil { return "", err } return addrs[0].IP.String(), nil }
func NewDriver(config *Config) (*driver, error) { link, err := netlink.LinkByName(config.Interface) if err != nil { return nil, err } addrs, err := netlink.AddrList(link, netlink.FAMILY_ALL) if err != nil { return nil, err } // If no subnet was configured on the command line, take the first one // from the host interface if len(config.Subnet) == 0 { config.Subnet = addrs[0].IPNet.String() Debug.Printf("using interface subnet %s\n", config.Subnet) if len(config.Gateway) == 0 { routes, err := netlink.RouteList(link, netlink.FAMILY_ALL) if err != nil { return nil, err } for _, route := range routes { if route.Dst == nil { config.Gateway = route.Gw.String() Debug.Printf("using gateway %s\n", config.Gateway) } } if len(config.Gateway) == 0 { return nil, fmt.Errorf("cannot autoselect default gateway") } } } ip, ipnet, err := net.ParseCIDR(config.Subnet) if err != nil { return nil, err } d := &driver{ config: config, ip: ip, ipnet: ipnet, hostLink: link, interfaces: make(map[string][]net.IP), } return d, nil }
// Do post-attach configuration of all veths we have created func ConfigureARPforVeths(processID int, prefix string) error { _, err := FindNetDevs(processID, func(link netlink.Link) bool { ifName := link.Attrs().Name if strings.HasPrefix(ifName, prefix) { weavenet.ConfigureARPCache(ifName) if addrs, err := netlink.AddrList(link, netlink.FAMILY_V4); err == nil { for _, addr := range addrs { arping.GratuitousArpOverIfaceByName(addr.IPNet.IP, ifName) } } } return false }) return err }
func AddAddresses(link netlink.Link, cidrs []*net.IPNet) (newAddrs []*net.IPNet, err error) { existingAddrs, err := netlink.AddrList(link, netlink.FAMILY_V4) if err != nil { return nil, fmt.Errorf("failed to get IP address for %q: %v", link.Attrs().Name, err) } for _, ipnet := range cidrs { if contains(existingAddrs, ipnet) { continue } if err := netlink.AddrAdd(link, &netlink.Addr{IPNet: ipnet}); err != nil { return nil, fmt.Errorf("failed to add IP address to %q: %v", link.Attrs().Name, err) } newAddrs = append(newAddrs, ipnet) } return newAddrs, nil }
// getIfaceAddr returns the IPv4 address of a network interface. func getIfaceAddr(name string) (*net.IPNet, error) { iface, err := netlink.LinkByName(name) if err != nil { return nil, err } addrs, err := netlink.AddrList(iface, netlink.FAMILY_V4) if err != nil { return nil, err } if len(addrs) == 0 { return nil, fmt.Errorf("Interface %s has no IP addresses", name) } if len(addrs) > 1 { logrus.Infof("Interface [ %#v ] has more than 1 IPv4 address. Defaulting to using [ %#v ]\n", name, addrs[0].IP) } return addrs[0].IPNet, nil }
// DelLinkByNameAddr remove an interface returns its IP address // of the specified family func DelLinkByNameAddr(ifName string, family int) (*net.IPNet, error) { iface, err := netlink.LinkByName(ifName) if err != nil { return nil, fmt.Errorf("failed to lookup %q: %v", ifName, err) } addrs, err := netlink.AddrList(iface, family) if err != nil || len(addrs) == 0 { return nil, fmt.Errorf("failed to get IP addresses for %q: %v", ifName, err) } if err = netlink.LinkDel(iface); err != nil { return nil, fmt.Errorf("failed to delete %q: %v", ifName, err) } return addrs[0].IPNet, nil }
// Returns a list of devices and addresses ("ip addr show") func AddrMap() (*map[string][]string, *map[string]string) { addrs, _ := netlink.AddrList(nil, netlink.FAMILY_V4) devMap := make(map[string][]string) addrMap := make(map[string]string) for _, a := range addrs { addr := a.IP.String() dev := a.Label l, ok := devMap[dev] if ok { devMap[dev] = append(l, addr) } else { devMap[dev] = []string{addr} } addrMap[addr] = dev } return &devMap, &addrMap }
func (plugin *kubenetNetworkPlugin) clearBridgeAddressesExcept(keep string) { bridge, err := netlink.LinkByName(BridgeName) if err != nil { return } addrs, err := netlink.AddrList(bridge, syscall.AF_INET) if err != nil { return } for _, addr := range addrs { if addr.IPNet.String() != keep { glog.V(5).Infof("Removing old address %s from %s", addr.IPNet.String(), BridgeName) netlink.AddrDel(bridge, &addr) } } }