func setIfNs(ifname string, pid int) error { link, err := netlink.LinkByName(ifname) if err != nil { if !strings.Contains(err.Error(), "Link not found") { log.Errorf("unable to find link %q. Error: %q", ifname, err) return err } // try once more as sometimes (somehow) link creation is taking // sometime, causing link not found error time.Sleep(1 * time.Second) link, err = netlink.LinkByName(ifname) if err != nil { log.Errorf("unable to find link %q. Error %q", ifname, err) return err } } err = netlink.LinkSetNsPid(link, pid) if err != nil { log.Errorf("unable to move interface '%s' to pid %d. Error: %s", ifname, pid, err) } return err }
/* SetupNetwork() */ func SetupNetwork(addr string) error { // Bring up loop back interface. lo, e := netlink.LinkByName("lo") if e != nil { return fmt.Errorf("Failed to find loopback interface: %v", e) } if e := netlink.LinkSetUp(lo); e != nil { return fmt.Errorf("Failed to setup loopback interface: %v", e) } if len(addr) > 0 { veth, e := netlink.LinkByName("veth0") if e != nil { return fmt.Errorf("Failed to find veth interface: %v", e) } addr, e := netlink.ParseAddr(addr) if e != nil { return fmt.Errorf("Failed to parse NetworkAddr: %v", e) } netlink.AddrAdd(veth, addr) if e := netlink.LinkSetUp(veth); e != nil { return fmt.Errorf("Network link failed to come up: %v", e) } } return nil }
func checkSandbox(t *testing.T, info libnetwork.EndpointInfo) { origns, err := netns.Get() if err != nil { t.Fatalf("Could not get the current netns: %v", err) } defer origns.Close() key := info.Sandbox().Key() f, err := os.OpenFile(key, os.O_RDONLY, 0) if err != nil { t.Fatalf("Failed to open network namespace path %q: %v", key, err) } defer f.Close() runtime.LockOSThread() defer runtime.UnlockOSThread() nsFD := f.Fd() if err = netns.Set(netns.NsHandle(nsFD)); err != nil { t.Fatalf("Setting to the namespace pointed to by the sandbox %s failed: %v", key, err) } defer netns.Set(origns) _, err = netlink.LinkByName("eth0") if err != nil { t.Fatalf("Could not find the interface eth0 inside the sandbox: %v", err) } _, err = netlink.LinkByName("eth1") if err != nil { t.Fatalf("Could not find the interface eth1 inside the sandbox: %v", err) } }
// Set the IP addr of a netlink interface func (driver *driver) setInterfaceIP(name string, rawIP string) error { var netlinkRetryTimer time.Duration netlinkRetryTimer = 2 iface, err := netlink.LinkByName(name) if err != nil { log.Debugf("error retrieving new OVS bridge netlink link [ %s ] allowing another [ %d ] seconds for the host to finish creating it..", bridgeName, netlinkRetryTimer) time.Sleep(netlinkRetryTimer * time.Second) iface, err = netlink.LinkByName(name) if err != nil { log.Debugf("error retrieving new OVS bridge netlink link [ %s ] allowing another [ %d ] seconds for the host to finish creating it..", bridgeName, netlinkRetryTimer) time.Sleep(netlinkRetryTimer * time.Second) iface, err = netlink.LinkByName(name) if err != nil { log.Fatalf("Abandoning retrieving the new OVS bridge link from netlink, Run [ ip link ] to troubleshoot the error: %s", err) return err } } } ipNet, err := netlink.ParseIPNet(rawIP) if err != nil { return err } addr := &netlink.Addr{ipNet, ""} return netlink.AddrAdd(iface, addr) }
func (d *OvsDriver) getIntfName() (string, error) { // take a lock for modifying shared state d.lock.Lock() defer d.lock.Unlock() // get the next available port number for i := 0; i < maxIntfRetry; i++ { // Pick next port number d.oper.CurrPortNum++ if d.oper.CurrPortNum >= maxPortNum { d.oper.CurrPortNum = 0 // roll over } intfName := fmt.Sprintf("vport%d", d.oper.CurrPortNum) ovsIntfName := getOvsPortName(intfName, false) // check if the port name is already in use _, err := netlink.LinkByName(intfName) _, err2 := netlink.LinkByName(ovsIntfName) if err != nil && strings.Contains(err.Error(), "not found") && err2 != nil && strings.Contains(err2.Error(), "not found") { // save the new state err = d.oper.Write() if err != nil { return "", err } return intfName, nil } } return "", core.Errorf("Could not get intf name. Max retry exceeded") }
func (e *Endpoint) makeIface(network *Network, netns string) error { if vethLink, _ := netlink.LinkByName("veth" + e.EndpointShortID); vethLink != nil { log.Println("veth"+e.EndpointShortID, "already exist") } else { ethLink, err := netlink.LinkByName(network.Eth) if err != nil { fmt.Println("[Err] LinkByName:", err) return err } attrs := netlink.NewLinkAttrs() attrs.Name = "veth" + e.EndpointShortID attrs.ParentIndex = ethLink.Attrs().Index vlan := &netlink.Vlan{ attrs, network.VLanID, } if err := netlink.LinkAdd(vlan); err != nil { log.Println("Err: ", err, "LinkAdd") return err } } if err := exec.Command("ip", "link", "set", "veth"+e.EndpointShortID, "netns", netns).Run(); err != nil { log.Println("Err: ", err, "LinkSet NS") return err } return nil }
// attach a container network interface to an external network func (v *veth) attach(n *configs.Network) (err error) { brl, err := netlink.LinkByName(n.Bridge) if err != nil { return err } br, ok := brl.(*netlink.Bridge) if !ok { return fmt.Errorf("Wrong device type %T", brl) } host, err := netlink.LinkByName(n.HostInterfaceName) if err != nil { return err } if err := netlink.LinkSetMaster(host, br); err != nil { return err } if err := netlink.LinkSetMTU(host, n.Mtu); err != nil { return err } if n.HairpinMode { if err := netlink.LinkSetHairpin(host, true); err != nil { return err } } if err := netlink.LinkSetUp(host); err != nil { return err } return nil }
// Remove routes with netlink syscalls with a scope of: // RT_SCOPE_LINK = 0xfd (253) // RT_SCOPE_UNIVERSE = 0x0 (0) func cleanExistingRoutes(ifaceStr string) error { iface, err := netlink.LinkByName(ifaceStr) ipvlanParentIface, err := netlink.LinkByName(ifaceStr) if err != nil { log.Errorf("Error occoured finding the linux link [ %s ] from netlink: %s", ipvlanParentIface.Attrs().Name, err) return err } routes, err := netlink.RouteList(iface, netlink.FAMILY_V4) if err != nil { log.Errorf("Unable to retreive netlink routes: %s", err) return err } ifaceIP, err := getIfaceIP(ifaceStr) if err != nil { log.Errorf("Unable to retreive a usable IP via ethernet interface: %s", ifaceStr) return err } for _, route := range routes { if netOverlaps(ifaceIP, route.Dst) == true { log.Warnf("Ignoring route [ %v ] as it is associated to the [ %s ] interface", ifaceIP, ifaceStr) } else if route.Scope == 0x0 || route.Scope == 0xfd { // Remove link and universal routes from the docker host ipvlan interface log.Infof("Cleaning static route cache for the destination: [ %s ]", route.Dst) err := delRoute(route, ipvlanParentIface) if err != nil { log.Errorf("Error deleting static route cache for Destination: [ %s ] and Nexthop [ %s ] Error: %s", route.Dst, route.Gw, err) } } } return nil }
// create and attach a veth to the Weave bridge func CreateAndAttachVeth(name, peerName, bridgeName string, mtu int, keepTXOn bool, init func(peer netlink.Link) error) (*netlink.Veth, error) { bridge, err := netlink.LinkByName(bridgeName) if err != nil { return nil, fmt.Errorf(`bridge "%s" not present; did you launch weave?`, bridgeName) } if mtu == 0 { mtu = bridge.Attrs().MTU } veth := &netlink.Veth{ LinkAttrs: netlink.LinkAttrs{ Name: name, MTU: mtu}, PeerName: peerName, } if err := netlink.LinkAdd(veth); err != nil { return nil, fmt.Errorf(`could not create veth pair %s-%s: %s`, name, peerName, err) } cleanup := func(format string, a ...interface{}) (*netlink.Veth, error) { netlink.LinkDel(veth) return nil, fmt.Errorf(format, a...) } switch bridgeType := DetectBridgeType(bridgeName, DatapathName); bridgeType { case Bridge, BridgedFastdp: if err := netlink.LinkSetMasterByIndex(veth, bridge.Attrs().Index); err != nil { return cleanup(`unable to set master of %s: %s`, name, err) } if bridgeType == Bridge && !keepTXOn { if err := EthtoolTXOff(peerName); err != nil { return cleanup(`unable to set tx off on %q: %s`, peerName, err) } } case Fastdp: if err := odp.AddDatapathInterface(bridgeName, name); err != nil { return cleanup(`failed to attach %s to device "%s": %s`, name, bridgeName, err) } default: return cleanup(`invalid bridge configuration`) } if init != nil { peer, err := netlink.LinkByName(peerName) if err != nil { return cleanup("unable to find peer veth %s: %s", peerName, err) } if err := init(peer); err != nil { return cleanup("initializing veth: %s", err) } } if err := netlink.LinkSetUp(veth); err != nil { return cleanup("unable to bring veth up: %s", err) } return veth, nil }
func (driver *driver) createNetwork(w http.ResponseWriter, r *http.Request) { var create networkCreate err := json.NewDecoder(r.Body).Decode(&create) if err != nil { sendError(w, "Unable to decode JSON payload: "+err.Error(), http.StatusBadRequest) return } if driver.network != "" { errorResponsef(w, "You get just one network, and you already made %s", driver.network) return } driver.network = create.NetworkID containerCidr := driver.pluginConfig.containerSubnet driver.cidr = containerCidr // Todo: check for ipam errors driver.ipAllocator.RequestIP(containerCidr, nil) emptyResponse(w) // TODO: sort out what rules are in place by default vs. plugin err = driver.natOut() if err != nil { log.Warnf("error setting up outboud nat: %s", err) } if ipVlanMode == ipVlanL3 { log.Debugf("Adding route for the local ipvlan subnet [ %s ] in the default namespace using the specified host interface [ %s]", containerCidr.String(), ipVlanEthIface) ipvlanParent, err := netlink.LinkByName(ipVlanEthIface) // Add a route in the default NS to point to the IPVlan namespace subnet addRouteIface(containerCidr, ipvlanParent) if err != nil { log.Debugf("a problem occurred adding the container subnet default namespace route", err) } } else if ipVlanMode == ipVlanL3Routing { log.Debugf("Adding route for the local ipvlan subnet [ %s ] in the default namespace using the specified host interface [ %s]", containerCidr.String(), ipVlanEthIface) ipvlanParent, err := netlink.LinkByName(ipVlanEthIface) // Add a route in the default NS to point to the IPVlan namespace subnet addRouteIface(containerCidr, ipvlanParent) if err != nil { log.Debugf("a problem occurred adding the container subnet default namespace route", err) } // Announce the local IPVLAN network to the other peers in the BGP cluster log.Infof("New Docker network: [ %s ]", containerCidr.String()) err = routing.AdvertizeNewRoute(containerCidr) if err != nil { log.Fatalf("Error installing container route : %s", err) } } }
func (Bridge) Add(bridge, slaveIf *net.Interface) error { netlinkMu.Lock() defer netlinkMu.Unlock() master, err := netlink.LinkByName(bridge.Name) if err != nil { return err } slave, err := netlink.LinkByName(slaveIf.Name) if err != nil { return err } return netlink.LinkSetMaster(slave, master.(*netlink.Bridge)) }
// Remove default bridge interface if present (--bridge=none use case) func removeDefaultBridgeInterface() { if lnk, err := netlink.LinkByName(bridge.DefaultBridgeName); err == nil { if err := netlink.LinkDel(lnk); err != nil { logrus.Warnf("Failed to remove bridge interface (%s): %v", bridge.DefaultBridgeName, err) } } }
func setupRoute(config *configs.Config) error { for _, config := range config.Routes { _, dst, err := net.ParseCIDR(config.Destination) if err != nil { return err } src := net.ParseIP(config.Source) if src == nil { return fmt.Errorf("Invalid source for route: %s", config.Source) } gw := net.ParseIP(config.Gateway) if gw == nil { return fmt.Errorf("Invalid gateway for route: %s", config.Gateway) } l, err := netlink.LinkByName(config.InterfaceName) if err != nil { return err } route := &netlink.Route{ Scope: netlink.SCOPE_UNIVERSE, Dst: dst, Src: src, Gw: gw, LinkIndex: l.Attrs().Index, } if err := netlink.RouteAdd(route); err != nil { return err } } return nil }
func (b *Bridge) setupBridge(externalPort string) error { la := netlink.NewLinkAttrs() la.Name = b.bridgeName bridge, _ := netlink.LinkByName(b.bridgeName) if bridge == nil { log.Debugf("Bridge %s does not exist ", b.bridgeName) out, err := exec.Command("ovs-vsctl", "add-br", b.bridgeName).CombinedOutput() if err != nil { log.Fatalf("Bridge %s creation failed been created. Resp: %s, err: %s", b.bridgeName, out, err) } log.Infof("Bridge %s has been created. Resp: %s", b.bridgeName, out) out, err = exec.Command("ovs-vsctl", "add-port", b.bridgeName, externalPort).CombinedOutput() if err != nil { log.Fatalf("Failed to add external port %s. Resp: %s, err: %s", externalPort, out, err) } log.Infof("External port %s has been added to %s. Resp: %s", externalPort, b.bridgeName, out) out, err = exec.Command("ifconfig", externalPort, "0.0.0.0").CombinedOutput() if err != nil { log.Fatalf("Failed to ip address of port %s. Resp: %s, err: %s", externalPort, out, err) } log.Infof("Ip address of port %s has been cleaned. Resp: %s", externalPort, out) return err } else { log.Debugf("Bridge %s already exsist", b.bridgeName) } return nil }
// setLinkUp sets the link up func setLinkUp(name string) error { iface, err := netlink.LinkByName(name) if err != nil { return err } return netlink.LinkSetUp(iface) }
func (v *veth) create(n *network, nspid int) (err error) { tmpName, err := v.generateTempPeerName() if err != nil { return err } n.TempVethPeerName = tmpName if n.Bridge == "" { return fmt.Errorf("bridge is not specified") } veth := &netlink.Veth{ LinkAttrs: netlink.LinkAttrs{ Name: n.HostInterfaceName, TxQLen: n.TxQueueLen, }, PeerName: n.TempVethPeerName, } if err := netlink.LinkAdd(veth); err != nil { return err } defer func() { if err != nil { netlink.LinkDel(veth) } }() if err := v.attach(&n.Network); err != nil { return err } child, err := netlink.LinkByName(n.TempVethPeerName) if err != nil { return err } return netlink.LinkSetNsPid(child, nspid) }
// Create the macvlan slave specifying the source name func createMacVlan(containerIfName, parent, macvlanMode string) (string, error) { // Set the macvlan mode. Default is bridge mode mode, err := setMacVlanMode(macvlanMode) if err != nil { return "", fmt.Errorf("Unsupported %s macvlan mode: %v", macvlanMode, err) } // verify the Docker host interface acting as the macvlan parent iface exists if !parentExists(parent) { return "", fmt.Errorf("the requested parent interface %s was not found on the Docker host", parent) } // Get the link for the master index (Example: the docker host eth iface) parentLink, err := netlink.LinkByName(parent) if err != nil { return "", fmt.Errorf("error occoured looking up the %s parent iface %s error: %s", macvlanType, parent, err) } // Create a macvlan link macvlan := &netlink.Macvlan{ LinkAttrs: netlink.LinkAttrs{ Name: containerIfName, ParentIndex: parentLink.Attrs().Index, }, Mode: mode, } if err := netlink.LinkAdd(macvlan); err != nil { // If a user creates a macvlan and ipvlan on same parent, only one slave iface can be active at a time. return "", fmt.Errorf("failed to create the %s port: %v", macvlanType, err) } return macvlan.Attrs().Name, nil }
// 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 }
func (adapter *HostAdapter) AcquireInterface(name string) (uint, error) { link, err := netlink.LinkByName(name) if err != nil { return 0, err } return uint(link.Attrs().Index), nil }
// Set the link mtu func setLinkMtu(name string, mtu int) error { iface, err := netlink.LinkByName(name) if err != nil { return err } return netlink.LinkSetMTU(iface, mtu) }
// ensureBridgeTxQueueLen() ensures that the bridge interface's TX queue // length is greater than zero. Due to a CNI <= 0.3.0 'bridge' plugin bug, // the bridge is initially created with a TX queue length of 0, which gets // used as the packet limit for FIFO traffic shapers, which drops packets. // TODO: remove when we can depend on a fixed CNI func (plugin *kubenetNetworkPlugin) ensureBridgeTxQueueLen() { bridge, err := netlink.LinkByName(BridgeName) if err != nil { return } if bridge.Attrs().TxQLen > 0 { return } req := nl.NewNetlinkRequest(syscall.RTM_NEWLINK, syscall.NLM_F_ACK) msg := nl.NewIfInfomsg(syscall.AF_UNSPEC) req.AddData(msg) nameData := nl.NewRtAttr(syscall.IFLA_IFNAME, nl.ZeroTerminated(BridgeName)) req.AddData(nameData) qlen := nl.NewRtAttr(syscall.IFLA_TXQLEN, nl.Uint32Attr(1000)) req.AddData(qlen) _, err = req.Execute(syscall.NETLINK_ROUTE, 0) if err != nil { glog.V(5).Infof("Failed to set bridge tx queue length: %v", err) } }
func (driver *driver) deleteEndpoint(w http.ResponseWriter, r *http.Request) { var delete endpointDelete if err := json.NewDecoder(r.Body).Decode(&delete); err != nil { sendError(w, "Could not decode JSON encode payload", http.StatusBadRequest) return } log.Debugf("Delete endpoint request: %+v", &delete) emptyResponse(w) log.Debugf("Delete endpoint %s", delete.EndpointID) containerLink := delete.EndpointID[:5] // Check the interface to delete exists to avoid a panic if nil if ok := validateHostIface(containerLink); !ok { log.Errorf("The requested interface to delete [ %s ] was not found on the host.", containerLink) return } // Get the link handle link, err := netlink.LinkByName(containerLink) if err != nil { log.Errorf("Error looking up link [ %s ] object: [ %v ] error: [ %s ]", link.Attrs().Name, link, err) return } log.Infof("Deleting the unused ipvlan link [ %s ] from the removed container", link.Attrs().Name) // Delete the link if err := netlink.LinkDel(link); err != nil { log.Errorf("Unable to delete the ipvlan link named [ %s ] for the exiting container: %s", link.Attrs().Name, err) } }
// ConfigureIface takes the result of IPAM plugin and // applies to the ifName interface func ConfigureIface(ifName string, res *types.Result) error { link, err := netlink.LinkByName(ifName) if err != nil { return fmt.Errorf("failed to lookup %q: %v", ifName, err) } if err := netlink.LinkSetUp(link); err != nil { return fmt.Errorf("failed to set %q UP: %v", ifName, err) } // TODO(eyakubovich): IPv6 addr := &netlink.Addr{IPNet: &res.IP4.IP, Label: ""} if err = netlink.AddrAdd(link, addr); err != nil { return fmt.Errorf("failed to add IP addr to %q: %v", ifName, err) } for _, r := range res.IP4.Routes { gw := r.GW if gw == nil { gw = res.IP4.Gateway } if err = ip.AddRoute(&r.Dst, gw, link); err != nil { // we skip over duplicate routes as we assume the first one wins if !os.IsExist(err) { return fmt.Errorf("failed to add route '%v via %v dev %v': %v", r.Dst, gw, ifName, err) } } } return nil }
func setupHostVeth(vethName string, ipConf *types.IPConfig) error { // hostVeth moved namespaces and may have a new ifindex veth, err := netlink.LinkByName(vethName) if err != nil { return fmt.Errorf("failed to lookup %q: %v", vethName, err) } // TODO(eyakubovich): IPv6 ipn := &net.IPNet{ IP: ipConf.Gateway, Mask: net.CIDRMask(32, 32), } addr := &netlink.Addr{IPNet: ipn, Label: ""} if err = netlink.AddrAdd(veth, addr); err != nil { return fmt.Errorf("failed to add IP addr (%#v) to veth: %v", ipn, err) } ipn = &net.IPNet{ IP: ipConf.IP.IP, Mask: net.CIDRMask(32, 32), } // dst happens to be the same as IP/net of host veth if err = ip.AddHostRoute(ipn, nil, veth); err != nil && !os.IsExist(err) { return fmt.Errorf("failed to add route on host: %v", err) } return nil }
// delVlanLink verifies only sub-interfaces with a vlan id get deleted func delVlanLink(linkName string) error { if strings.Contains(linkName, ".") { _, _, err := parseVlan(linkName) if err != nil { return err } // delete the vlan subinterface vlanLink, err := netlink.LinkByName(linkName) if err != nil { return fmt.Errorf("failed to find interface %s on the Docker host : %v", linkName, err) } // verify a parent interface isn't being deleted if vlanLink.Attrs().ParentIndex == 0 { return fmt.Errorf("interface %s does not appear to be a slave device: %v", linkName, err) } // delete the macvlan slave device if err := netlink.LinkDel(vlanLink); err != nil { return fmt.Errorf("failed to delete %s link: %v", linkName, err) } logrus.Debugf("Deleted a vlan tagged netlink subinterface: %s", linkName) } // if the subinterface doesn't parse to iface.vlan_id leave the interface in // place since it could be a user specified name not created by the driver. return nil }
func setupVeth(netns string, br *netlink.Bridge, ifName string, mtu int, hairpinMode bool) error { var hostVethName string err := ns.WithNetNSPath(netns, false, func(hostNS *os.File) error { // create the veth pair in the container and move host end into host netns hostVeth, _, err := ip.SetupVeth(ifName, mtu, hostNS) if err != nil { return err } hostVethName = hostVeth.Attrs().Name return nil }) if err != nil { return err } // need to lookup hostVeth again as its index has changed during ns move hostVeth, err := netlink.LinkByName(hostVethName) if err != nil { return fmt.Errorf("failed to lookup %q: %v", hostVethName, err) } // connect host veth end to the bridge if err = netlink.LinkSetMaster(hostVeth, br); err != nil { return fmt.Errorf("failed to connect %q to bridge %v: %v", hostVethName, br.Attrs().Name, err) } // set hairpin mode if err = netlink.LinkSetHairpin(hostVeth, hairpinMode); err != nil { return fmt.Errorf("failed to setup hairpin mode for %v: %v", hostVethName, err) } return nil }
func verifySandbox(t *testing.T, s Sandbox, ifaceSuffixes []string) { _, ok := s.(*networkNamespace) if !ok { t.Fatalf("The sandox interface returned is not of type networkNamespace") } origns, err := netns.Get() if err != nil { t.Fatalf("Could not get the current netns: %v", err) } defer origns.Close() f, err := os.OpenFile(s.Key(), os.O_RDONLY, 0) if err != nil { t.Fatalf("Failed top open network namespace path %q: %v", s.Key(), err) } defer f.Close() runtime.LockOSThread() defer runtime.UnlockOSThread() nsFD := f.Fd() if err = netns.Set(netns.NsHandle(nsFD)); err != nil { t.Fatalf("Setting to the namespace pointed to by the sandbox %s failed: %v", s.Key(), err) } defer netns.Set(origns) for _, suffix := range ifaceSuffixes { _, err = netlink.LinkByName(sboxIfaceName + suffix) if err != nil { t.Fatalf("Could not find the interface %s inside the sandbox: %v", sboxIfaceName+suffix, err) } } }
// 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() }
func loopbackUp() error { iface, err := netlink.LinkByName("lo") if err != nil { return err } return netlink.LinkSetUp(iface) }
// 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 }