Beispiel #1
0
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
}
Beispiel #2
0
/*   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)
}
Beispiel #5
0
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
}
Beispiel #9
0
// 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)
		}
	}
}
Beispiel #11
0
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))
}
Beispiel #12
0
// 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)
		}
	}
}
Beispiel #13
0
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
}
Beispiel #14
0
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
}
Beispiel #15
0
// 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)
}
Beispiel #17
0
// 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
}
Beispiel #18
0
// 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
}
Beispiel #19
0
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
}
Beispiel #20
0
// 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)
	}
}
Beispiel #23
0
// 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
}
Beispiel #24
0
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
}
Beispiel #25
0
// 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
}
Beispiel #26
0
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
}
Beispiel #27
0
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)
		}
	}
}
Beispiel #28
0
// 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)
}
Beispiel #30
0
// 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
}