Beispiel #1
0
func releaseVF(conf *NetConf, ifName string, initns ns.NetNS) error {
	// get VF device
	vfDev, err := netlink.LinkByName(ifName)
	if err != nil {
		return fmt.Errorf("failed to lookup vf %d device %q: %v", conf.VF, ifName, err)
	}

	// device name in init netns
	index := vfDev.Attrs().Index
	devName := fmt.Sprintf("dev%d", index)

	// shutdown VF device
	if err = netlink.LinkSetDown(vfDev); err != nil {
		return fmt.Errorf("failed to down vf % device: %v", conf.VF, err)
	}

	// rename VF device
	err = renameLink(ifName, devName)
	if err != nil {
		return fmt.Errorf("failed to rename vf %d evice %q to %q: %v", conf.VF, ifName, devName, err)
	}

	// move VF device to init netns
	if err = netlink.LinkSetNsFd(vfDev, int(initns.Fd())); err != nil {
		return fmt.Errorf("failed to move vf %d to init netns: %v", conf.VF, err)
	}

	return nil
}
Beispiel #2
0
func (b *Bonding) AddSlave(slave string) {
	if b.err != nil {
		return
	}

	if ok, err := contains(base+b.name+"/bonding/slaves", slave); err != nil {
		b.err = err
		return
	} else if ok {
		return
	}

	link, err := netlink.LinkByName(slave)
	if err != nil {
		b.err = err
		return
	}

	b.err = netlink.LinkSetDown(link)
	if b.err != nil {
		return
	}

	p := base + b.name + "/bonding/slaves"
	logrus.Infof("Adding slave %s to master %s", slave, b.name)
	b.err = ioutil.WriteFile(p, []byte("+"+slave), 0644)
}
Beispiel #3
0
func (n *networkNamespace) AddInterface(i *Interface) error {
	n.Lock()
	i.DstName = fmt.Sprintf("%s%d", i.DstName, n.nextIfIndex)
	n.nextIfIndex++
	n.Unlock()

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	origns, err := netns.Get()
	if err != nil {
		return err
	}
	defer origns.Close()

	f, err := os.OpenFile(n.path, os.O_RDONLY, 0)
	if err != nil {
		return fmt.Errorf("failed get network namespace %q: %v", n.path, err)
	}
	defer f.Close()

	// Find the network interface identified by the SrcName attribute.
	iface, err := netlink.LinkByName(i.SrcName)
	if err != nil {
		return err
	}

	// Move the network interface to the destination namespace.
	nsFD := f.Fd()
	if err := netlink.LinkSetNsFd(iface, int(nsFD)); err != nil {
		return err
	}

	if err = netns.Set(netns.NsHandle(nsFD)); err != nil {
		return err
	}
	defer netns.Set(origns)

	// Down the interface before configuring
	if err := netlink.LinkSetDown(iface); err != nil {
		return err
	}

	// Configure the interface now this is moved in the proper namespace.
	if err := configureInterface(iface, i); err != nil {
		return err
	}

	// Up the interface.
	if err := netlink.LinkSetUp(iface); err != nil {
		return err
	}

	n.Lock()
	n.sinfo.Interfaces = append(n.sinfo.Interfaces, i)
	n.Unlock()

	return nil
}
Beispiel #4
0
func (b *Bonding) linkDown() error {
	link, err := netlink.LinkByName(b.name)
	if err != nil {
		return err
	}

	return netlink.LinkSetDown(link)
}
func (n *networkNamespace) RemoveInterface(i *Interface) error {
	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	origns, err := netns.Get()
	if err != nil {
		return err
	}
	defer origns.Close()

	f, err := os.OpenFile(n.path, os.O_RDONLY, 0)
	if err != nil {
		return fmt.Errorf("failed get network namespace %q: %v", n.path, err)
	}
	defer f.Close()

	nsFD := f.Fd()
	if err = netns.Set(netns.NsHandle(nsFD)); err != nil {
		return err
	}
	defer netns.Set(origns)

	// Find the network inteerface identified by the DstName attribute.
	iface, err := netlink.LinkByName(i.DstName)
	if err != nil {
		return err
	}

	// Down the interface before configuring
	if err := netlink.LinkSetDown(iface); err != nil {
		return err
	}

	err = netlink.LinkSetName(iface, i.SrcName)
	if err != nil {
		fmt.Println("LinkSetName failed: ", err)
		return err
	}

	// Move the network interface to caller namespace.
	if err := netlink.LinkSetNsFd(iface, int(origns)); err != nil {
		fmt.Println("LinkSetNsPid failed: ", err)
		return err
	}

	n.Lock()
	for index, intf := range n.sinfo.Interfaces {
		if intf == i {
			n.sinfo.Interfaces = append(n.sinfo.Interfaces[:index], n.sinfo.Interfaces[index+1:]...)
			break
		}
	}
	n.Unlock()

	return nil
}
Beispiel #6
0
func (n *networks) deleteLink(config networkConfig) error {
	if li, err := netlink.LinkByName(config.BridgeName); err == nil {
		if err := netlink.LinkSetDown(li); err != nil {
			return ErrNetlinkError{"bring bridge down", err}
		}
		if err := netlink.LinkDel(li); err != nil {
			return ErrNetlinkError{"delete bridge", err}
		}
	}
	if li, err := netlink.LinkByName(config.LinkName); err == nil {
		if err := netlink.LinkSetDown(li); err != nil {
			return ErrNetlinkError{"bring vlan down", err}
		}
		if err := netlink.LinkDel(li); err != nil {
			return ErrNetlinkError{"delete vlan", err}
		}
	}
	return nil
}
Beispiel #7
0
func (i *nwIface) Remove() error {
	i.Lock()
	n := i.ns
	i.Unlock()

	n.Lock()
	path := n.path
	isDefault := n.isDefault
	n.Unlock()

	return nsInvoke(path, func(nsFD int) error { return nil }, func(callerFD int) error {
		// Find the network inteerface identified by the DstName attribute.
		iface, err := netlink.LinkByName(i.DstName())
		if err != nil {
			return err
		}

		// Down the interface before configuring
		if err := netlink.LinkSetDown(iface); err != nil {
			return err
		}

		err = netlink.LinkSetName(iface, i.SrcName())
		if err != nil {
			fmt.Println("LinkSetName failed: ", err)
			return err
		}

		// if it is a bridge just delete it.
		if i.Bridge() {
			if err := netlink.LinkDel(iface); err != nil {
				return fmt.Errorf("failed deleting bridge %q: %v", i.SrcName(), err)
			}
		} else if !isDefault {
			// Move the network interface to caller namespace.
			if err := netlink.LinkSetNsFd(iface, callerFD); err != nil {
				fmt.Println("LinkSetNsPid failed: ", err)
				return err
			}
		}

		n.Lock()
		for index, intf := range n.iFaces {
			if intf == i {
				n.iFaces = append(n.iFaces[:index], n.iFaces[index+1:]...)
				break
			}
		}
		n.Unlock()

		return nil
	})
}
// Wire up a tap interface for communicating with the guest. Returns the name
// of the created tap interface.
func wireTapInterface(config *netConfig) string {
	// Drop link on eth0 before configuring anything
	eth0, err := netlink.LinkByName("eth0")
	if err != nil {
		log.Fatalf("LinkByName(eth0): %v", err)
	}
	if err := netlink.LinkSetDown(eth0); err != nil {
		log.Fatalf("LinkSetDown(eth0): %v", err)
	}
	// Flush any L3 addresses on eth0
	if err := flushAddresses(eth0); err != nil {
		log.Fatalf("flushAddresses(eth0): %v", err)
	}
	// Generate and set random MAC address for eth0
	eth0Addr := generateHardwareAddr()
	if err := netlink.LinkSetHardwareAddr(eth0, eth0Addr); err != nil {
		log.Fatalf("LinkSetHardwareAddr(eth0): %v", err)
	}
	// Create "tap0" (interface to guest)
	tap0Attrs := netlink.NewLinkAttrs()
	tap0Attrs.Name = "tap0"
	tap0 := &netlink.Tuntap{tap0Attrs, netlink.TUNTAP_MODE_TAP}
	if err := netlink.LinkAdd(tap0); err != nil {
		log.Fatalf("LinkAdd(tap0): %v", err)
	}
	// Create a new bridge, br0 and add eth0 and tap0 to it
	br0Attrs := netlink.NewLinkAttrs()
	br0Attrs.Name = "br0"
	br0 := &netlink.Bridge{br0Attrs}
	if err := netlink.LinkAdd(br0); err != nil {
		log.Fatalf("LinkAdd(br0): %v", err)
	}
	if err := netlink.LinkSetMaster(eth0, br0); err != nil {
		log.Fatalf("LinkSetMaster(eth0, br0): %v", err)
	}
	if err := netlink.LinkSetMaster(tap0, br0); err != nil {
		log.Fatalf("LinkSetMaster(tap0, br0): %v", err)
	}
	// Set all links up
	if err := netlink.LinkSetUp(tap0); err != nil {
		log.Fatalf("LinkSetUp(tap0): %v", err)
	}
	if err := netlink.LinkSetUp(eth0); err != nil {
		log.Fatalf("LinkSetUp(eth0): %v", err)
	}
	if err := netlink.LinkSetUp(br0); err != nil {
		log.Fatalf("LinkSetUp(br0): %v", err)
	}
	return tap0Attrs.Name
}
Beispiel #9
0
func NetIfaceDown(cResp chan<- *Response, rawArgs *json.RawMessage, tag string) {
	args := &struct {
		Ifname string `json:"ifname"`
	}{}

	json.Unmarshal(*rawArgs, &args)

	iface := &netlink.Device{netlink.LinkAttrs{Name: args.Ifname}}
	if err := netlink.LinkSetDown(iface); err != nil {
		cResp <- &Response{nil, tag, NewRTNetlinkError(err)}
		return
	}

	cResp <- &Response{true, tag, nil}
}
Beispiel #10
0
func bridgeDestroy() {
	bridgeInt, err := netlink.LinkByName("mycbridge")
	if err != nil {
		panic(err)
	}

	err = netlink.LinkSetDown(bridgeInt)
	if err != nil {
		panic(err)
	}

	err = netlink.LinkDel(bridgeInt)
	if err != nil {
		panic(err)
	}
}
Beispiel #11
0
func deleteBridgeAddr(br *netlink.Bridge, ipn *net.IPNet) error {
	addr := &netlink.Addr{IPNet: ipn, Label: ""}

	if err := netlink.LinkSetDown(br); err != nil {
		return fmt.Errorf("could not set down bridge %q: %v", br.Name, err)
	}

	if err := netlink.AddrDel(br, addr); err != nil {
		return fmt.Errorf("could not remove IP address from %q: %v", br.Name, err)
	}

	if err := netlink.LinkSetUp(br); err != nil {
		return fmt.Errorf("could not set up bridge %q: %v", br.Name, err)
	}

	return nil
}
Beispiel #12
0
func cmdDel(args *skel.CmdArgs) error {
	args.IfName = "lo" // ignore config, this only works for loopback
	err := ns.WithNetNSPath(args.Netns, func(ns.NetNS) error {
		link, err := netlink.LinkByName(args.IfName)
		if err != nil {
			return err // not tested
		}

		err = netlink.LinkSetDown(link)
		if err != nil {
			return err // not tested
		}

		return nil
	})
	if err != nil {
		return err // not tested
	}

	return nil
}
Beispiel #13
0
func routingDown() {
	veth, err := netlink.LinkByName("myveth1")
	if err != nil {
		panic(err)
	}

	routes := createRoutes(veth)

	for _, route := range routes {
		fmt.Println("Removing route", route)
		err := netlink.RouteDel(route)
		if err != nil {
			// panic(err)
			fmt.Println(err)
		}
	}

	err = netlink.LinkSetDown(veth)
	if err != nil {
		panic(err)
	}
}
Beispiel #14
0
func collectionInterfaceInfo() []supervisor.InterfaceInfo {
	infos := []supervisor.InterfaceInfo{}

	links, err := netlink.LinkList()
	if err != nil {
		glog.Error(err)
		return infos
	}

	for _, link := range links {
		if link.Type() != "veth" {
			// lo is here too
			continue
		}

		addrs, err := netlink.AddrList(link, netlink.FAMILY_V4)
		if err != nil {
			glog.Error(err)
			return infos
		}

		for _, addr := range addrs {
			info := supervisor.InterfaceInfo{
				Ip:        addr.IPNet.String(),
				Index:     link.Attrs().Index,
				PeerIndex: link.Attrs().ParentIndex,
			}
			glog.Infof("get interface %v", info)
			infos = append(infos, info)
		}

		// set link down, tap device take over it
		netlink.LinkSetDown(link)
	}
	return infos
}
Beispiel #15
0
// configureInterface configures the network interface in the network namespace.
func configureInterface(name string, pid int, addr *net.IPNet, gatewayIP string) error {
	// Lock the OS Thread so we don't accidentally switch namespaces
	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	// Save the current network namespace
	origns, err := netns.Get()
	if err != nil {
		return fmt.Errorf("Getting current network namespace failed: %v", err)
	}
	defer origns.Close()

	// Get the namespace
	newns, err := netns.GetFromPid(pid)
	if err != nil {
		return fmt.Errorf("Getting network namespace for pid %d failed: %v", pid, err)
	}
	defer newns.Close()

	// Enter the namespace
	if err := netns.Set(newns); err != nil {
		return fmt.Errorf("Entering network namespace failed: %v", err)
	}

	// Find the network interface identified by the name
	iface, err := netlink.LinkByName(name)
	if err != nil {
		return fmt.Errorf("Getting link by name %s failed: %v", name, err)
	}

	// Bring the interface down
	if err := netlink.LinkSetDown(iface); err != nil {
		return fmt.Errorf("Bringing interface [ %#v ] down failed: %v", iface, err)
	}

	// Change the interface name to eth0 in the namespace
	if err := netlink.LinkSetName(iface, containerInterface); err != nil {
		return fmt.Errorf("Renaming interface %s to %s failed: %v", name, defaultContainerInterface, err)
	}

	// Add the IP address
	ipAddr := &netlink.Addr{IPNet: addr, Label: ""}
	if err := netlink.AddrAdd(iface, ipAddr); err != nil {
		return fmt.Errorf("Setting interface %s ip to %s failed: %v", name, addr.String(), err)
	}

	// Bring the interface up
	if err := netlink.LinkSetUp(iface); err != nil {
		return fmt.Errorf("Bringing interface [ %#v ] up failed: %v", iface, err)
	}

	// Add the gateway route
	gw := net.ParseIP(gatewayIP)
	err = netlink.RouteAdd(&netlink.Route{
		Scope:     netlink.SCOPE_UNIVERSE,
		LinkIndex: iface.Attrs().Index,
		Gw:        gw,
	})
	if err != nil {
		return fmt.Errorf("Adding route %s to interface %s failed: %v", gw.String(), name, err)
	}

	// Switch back to the original namespace
	if err := netns.Set(origns); err != nil {
		return fmt.Errorf("Switching back to original namespace failed: %v", err)
	}

	return nil
}
Beispiel #16
0
func (n *networkNamespace) AddInterface(srcName, dstPrefix string, options ...IfaceOption) error {
	i := &nwIface{srcName: srcName, dstName: dstPrefix, ns: n}
	i.processInterfaceOptions(options...)

	if i.master != "" {
		i.dstMaster = n.findDst(i.master, true)
		if i.dstMaster == "" {
			return fmt.Errorf("could not find an appropriate master %q for %q",
				i.master, i.srcName)
		}
	}

	n.Lock()
	if n.isDefault {
		i.dstName = i.srcName
	} else {
		i.dstName = fmt.Sprintf("%s%d", i.dstName, n.nextIfIndex)
		n.nextIfIndex++
	}

	path := n.path
	isDefault := n.isDefault
	n.Unlock()

	return nsInvoke(path, func(nsFD int) error {
		// If it is a bridge interface we have to create the bridge inside
		// the namespace so don't try to lookup the interface using srcName
		if i.bridge {
			return nil
		}

		// Find the network interface identified by the SrcName attribute.
		iface, err := netlink.LinkByName(i.srcName)
		if err != nil {
			return fmt.Errorf("failed to get link by name %q: %v", i.srcName, err)
		}

		// Move the network interface to the destination
		// namespace only if the namespace is not a default
		// type
		if !isDefault {
			if err := netlink.LinkSetNsFd(iface, nsFD); err != nil {
				return fmt.Errorf("failed to set namespace on link %q: %v", i.srcName, err)
			}
		}

		return nil
	}, func(callerFD int) error {
		if i.bridge {
			link := &netlink.Bridge{
				LinkAttrs: netlink.LinkAttrs{
					Name: i.srcName,
				},
			}

			if err := netlink.LinkAdd(link); err != nil {
				return fmt.Errorf("failed to create bridge %q: %v", i.srcName, err)
			}
		}

		// Find the network interface identified by the SrcName attribute.
		iface, err := netlink.LinkByName(i.srcName)
		if err != nil {
			return fmt.Errorf("failed to get link by name %q: %v", i.srcName, err)
		}

		// Down the interface before configuring
		if err := netlink.LinkSetDown(iface); err != nil {
			return fmt.Errorf("failed to set link down: %v", err)
		}

		// Configure the interface now this is moved in the proper namespace.
		if err := configureInterface(iface, i); err != nil {
			return err
		}

		// Up the interface.
		if err := netlink.LinkSetUp(iface); err != nil {
			return fmt.Errorf("failed to set link up: %v", err)
		}

		// Set the routes on the interface. This can only be done when the interface is up.
		if err := setInterfaceRoutes(iface, i); err != nil {
			return fmt.Errorf("error setting interface %q routes to %q: %v", iface.Attrs().Name, i.Routes(), err)
		}

		n.Lock()
		n.iFaces = append(n.iFaces, i)
		n.Unlock()

		return nil
	})
}
Beispiel #17
0
func (e *endpoints) create(eid string, ifInfo *driverapi.EndpointInterface, niConfig networkConfig) (err error) {
	ep := endpoint{}

	// Generate a name for what will be the host side pipe interface
	hostIfName, err := netutils.GenerateIfaceName(vethPrefix, vethLen)
	if err != nil {
		return err
	}

	// Generate a name for what will be the sandbox side pipe interface
	containerIfName, err := netutils.GenerateIfaceName(vethPrefix, vethLen)
	if err != nil {
		return err
	}

	// Generate and add the interface pipe host <-> sandbox
	veth := &netlink.Veth{
		LinkAttrs: netlink.LinkAttrs{Name: hostIfName, TxQLen: 0},
		PeerName:  containerIfName,
	}
	if err = netlink.LinkAdd(veth); err != nil {
		return types.InternalErrorf("failed to add the host (%s) <=> sandbox (%s) pair interfaces: %v", hostIfName, containerIfName, err)
	}

	// Get the host side pipe interface handler
	host, err := netlink.LinkByName(hostIfName)
	if err != nil {
		return types.InternalErrorf("failed to find host side interface %s: %v", hostIfName, err)
	}
	defer func() {
		if err != nil {
			netlink.LinkDel(host)
		}
	}()

	// Get the sandbox side pipe interface handler
	sbox, err := netlink.LinkByName(containerIfName)
	if err != nil {
		return types.InternalErrorf("failed to find sandbox side interface %s: %v", containerIfName, err)
	}
	defer func() {
		if err != nil {
			netlink.LinkDel(sbox)
		}
	}()

	// Add bridge inherited attributes to pipe interfaces
	if niConfig.Mtu != 0 {
		err = netlink.LinkSetMTU(host, niConfig.Mtu)
		if err != nil {
			return types.InternalErrorf("failed to set MTU on host interface %s: %v", hostIfName, err)
		}
		err = netlink.LinkSetMTU(sbox, niConfig.Mtu)
		if err != nil {
			return types.InternalErrorf("failed to set MTU on sandbox interface %s: %v", containerIfName, err)
		}
	}

	// Attach host side pipe interface into the bridge
	br, err := netlink.LinkByName(niConfig.BridgeName)
	if err != nil {
		return types.InternalErrorf("failed to find bridge by name %s: %v", niConfig.BridgeName, err)
	}
	if err = netlink.LinkSetMaster(host, br.(*netlink.Bridge)); err != nil {
		return fmt.Errorf("adding interface %s to bridge %s failed: %v", hostIfName, niConfig.BridgeName, err)
	}

	// Create the sandbox side pipe interface
	ep.ifname = containerIfName
	ep.addr, _, err = net.ParseCIDR(ifInfo.Address)
	if err != nil {
		return fmt.Errorf("ipv4 adress unparseable")
	}
	/*
		_, ep.addrv6, err = net.ParseCIDR(ifInfo.AddressIPv6)
		if err != nil {
			return fmt.Errorf("ipv6 adress unparseable")
		}
	*/

	if ifInfo.MacAddress != "" {
		ep.mac, err = net.ParseMAC(ifInfo.MacAddress)
		if err != nil {
			return fmt.Errorf("mac adress unparseable")
		}
		// Down the interface before configuring mac address.
		if err = netlink.LinkSetDown(sbox); err != nil {
			return fmt.Errorf("could not set link down for container interface %s: %v", containerIfName, err)
		}

		err = netlink.LinkSetHardwareAddr(sbox, ep.mac)
		if err != nil {
			return fmt.Errorf("could not set mac address for container interface %s: %v", containerIfName, err)
		}

		if err = netlink.LinkSetUp(sbox); err != nil {
			return fmt.Errorf("could not set link up for container interface %s: %v", containerIfName, err)
		}
	} else {
		// Get existing mac address from interface
		ep.mac = sbox.Attrs().HardwareAddr
	}

	// Up the host interface after finishing all netlink configuration
	if err = netlink.LinkSetUp(host); err != nil {
		return fmt.Errorf("could not set link up for host interface %s: %v", hostIfName, err)
	}

	if ep.addrv6 == nil && niConfig.EnableIPv6 {
		return fmt.Errorf("IPV6 is not supported. Go and code it yourself.")
	}

	e.add(eid, ep)

	Log.Debugf("ep data at join: ip: %v, mac: %v", ep.addr, ep.mac)
	broadcastChange(br, ep)

	return nil
}
Beispiel #18
0
func (l *DHCPLease) downIface() {
	if err := netlink.LinkSetDown(l.link); err != nil {
		log.Printf("%v: failed to bring %v interface DOWN: %v", l.clientID, l.link.Attrs().Name, err)
	}
}
Beispiel #19
0
func AddVlannetwork(etcdval string, vlanid string, containerName string) {
	ss := strings.Split(etcdval, ",")
	hostif := ss[0]
	if ok := utils.ValidateHostIface(hostif); !ok {
		log.Warnf("the host interface not exist")
		return
	}

	vlandevName := hostif + "." + vlanid
	hostEth, _ := netlink.LinkByName(hostif)

	intvlanid, err := strconv.Atoi(vlanid)
	if err != nil {
		log.Warnf("the vlan id convert error: \n")
		return
	}

	var vlandev *netlink.Vlan
	if ok := utils.ValidateHostIface(vlandevName); ok {

	} else {
		//not exist ,create the vlan device
		vlandev = &netlink.Vlan{
			LinkAttrs: netlink.LinkAttrs{
				Name:        vlandevName,
				ParentIndex: hostEth.Attrs().Index,
			},
			VlanId: intvlanid,
		}
		if err := netlink.LinkAdd(vlandev); err != nil {
			log.Warnf("failed to create vlandev: [ %v ] with the error: %s", vlandev, err)
			return
		}
	}

	netlink.LinkSetUp(vlandev)
	macvlanname, _ := utils.GenerateRandomName("vlan"+vlanid, 5)
	//create the macvlan device
	macvlandev := &netlink.Macvlan{
		LinkAttrs: netlink.LinkAttrs{
			Name:        macvlanname,
			ParentIndex: vlandev.Attrs().Index,
		},
		Mode: netlink.MACVLAN_MODE_BRIDGE,
	}

	if err := netlink.LinkAdd(macvlandev); err != nil {
		log.Warnf("failed to create Macvlan: [ %v ] with the error: %s", macvlandev, err)
		return
	}

	dockerPid := utils.DockerPid(containerName)
	//the macvlandev can be use directly, don't get netlink.byname again.
	netlink.LinkSetNsPid(macvlandev, dockerPid)

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	//get root network naAddVlannetworkmespace
	origns, _ := netns.Get()
	defer origns.Close()

	//enter the docker container network
	dockerNS, _ := netns.GetFromPid(dockerPid)
	defer dockerNS.Close()

	netns.Set(dockerNS)

	netlink.LinkSetDown(macvlandev)
	netlink.LinkSetName(macvlandev, "eth1")

	_, network, _ := net.ParseCIDR(ss[1])
	if _, ok := ipallocs[vlanid]; !ok {
		log.Fatalf("the ipallocator is null \n")
	}
	ip, _ := ipallocs[vlanid].RequestIP(network, nil)
	ind := strings.LastIndex(ss[1], "/")
	ipstring := ip.String() + ss[1][ind:]

	addr, err := netlink.ParseAddr(ipstring)

	netlink.AddrAdd(macvlandev, addr)
	netlink.LinkSetUp(macvlandev)

	/*
		routes, _ := netlink.RouteList(nil, netlink.FAMILY_V4)
		for _, r := range routes {
			if r.Dst == nil {
				if err := netlink.RouteDel(&r); err != nil {
					log.Warnf("delete the default error: ", err)
				}
			}
		}

		if CligwIP == "" {
			log.Fatal("container gw is null")
		}

		defaultRoute := &netlink.Route{
			Dst:       nil,
			Gw:        net.ParseIP(CligwIP),
			LinkIndex: macvlandev1.Attrs().Index,
		}
		if err := netlink.RouteAdd(defaultRoute); err != nil {
			log.Warnf("create default route error: ", err)
		}
	*/
	netns.Set(origns)
}
Beispiel #20
0
func (t *BaseOperations) LinkSetDown(link netlink.Link) error {
	return netlink.LinkSetDown(link)
}
Beispiel #21
0
func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, epOptions map[string]interface{}) error {
	defer osl.InitOSContext()()

	if ifInfo == nil {
		return errors.New("invalid interface info passed")
	}

	// Get the network handler and make sure it exists
	d.Lock()
	n, ok := d.networks[nid]
	dconfig := d.config
	d.Unlock()

	if !ok {
		return types.NotFoundErrorf("network %s does not exist", nid)
	}
	if n == nil {
		return driverapi.ErrNoNetwork(nid)
	}

	// Sanity check
	n.Lock()
	if n.id != nid {
		n.Unlock()
		return InvalidNetworkIDError(nid)
	}
	n.Unlock()

	// Check if endpoint id is good and retrieve correspondent endpoint
	ep, err := n.getEndpoint(eid)
	if err != nil {
		return err
	}

	// Endpoint with that id exists either on desired or other sandbox
	if ep != nil {
		return driverapi.ErrEndpointExists(eid)
	}

	// Try to convert the options to endpoint configuration
	epConfig, err := parseEndpointOptions(epOptions)
	if err != nil {
		return err
	}

	// Create and add the endpoint
	n.Lock()
	endpoint := &bridgeEndpoint{id: eid, config: epConfig}
	n.endpoints[eid] = endpoint
	n.Unlock()

	// On failure make sure to remove the endpoint
	defer func() {
		if err != nil {
			n.Lock()
			delete(n.endpoints, eid)
			n.Unlock()
		}
	}()

	// Generate a name for what will be the host side pipe interface
	hostIfName, err := netutils.GenerateIfaceName(vethPrefix, vethLen)
	if err != nil {
		return err
	}

	// Generate a name for what will be the sandbox side pipe interface
	containerIfName, err := netutils.GenerateIfaceName(vethPrefix, vethLen)
	if err != nil {
		return err
	}

	// Generate and add the interface pipe host <-> sandbox
	veth := &netlink.Veth{
		LinkAttrs: netlink.LinkAttrs{Name: hostIfName, TxQLen: 0},
		PeerName:  containerIfName}
	if err = netlink.LinkAdd(veth); err != nil {
		return types.InternalErrorf("failed to add the host (%s) <=> sandbox (%s) pair interfaces: %v", hostIfName, containerIfName, err)
	}

	// Get the host side pipe interface handler
	host, err := netlink.LinkByName(hostIfName)
	if err != nil {
		return types.InternalErrorf("failed to find host side interface %s: %v", hostIfName, err)
	}
	defer func() {
		if err != nil {
			netlink.LinkDel(host)
		}
	}()

	// Get the sandbox side pipe interface handler
	sbox, err := netlink.LinkByName(containerIfName)
	if err != nil {
		return types.InternalErrorf("failed to find sandbox side interface %s: %v", containerIfName, err)
	}
	defer func() {
		if err != nil {
			netlink.LinkDel(sbox)
		}
	}()

	n.Lock()
	config := n.config
	n.Unlock()

	// Add bridge inherited attributes to pipe interfaces
	if config.Mtu != 0 {
		err = netlink.LinkSetMTU(host, config.Mtu)
		if err != nil {
			return types.InternalErrorf("failed to set MTU on host interface %s: %v", hostIfName, err)
		}
		err = netlink.LinkSetMTU(sbox, config.Mtu)
		if err != nil {
			return types.InternalErrorf("failed to set MTU on sandbox interface %s: %v", containerIfName, err)
		}
	}

	// Attach host side pipe interface into the bridge
	if err = addToBridge(hostIfName, config.BridgeName); err != nil {
		return fmt.Errorf("adding interface %s to bridge %s failed: %v", hostIfName, config.BridgeName, err)
	}

	if !dconfig.EnableUserlandProxy {
		err = setHairpinMode(host, true)
		if err != nil {
			return err
		}
	}

	// Create the sandbox side pipe interface
	endpoint.srcName = containerIfName
	endpoint.macAddress = ifInfo.MacAddress()
	endpoint.addr = ifInfo.Address()
	endpoint.addrv6 = ifInfo.AddressIPv6()

	// Down the interface before configuring mac address.
	if err = netlink.LinkSetDown(sbox); err != nil {
		return fmt.Errorf("could not set link down for container interface %s: %v", containerIfName, err)
	}

	// Set the sbox's MAC. If specified, use the one configured by user, otherwise generate one based on IP.
	if endpoint.macAddress == nil {
		endpoint.macAddress = electMacAddress(epConfig, endpoint.addr.IP)
		if err := ifInfo.SetMacAddress(endpoint.macAddress); err != nil {
			return err
		}
	}
	err = netlink.LinkSetHardwareAddr(sbox, endpoint.macAddress)
	if err != nil {
		return fmt.Errorf("could not set mac address for container interface %s: %v", containerIfName, err)
	}

	// Up the host interface after finishing all netlink configuration
	if err = netlink.LinkSetUp(host); err != nil {
		return fmt.Errorf("could not set link up for host interface %s: %v", hostIfName, err)
	}

	if endpoint.addrv6 == nil && config.EnableIPv6 {
		var ip6 net.IP
		network := n.bridge.bridgeIPv6
		if config.AddressIPv6 != nil {
			network = config.AddressIPv6
		}

		ones, _ := network.Mask.Size()
		if ones > 80 {
			err = types.ForbiddenErrorf("Cannot self generate an IPv6 address on network %v: At least 48 host bits are needed.", network)
			return err
		}

		ip6 = make(net.IP, len(network.IP))
		copy(ip6, network.IP)
		for i, h := range endpoint.macAddress {
			ip6[i+10] = h
		}

		endpoint.addrv6 = &net.IPNet{IP: ip6, Mask: network.Mask}
		if err := ifInfo.SetIPAddress(endpoint.addrv6); err != nil {
			return err
		}
	}

	// Program any required port mapping and store them in the endpoint
	endpoint.portMapping, err = n.allocatePorts(epConfig, endpoint, config.DefaultBindingIP, d.config.EnableUserlandProxy)
	if err != nil {
		return err
	}

	return nil
}
Beispiel #22
0
func AddDHCPNetwork() {

	if ok := utils.ValidateHostIface(flat.CliIF); !ok {
		log.Fatalf("the host-interface [ %s ] was not found.", flat.CliIF)
	}

	hostmacvlanname, _ := utils.GenerateRandomName(hostprefix, hostlen)
	hostEth, _ := netlink.LinkByName(flat.CliIF)

	//create the macvlan device
	macvlandev := &netlink.Macvlan{
		LinkAttrs: netlink.LinkAttrs{
			Name:        hostmacvlanname,
			ParentIndex: hostEth.Attrs().Index,
		},
		Mode: netlink.MACVLAN_MODE_BRIDGE,
	}
	if err := netlink.LinkAdd(macvlandev); err != nil {
		log.Fatalf("failed to create Macvlan: [ %v ] with the error: %s", macvlandev.Attrs().Name, err)
	}

	dockerPid := utils.DockerPid(flat.CliCName)
	netlink.LinkSetNsPid(macvlandev, dockerPid)

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	//get root network namespace
	origns, _ := netns.Get()
	defer origns.Close()

	//enter the docker container network
	dockerNS, _ := netns.GetFromPid(dockerPid)
	defer dockerNS.Close()

	//get the dochclient name
	dhcpClientPath := "/home/fmzhen/go/src/github.com/fmzhen/docker-macvlan/macvlan/dhcp/dhcpclient.sh"
	out, err := exec.Command(dhcpClientPath).Output()
	if err != nil {
		log.Fatal("exec the dhcpclient.sh error: ", err)
	}
	dhcpClient := string(out)

	// like ip netns exec xxx, just the netns ,so the command in host can exec
	netns.Set(dockerNS)

	// use macvlandev can cause error,need type assertion. netlink.Macvlan not must be netlink.Link,fmz
	macvlandev1, _ := netlink.LinkByName(macvlandev.Attrs().Name)
	netlink.LinkSetDown(macvlandev1)
	netlink.LinkSetName(macvlandev1, "eth1")
	netlink.LinkSetUp(macvlandev1)

	//delete the default route
	routes, _ := netlink.RouteList(nil, netlink.FAMILY_V4)
	for _, r := range routes {
		if r.Dst == nil {
			if err := netlink.RouteDel(&r); err != nil {
				log.Warnf("delete the default error: ", err)
			}
		}
	}

	//it doesn't work, the problem at the atgs don't pass to the shell script
	dhcpReqpath := "/home/fmzhen/go/src/github.com/fmzhen/docker-macvlan/macvlan/dhcp/dhcpReq.sh"
	exec.Command(dhcpReqpath, dhcpClient, string(dockerPid), flat.CliCName).Run()

	netns.Set(origns)
}
func (v *veth) initialize(config *network) error {
	peer := config.TempVethPeerName
	if peer == "" {
		return fmt.Errorf("peer is not specified")
	}
	child, err := netlink.LinkByName(peer)
	if err != nil {
		return err
	}
	if err := netlink.LinkSetDown(child); err != nil {
		return err
	}
	if err := netlink.LinkSetName(child, config.Name); err != nil {
		return err
	}
	// get the interface again after we changed the name as the index also changes.
	if child, err = netlink.LinkByName(config.Name); err != nil {
		return err
	}
	if config.MacAddress != "" {
		mac, err := net.ParseMAC(config.MacAddress)
		if err != nil {
			return err
		}
		if err := netlink.LinkSetHardwareAddr(child, mac); err != nil {
			return err
		}
	}
	ip, err := netlink.ParseAddr(config.Address)
	if err != nil {
		return err
	}
	if err := netlink.AddrAdd(child, ip); err != nil {
		return err
	}
	if config.IPv6Address != "" {
		ip6, err := netlink.ParseAddr(config.IPv6Address)
		if err != nil {
			return err
		}
		if err := netlink.AddrAdd(child, ip6); err != nil {
			return err
		}
	}
	if err := netlink.LinkSetMTU(child, config.Mtu); err != nil {
		return err
	}
	if err := netlink.LinkSetUp(child); err != nil {
		return err
	}
	if config.Gateway != "" {
		gw := net.ParseIP(config.Gateway)
		if err := netlink.RouteAdd(&netlink.Route{
			Scope:     netlink.SCOPE_UNIVERSE,
			LinkIndex: child.Attrs().Index,
			Gw:        gw,
		}); err != nil {
			return err
		}
	}
	if config.IPv6Gateway != "" {
		gw := net.ParseIP(config.IPv6Gateway)
		if err := netlink.RouteAdd(&netlink.Route{
			Scope:     netlink.SCOPE_UNIVERSE,
			LinkIndex: child.Attrs().Index,
			Gw:        gw,
		}); err != nil {
			return err
		}
	}
	return nil
}
Beispiel #24
0
func applyInterfaceConfig(link netlink.Link, netConf InterfaceConfig) error {
	if netConf.Bond != "" {
		if err := netlink.LinkSetDown(link); err != nil {
			return err
		}

		b, err := Bond(netConf.Bond)
		if err != nil {
			return err
		}
		if err := b.AddSlave(link.Attrs().Name); err != nil {
			return err
		}
		return nil
	}

	if netConf.Bridge != "" && netConf.Bridge != "true" {
		b, err := NewBridge(netConf.Bridge)
		if err != nil {
			return err
		}
		if err := b.AddLink(link); err != nil {
			return err
		}
		return linkUp(link, netConf)
	}

	if netConf.IPV4LL {
		if err := AssignLinkLocalIP(link); err != nil {
			log.Errorf("IPV4LL set failed: %v", err)
			return err
		}
	} else {
		addresses := []string{}

		if netConf.Address != "" {
			addresses = append(addresses, netConf.Address)
		}

		if len(netConf.Addresses) > 0 {
			addresses = append(addresses, netConf.Addresses...)
		}

		for _, address := range addresses {
			err := applyAddress(address, link, netConf)
			if err != nil {
				log.Errorf("Failed to apply address %s to %s: %v", address, link.Attrs().Name, err)
			}
		}
	}

	if netConf.MTU > 0 {
		if err := netlink.LinkSetMTU(link, netConf.MTU); err != nil {
			log.Errorf("set MTU Failed: %v", err)
			return err
		}
	}

	runCmds(netConf.PreUp, link.Attrs().Name)

	if err := linkUp(link, netConf); err != nil {
		return err
	}

	if err := setGateway(netConf.Gateway); err != nil {
		log.Errorf("Fail to set gateway %s", netConf.Gateway)
	}

	if err := setGateway(netConf.GatewayIpv6); err != nil {
		log.Errorf("Fail to set gateway %s", netConf.GatewayIpv6)
	}

	runCmds(netConf.PostUp, link.Attrs().Name)

	return nil
}
Beispiel #25
0
func (d *driver) CreateEndpoint(nid, eid types.UUID, epInfo driverapi.EndpointInfo, epOptions map[string]interface{}) error {
	var (
		ipv6Addr *net.IPNet
		err      error
	)

	defer sandbox.InitOSContext()()

	if epInfo == nil {
		return errors.New("invalid endpoint info passed")
	}

	if len(epInfo.Interfaces()) != 0 {
		return errors.New("non empty interface list passed to bridge(local) driver")
	}

	// Get the network handler and make sure it exists
	d.Lock()
	n, ok := d.networks[nid]
	d.Unlock()

	if !ok {
		return types.NotFoundErrorf("network %s does not exist", nid)
	}
	if n == nil {
		return driverapi.ErrNoNetwork(nid)
	}

	// Sanity check
	n.Lock()
	if n.id != nid {
		n.Unlock()
		return InvalidNetworkIDError(nid)
	}
	n.Unlock()

	// Check if endpoint id is good and retrieve correspondent endpoint
	ep, err := n.getEndpoint(eid)
	if err != nil {
		return err
	}

	// Endpoint with that id exists either on desired or other sandbox
	if ep != nil {
		return driverapi.ErrEndpointExists(eid)
	}

	// Try to convert the options to endpoint configuration
	epConfig, err := parseEndpointOptions(epOptions)
	if err != nil {
		return err
	}

	// Create and add the endpoint
	n.Lock()
	endpoint := &bridgeEndpoint{id: eid, config: epConfig}
	n.endpoints[eid] = endpoint
	n.Unlock()

	// On failure make sure to remove the endpoint
	defer func() {
		if err != nil {
			n.Lock()
			delete(n.endpoints, eid)
			n.Unlock()
		}
	}()

	// Generate a name for what will be the host side pipe interface
	hostIfName, err := netutils.GenerateIfaceName(vethPrefix, vethLen)
	if err != nil {
		return err
	}

	// Generate a name for what will be the sandbox side pipe interface
	containerIfName, err := netutils.GenerateIfaceName(vethPrefix, vethLen)
	if err != nil {
		return err
	}

	// Generate and add the interface pipe host <-> sandbox
	veth := &netlink.Veth{
		LinkAttrs: netlink.LinkAttrs{Name: hostIfName, TxQLen: 0},
		PeerName:  containerIfName}
	if err = netlink.LinkAdd(veth); err != nil {
		return err
	}

	// Get the host side pipe interface handler
	host, err := netlink.LinkByName(hostIfName)
	if err != nil {
		return err
	}
	defer func() {
		if err != nil {
			netlink.LinkDel(host)
		}
	}()

	// Get the sandbox side pipe interface handler
	sbox, err := netlink.LinkByName(containerIfName)
	if err != nil {
		return err
	}
	defer func() {
		if err != nil {
			netlink.LinkDel(sbox)
		}
	}()

	n.Lock()
	config := n.config
	n.Unlock()

	// Add bridge inherited attributes to pipe interfaces
	if config.Mtu != 0 {
		err = netlink.LinkSetMTU(host, config.Mtu)
		if err != nil {
			return err
		}
		err = netlink.LinkSetMTU(sbox, config.Mtu)
		if err != nil {
			return err
		}
	}

	// Attach host side pipe interface into the bridge
	if err = addToBridge(hostIfName, config.BridgeName); err != nil {
		return fmt.Errorf("adding interface %s to bridge %s failed: %v", hostIfName, config.BridgeName, err)
	}

	if !config.EnableUserlandProxy {
		err = setHairpinMode(host, true)
		if err != nil {
			return err
		}
	}

	// v4 address for the sandbox side pipe interface
	ip4, err := ipAllocator.RequestIP(n.bridge.bridgeIPv4, nil)
	if err != nil {
		return err
	}
	ipv4Addr := &net.IPNet{IP: ip4, Mask: n.bridge.bridgeIPv4.Mask}

	// Down the interface before configuring mac address.
	if err = netlink.LinkSetDown(sbox); err != nil {
		return fmt.Errorf("could not set link down for container interface %s: %v", containerIfName, err)
	}

	// Set the sbox's MAC. If specified, use the one configured by user, otherwise generate one based on IP.
	mac := electMacAddress(epConfig, ip4)
	err = netlink.LinkSetHardwareAddr(sbox, mac)
	if err != nil {
		return fmt.Errorf("could not set mac address for container interface %s: %v", containerIfName, err)
	}
	endpoint.macAddress = mac

	// Up the host interface after finishing all netlink configuration
	if err = netlink.LinkSetUp(host); err != nil {
		return fmt.Errorf("could not set link up for host interface %s: %v", hostIfName, err)
	}

	// v6 address for the sandbox side pipe interface
	ipv6Addr = &net.IPNet{}
	if config.EnableIPv6 {
		var ip6 net.IP

		network := n.bridge.bridgeIPv6
		if config.FixedCIDRv6 != nil {
			network = config.FixedCIDRv6
		}

		ones, _ := network.Mask.Size()
		if ones <= 80 {
			ip6 = make(net.IP, len(network.IP))
			copy(ip6, network.IP)
			for i, h := range mac {
				ip6[i+10] = h
			}
		}

		ip6, err := ipAllocator.RequestIP(network, ip6)
		if err != nil {
			return err
		}

		ipv6Addr = &net.IPNet{IP: ip6, Mask: network.Mask}
	}

	// Create the sandbox side pipe interface
	endpoint.srcName = containerIfName
	endpoint.addr = ipv4Addr

	if config.EnableIPv6 {
		endpoint.addrv6 = ipv6Addr
	}

	err = epInfo.AddInterface(ifaceID, endpoint.macAddress, *ipv4Addr, *ipv6Addr)
	if err != nil {
		return err
	}

	// Program any required port mapping and store them in the endpoint
	endpoint.portMapping, err = n.allocatePorts(epConfig, endpoint, config.DefaultBindingIP, config.EnableUserlandProxy)
	if err != nil {
		return err
	}

	return nil
}
Beispiel #26
0
//netlink is not avaible in MAC OS, build fail.
func AddContainerNetworking() {
	if CliIF == "" {
		log.Fatal("the host-interface is missing,please give one")
	}
	if ok := utils.ValidateHostIface(CliIF); !ok {
		log.Fatalf("the host-interface [ %s ] was not found.", CliIF)
	}

	hostmacvlanname, _ := utils.GenerateRandomName(hostprefix, hostlen)
	hostEth, _ := netlink.LinkByName(CliIF)

	//create the macvlan device
	macvlandev := &netlink.Macvlan{
		LinkAttrs: netlink.LinkAttrs{
			Name:        hostmacvlanname,
			ParentIndex: hostEth.Attrs().Index,
		},
		Mode: netlink.MACVLAN_MODE_BRIDGE,
	}
	if err := netlink.LinkAdd(macvlandev); err != nil {
		log.Fatalf("failed to create Macvlan: [ %v ] with the error: %s", macvlandev.Attrs().Name, err)
	}
	//	log.Infof("Created Macvlan port: [ %s ] using the mode: [ %s ]", macvlan.Name, macvlanMode)
	// ugly, actually ,can get the ns from netns.getfromDocker. the netns have many function, netns.getformpid
	// netns.getfromdocker the arg can not be the container name
	dockerPid := utils.DockerPid(CliCName)
	//the macvlandev can be use directly, don't get netlink.byname again.
	netlink.LinkSetNsPid(macvlandev, dockerPid)

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	//get root network namespace
	origns, _ := netns.Get()
	defer origns.Close()

	//enter the docker container network
	dockerNS, _ := netns.GetFromPid(dockerPid)
	defer dockerNS.Close()

	netns.Set(dockerNS)

	// use macvlandev can cause error,need type assertion. netlink.Macvlan not must be netlink.Link,fmz(realy? the vlan action add)
	// it is wrong,
	macvlandev1, _ := netlink.LinkByName(macvlandev.Attrs().Name)

	// when the eth is up, set name fail,: Device or resource busy
	netlink.LinkSetDown(macvlandev1)
	netlink.LinkSetName(macvlandev1, "eth1")

	addr, err := netlink.ParseAddr(CliIP)
	if err != nil {
		log.Fatalf("failed to parse the ip address %v", CliIP)
	}
	netlink.AddrAdd(macvlandev1, addr)
	netlink.LinkSetUp(macvlandev1)

	/* set the default route, have some problem. Dst == 0.0.0.0/0? no
	defaultgw := &netlink.Route{
		Dst: nil,
	}
	netlink.RouteDel(defaultgw)
	ip, _ := net.ParseIP("8.8.8.8")
	routes, _ := netlink.RouteGet(ip)
	for _, r := range routes {
		netlink.RouteDel(&r)
	}
	*/

	//if use ip instruction,  it also can config the container, --privileged have no effect.
	// The sublime test code(test this function) is strange, it only can avaiable in first time. And then fail(even need to reboot)
	// got it,

	//following code successfully delete the default route in docker container,but error in my host ,no such process
	routes, _ := netlink.RouteList(nil, netlink.FAMILY_V4)
	for _, r := range routes {
		if r.Dst == nil {
			if err := netlink.RouteDel(&r); err != nil {
				log.Warnf("delete the default error: ", err)
			}
		}
	}

	if CligwIP == "" {
		log.Fatal("container gw is null")
	}

	defaultRoute := &netlink.Route{
		Dst:       nil,
		Gw:        net.ParseIP(CligwIP),
		LinkIndex: macvlandev1.Attrs().Index,
	}
	if err := netlink.RouteAdd(defaultRoute); err != nil {
		log.Warnf("create default route error: ", err)
	}
	netns.Set(origns)
}