Example #1
0
// 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
}
Example #2
0
func createInterfaces(netCfg *NetworkConfig) error {
	for name, iface := range netCfg.Interfaces {
		if iface.Bridge {
			bridge := netlink.Bridge{}
			bridge.LinkAttrs.Name = name

			if err := netlink.LinkAdd(&bridge); err != nil {
				log.Errorf("Failed to create bridge %s: %v", name, err)
			}
		} else if iface.Bond != "" {
			bondIface, ok := netCfg.Interfaces[iface.Bond]
			if !ok {
				log.Errorf("Failed to find bond configuration for [%s]", iface.Bond)
				continue
			}
			bond := Bond(iface.Bond)
			if bond.Error() != nil {
				log.Errorf("Failed to create bond [%s]: %v", iface.Bond, bond.Error())
				continue
			}

			for k, v := range bondIface.BondOpts {
				bond.Opt(k, v)
				bond.Clear()
			}
		}
	}

	return nil
}
Example #3
0
// addUplink adds a dummy uplink to ofnet agent
func addUplink(ofa *OfnetAgent, linkName string, ofpPortNo uint32) (*netlink.Veth, error) {
	link := &netlink.Veth{
		LinkAttrs: netlink.LinkAttrs{
			Name:   linkName,
			TxQLen: 100,
			MTU:    1400,
		},
		PeerName: linkName + "peer",
	}
	// delete old link if it exists.. and ignore error
	netlink.LinkDel(link)
	time.Sleep(100 * time.Millisecond)

	if err := netlink.LinkAdd(link); err != nil {
		return nil, err
	}

	// add it to ofnet
	err := ofa.AddUplink(ofpPortNo, linkName)
	if err != nil {
		return nil, err
	}
	time.Sleep(time.Second)

	// mark the link as up
	if err := netlink.LinkSetUp(link); err != nil {
		return nil, err
	}

	return link, nil
}
Example #4
0
func createDummyInterface(t *testing.T) {
	if testutils.RunningOnCircleCI() {
		t.Skipf("Skipping as not supported on CIRCLE CI kernel")
	}

	dummy := &netlink.Dummy{
		LinkAttrs: netlink.LinkAttrs{
			Name: "dummy",
		},
	}

	err := netlink.LinkAdd(dummy)
	require.NoError(t, err)

	dummyLink, err := netlink.LinkByName("dummy")
	require.NoError(t, err)

	ip, ipNet, err := net.ParseCIDR("10.1.1.1/24")
	require.NoError(t, err)

	ipNet.IP = ip

	ipAddr := &netlink.Addr{IPNet: ipNet, Label: ""}
	err = netlink.AddrAdd(dummyLink, ipAddr)
	require.NoError(t, err)
}
Example #5
0
func createInterface(t *testing.T, name string, nws ...string) {
	// Add interface
	link := &netlink.Bridge{
		LinkAttrs: netlink.LinkAttrs{
			Name: "test",
		},
	}
	bips := []*net.IPNet{}
	for _, nw := range nws {
		bip, err := types.ParseCIDR(nw)
		if err != nil {
			t.Fatal(err)
		}
		bips = append(bips, bip)
	}
	if err := netlink.LinkAdd(link); err != nil {
		t.Fatalf("Failed to create interface via netlink: %v", err)
	}
	for _, bip := range bips {
		if err := netlink.AddrAdd(link, &netlink.Addr{IPNet: bip}); err != nil {
			t.Fatal(err)
		}
	}
	if err := netlink.LinkSetUp(link); err != nil {
		t.Fatal(err)
	}
}
Example #6
0
func testBridgeSimpleSetup(t *testing.T, nsPrefix string, br *netlink.Bridge) (
	*netlink.Bridge, []*netlink.Veth, []netns.NsHandle, func()) {
	links, nets, cleanup := testNetnsPair(t, nsPrefix)

	if br == nil {
		br = &netlink.Bridge{
			LinkAttrs: netlink.LinkAttrs{
				Name: "br0",
			},
		}
		if err := netlink.LinkAdd(br); err != nil {
			cleanup()
			t.Fatal(err)
		}
	}

	cleanup2 := func() {
		netlink.LinkDel(br)
		cleanup()
	}

	if err := netlink.LinkSetMaster(links[0], br); err != nil {
		cleanup2()
		t.Fatal(err)
	}
	if err := netlink.LinkSetMaster(links[1], br); err != nil {
		cleanup2()
		t.Fatal(err)
	}
	if err := netlink.LinkSetUp(br); err != nil {
		cleanup2()
		t.Fatal(err)
	}
	return br, links, nets, cleanup2
}
Example #7
0
// create endpoint call
func (driver *driver) createEndpoint(w http.ResponseWriter, r *http.Request) {
	var create api.CreateEndpointRequest
	if err := json.NewDecoder(r.Body).Decode(&create); err != nil {
		sendError(w, "Unable to decode JSON payload: "+err.Error(), http.StatusBadRequest)
		return
	}
	Log.Infof("Create endpoint request %+v", &create)

	endID := create.EndpointID

	ip := create.Interface.Address
	Log.Infof("Got IP from IPAM %s", ip)

	local := vethPair(endID[:5])
	if err := netlink.LinkAdd(local); err != nil {
		Log.Error(err)
		errorResponse(w, "could not create veth pair")
		return
	}
	link, _ := netlink.LinkByName(local.PeerName)
	mac := link.Attrs().HardwareAddr.String()

	resp := &api.CreateEndpointResponse{
		Interface: &api.EndpointInterface{
			MacAddress: mac,
		},
	}

	objectResponse(w, resp)
	Log.Infof("Create endpoint %s %+v", endID, resp)
}
Example #8
0
File: bridge.go Project: aanm/cni
func ensureBridge(brName string, mtu int) (*netlink.Bridge, error) {
	br := &netlink.Bridge{
		LinkAttrs: netlink.LinkAttrs{
			Name: brName,
			MTU:  mtu,
		},
	}

	if err := netlink.LinkAdd(br); err != nil {
		if err != syscall.EEXIST {
			return nil, fmt.Errorf("could not add %q: %v", brName, err)
		}

		// it's ok if the device already exists as long as config is similar
		br, err = bridgeByName(brName)
		if err != nil {
			return nil, err
		}
	}

	if err := netlink.LinkSetUp(br); err != nil {
		return nil, err
	}

	return br, nil
}
Example #9
0
func (d *Driver) Join(r *dknet.JoinRequest) (*dknet.JoinResponse, error) {
	// create and attach local name to the bridge
	localVethPair := vethPair(truncateID(r.EndpointID))
	if err := netlink.LinkAdd(localVethPair); err != nil {
		log.Errorf("failed to create the veth pair named: [ %v ] error: [ %s ] ", localVethPair, err)
		return nil, err
	}
	// Bring the veth pair up
	err := netlink.LinkSetUp(localVethPair)
	if err != nil {
		log.Warnf("Error enabling  Veth local iface: [ %v ]", localVethPair)
		return nil, err
	}
	bridgeName := d.networks[r.NetworkID].BridgeName
	err = d.addOvsVethPort(bridgeName, localVethPair.Name, 0)
	if err != nil {
		log.Errorf("error attaching veth [ %s ] to bridge [ %s ]", localVethPair.Name, bridgeName)
		return nil, err
	}
	log.Infof("Attached veth [ %s ] to bridge [ %s ]", localVethPair.Name, bridgeName)

	// SrcName gets renamed to DstPrefix + ID on the container iface
	res := &dknet.JoinResponse{
		InterfaceName: dknet.InterfaceName{
			SrcName:   localVethPair.PeerName,
			DstPrefix: containerEthName,
		},
		Gateway: d.networks[r.NetworkID].Gateway,
	}
	log.Debugf("Join endpoint %s:%s to %s", r.NetworkID, r.EndpointID, r.SandboxKey)
	return res, nil
}
Example #10
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
}
Example #11
0
func ensureBridge(brName string, mtu int) (*netlink.Bridge, error) {
	br := &netlink.Bridge{
		LinkAttrs: netlink.LinkAttrs{
			Name: brName,
			MTU:  mtu,
			// Let kernel use default txqueuelen; leaving it unset
			// means 0, and a zero-length TX queue messes up FIFO
			// traffic shapers which use TX queue length as the
			// default packet limit
			TxQLen: -1,
		},
	}

	if err := netlink.LinkAdd(br); err != nil {
		if err != syscall.EEXIST {
			return nil, fmt.Errorf("could not add %q: %v", brName, err)
		}

		// it's ok if the device already exists as long as config is similar
		br, err = bridgeByName(brName)
		if err != nil {
			return nil, err
		}
	}

	if err := netlink.LinkSetUp(br); err != nil {
		return nil, err
	}

	return br, nil
}
Example #12
0
func createVethPair() (string, string, error) {
	defer osl.InitOSContext()()

	// Generate a name for what will be the host side pipe interface
	name1, err := netutils.GenerateIfaceName(vethPrefix, vethLen)
	if err != nil {
		return "", "", fmt.Errorf("error generating veth name1: %v", err)
	}

	// Generate a name for what will be the sandbox side pipe interface
	name2, err := netutils.GenerateIfaceName(vethPrefix, vethLen)
	if err != nil {
		return "", "", fmt.Errorf("error generating veth name2: %v", err)
	}

	// Generate and add the interface pipe host <-> sandbox
	veth := &netlink.Veth{
		LinkAttrs: netlink.LinkAttrs{Name: name1, TxQLen: 0},
		PeerName:  name2}
	if err := netlink.LinkAdd(veth); err != nil {
		return "", "", fmt.Errorf("error creating veth pair: %v", err)
	}

	return name1, name2, nil
}
Example #13
0
// Create creates a bridge device and returns the interface.
// If the device already exists, returns the existing interface.
func (Bridge) Create(name string, ip net.IP, subnet *net.IPNet) (intf *net.Interface, err error) {
	netlinkMu.Lock()
	defer netlinkMu.Unlock()

	if intf, _ := net.InterfaceByName(name); intf != nil {
		return intf, nil
	}

	link := &netlink.Bridge{LinkAttrs: netlink.LinkAttrs{Name: name}}

	if err := netlink.LinkAdd(link); err != nil && err.Error() != "file exists" {
		return nil, fmt.Errorf("devices: create bridge: %v", err)
	}

	hAddr, _ := net.ParseMAC(randMacAddr())
	err = netlink.LinkSetHardwareAddr(link, hAddr)
	if err != nil {
		return nil, fmt.Errorf("devices: set hardware address: %v", err)
	}

	if intf, err = net.InterfaceByName(name); err != nil {
		return nil, fmt.Errorf("devices: look up created bridge interface: %v", err)
	}

	addr := &netlink.Addr{IPNet: &net.IPNet{IP: ip, Mask: subnet.Mask}}
	if err = netlink.AddrAdd(link, addr); err != nil && err.Error() != "file exists" {
		return nil, fmt.Errorf("devices: add IP to bridge: %v", err)
	}
	return intf, nil
}
Example #14
0
func endpointCreate() {
	hostIfName := "myveth0"
	containerIfName := "myveth1"

	veth, err := netlink.LinkByName("myveth0")
	if err == nil && veth != nil {
		return
	}

	veth = &netlink.Veth{
		LinkAttrs: netlink.LinkAttrs{Name: hostIfName, TxQLen: 0},
		PeerName:  containerIfName}

	if err := netlink.LinkAdd(veth); err != nil {
		panic(err)
	}

	la := netlink.NewLinkAttrs()
	la.Name = "mycbridge"
	mybridge := &netlink.Bridge{la}

	err = netlink.LinkSetMaster(veth, mybridge)
	if err != nil {
		panic(err)
	}

	err = netlink.LinkSetUp(veth)
	if err != nil {
		panic(err)
	}
}
Example #15
0
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
}
Example #16
0
// SetupDevice create a new bridge interface/
func setupDevice(config *networkConfiguration, i *bridgeInterface) error {
	// We only attempt to create the bridge when the requested device name is
	// the default one.
	if config.BridgeName != DefaultBridgeName && !config.AllowNonDefaultBridge {
		return NonDefaultBridgeExistError(config.BridgeName)
	}

	// Set the bridgeInterface netlink.Bridge.
	i.Link = &netlink.Bridge{
		LinkAttrs: netlink.LinkAttrs{
			Name: config.BridgeName,
		},
	}

	// Only set the bridge's MAC address if the kernel version is > 3.3, as it
	// was not supported before that.
	kv, err := kernel.GetKernelVersion()
	if err == nil && (kv.Kernel >= 3 && kv.Major >= 3) {
		i.Link.Attrs().HardwareAddr = netutils.GenerateRandomMAC()
		log.Debugf("Setting bridge mac address to %s", i.Link.Attrs().HardwareAddr)
	}

	// Call out to netlink to create the device.
	if err = netlink.LinkAdd(i.Link); err != nil {
		return types.InternalErrorf("Failed to program bridge link: %s", err.Error())
	}
	return nil
}
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)
}
Example #18
0
File: veth.go Project: n054/weave
// 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
}
Example #19
0
func (driver *driver) joinEndpoint(w http.ResponseWriter, r *http.Request) {
	var j join
	if err := json.NewDecoder(r.Body).Decode(&j); err != nil {
		sendError(w, "Could not decode JSON encode payload", http.StatusBadRequest)
		return
	}
	Log.Debugf("Join request: %+v", &j)

	endID := j.EndpointID

	// create and attach local name to the bridge
	local := vethPair(endID[:5])
	if err := netlink.LinkAdd(local); err != nil {
		Log.Error(err)
		errorResponsef(w, "could not create veth pair")
		return
	}

	var bridge *netlink.Bridge
	if maybeBridge, err := netlink.LinkByName(WeaveBridge); err != nil {
		Log.Error(err)
		errorResponsef(w, `bridge "%s" not present`, WeaveBridge)
		return
	} else {
		var ok bool
		if bridge, ok = maybeBridge.(*netlink.Bridge); !ok {
			Log.Errorf("%s is %+v", WeaveBridge, maybeBridge)
			errorResponsef(w, `device "%s" not a bridge`, WeaveBridge)
			return
		}
	}
	if netlink.LinkSetMaster(local, bridge) != nil || netlink.LinkSetUp(local) != nil {
		errorResponsef(w, `unable to bring veth up`)
		return
	}

	ifname := &iface{
		SrcName:   local.PeerName,
		DstPrefix: "ethwe",
		ID:        0,
	}

	res := &joinResponse{
		InterfaceNames: []*iface{ifname},
	}
	if driver.nameserver != "" {
		routeToDNS := &staticRoute{
			Destination: driver.nameserver + "/32",
			RouteType:   types.CONNECTED,
			NextHop:     "",
			InterfaceID: 0,
		}
		res.StaticRoutes = []*staticRoute{routeToDNS}
	}

	objectResponse(w, res)
	Log.Infof("Join endpoint %s:%s to %s", j.NetworkID, j.EndpointID, j.SandboxKey)
}
Example #20
0
File: driver.go Project: brb/weave
func (driver *driver) JoinEndpoint(j *api.JoinRequest) (*api.JoinResponse, error) {
	endID := j.EndpointID

	maybeBridge, err := netlink.LinkByName(WeaveBridge)
	if err != nil {
		return nil, errorf(`bridge "%s" not present; did you launch weave?`, WeaveBridge)
	}

	// create and attach local name to the bridge
	local := vethPair(endID[:5])
	local.Attrs().MTU = maybeBridge.Attrs().MTU
	if err := netlink.LinkAdd(local); err != nil {
		return nil, errorf("could not create veth pair: %s", err)
	}

	switch maybeBridge.(type) {
	case *netlink.Bridge:
		if err := netlink.LinkSetMasterByIndex(local, maybeBridge.Attrs().Index); err != nil {
			return nil, errorf(`unable to set master: %s`, err)
		}
	case *netlink.GenericLink:
		if maybeBridge.Type() != "openvswitch" {
			Log.Errorf("device %s is %+v", WeaveBridge, maybeBridge)
			return nil, errorf(`device "%s" is of type "%s"`, WeaveBridge, maybeBridge.Type())
		}
		odp.AddDatapathInterface(WeaveBridge, local.Name)
	case *netlink.Device:
		Log.Warnf("kernel does not report what kind of device %s is, just %+v", WeaveBridge, maybeBridge)
		// Assume it's our openvswitch device, and the kernel has not been updated to report the kind.
		odp.AddDatapathInterface(WeaveBridge, local.Name)
	default:
		Log.Errorf("device %s is %+v", WeaveBridge, maybeBridge)
		return nil, errorf(`device "%s" not a bridge`, WeaveBridge)
	}
	if err := netlink.LinkSetUp(local); err != nil {
		return nil, errorf(`unable to bring veth up: %s`, err)
	}

	ifname := &api.InterfaceName{
		SrcName:   local.PeerName,
		DstPrefix: "ethwe",
	}

	response := &api.JoinResponse{
		InterfaceName: ifname,
	}
	if !driver.noMulticastRoute {
		multicastRoute := api.StaticRoute{
			Destination: "224.0.0.0/4",
			RouteType:   types.CONNECTED,
		}
		response.StaticRoutes = append(response.StaticRoutes, multicastRoute)
	}
	Log.Infof("Join endpoint %s:%s to %s", j.NetworkID, j.EndpointID, j.SandboxKey)
	return response, nil
}
Example #21
0
func (driver *driver) joinEndpoint(w http.ResponseWriter, r *http.Request) {
	var j join
	if err := json.NewDecoder(r.Body).Decode(&j); err != nil {
		sendError(w, "Could not decode JSON encode payload", http.StatusBadRequest)
		return
	}
	log.Debugf("Join request: %+v", &j)

	endID := j.EndpointID
	// unique name while still on the common netns
	preMoveName := endID[:5]
	mode, err := setVlanMode(macvlanMode)
	if err != nil {
		log.Errorf("error parsing vlan mode [ %v ]: %s", mode, err)
		return
	}
	// Get the link for the master index (Example: the docker host eth iface)
	hostEth, err := netlink.LinkByName(macvlanEthIface)
	if err != nil {
		log.Warnf("Error looking up the parent iface [ %s ] mode: [ %s ] error: [ %s ]", macvlanEthIface, mode, err)
	}
	macvlan := &netlink.Macvlan{
		LinkAttrs: netlink.LinkAttrs{
			Name:        preMoveName,
			ParentIndex: hostEth.Attrs().Index,
		},
		Mode: mode,
	}
	if err := netlink.LinkAdd(macvlan); err != nil {
		log.Errorf("failed to create Macvlan: [ %v ] with the error: %s", macvlan, err)
		log.Error("Ensure there are no existing [ ipvlan ] type links and remove with 'ip link del <link_name>'," +
			" also check `/var/run/docker/netns/` for orphaned links to unmount and delete, then restart the plugin")
		return
	}
	log.Infof("Created Macvlan port: [ %s ] using the mode: [ %s ]", macvlan.Name, macvlanMode)
	// Set the netlink iface MTU, default is 1500
	if err := netlink.LinkSetMTU(macvlan, defaultMTU); err != nil {
		log.Errorf("Error setting the MTU [ %d ] for link [ %s ]: %s", defaultMTU, macvlan.Name, err)
	}
	// Bring the netlink iface up
	if err := netlink.LinkSetUp(macvlan); err != nil {
		log.Warnf("failed to enable the [ macvlan ] netlink link: [ %v ]", macvlan, err)
	}
	// SrcName gets renamed to DstPrefix on the container iface
	ifname := &InterfaceName{
		SrcName:   macvlan.Name,
		DstPrefix: containerIfacePrefix,
	}
	res := &joinResponse{
		InterfaceName: *ifname,
		Gateway:       gatewayIP,
	}
	objectResponse(w, res)
	log.Debugf("Join endpoint %s:%s to %s", j.NetworkID, j.EndpointID, j.SandboxKey)
}
Example #22
0
File: kvm.go Project: nhlfr/rkt
// setupTapDevice creates persistent macvtap device
// and returns a newly created netlink.Link structure
// using part of pod hash and interface number in interface name
func setupMacVTapDevice(podID types.UUID, config MacVTapNetConf, interfaceNumber int) (netlink.Link, error) {
	master, err := netlink.LinkByName(config.Master)
	if err != nil {
		return nil, errwrap.Wrap(fmt.Errorf("cannot find master device '%v'", config.Master), err)
	}
	var mode netlink.MacvlanMode
	switch config.Mode {
	// if not set - defaults to bridge mode as in:
	// https://github.com/coreos/rkt/blob/master/Documentation/networking.md#macvlan
	case "", "bridge":
		mode = netlink.MACVLAN_MODE_BRIDGE
	case "private":
		mode = netlink.MACVLAN_MODE_PRIVATE
	case "vepa":
		mode = netlink.MACVLAN_MODE_VEPA
	case "passthru":
		mode = netlink.MACVLAN_MODE_PASSTHRU
	default:
		return nil, fmt.Errorf("unsupported macvtap mode: %v", config.Mode)
	}
	mtu := master.Attrs().MTU
	if config.MTU != 0 {
		mtu = config.MTU
	}
	interfaceName := fmt.Sprintf("rkt-%s-vtap%d", podID.String()[0:4], interfaceNumber)
	link := &netlink.Macvtap{
		Macvlan: netlink.Macvlan{
			LinkAttrs: netlink.LinkAttrs{
				Name:        interfaceName,
				MTU:         mtu,
				ParentIndex: master.Attrs().Index,
			},
			Mode: mode,
		},
	}

	if err := netlink.LinkAdd(link); err != nil {
		return nil, errwrap.Wrap(errors.New("cannot create macvtap interface"), err)
	}

	// TODO: duplicate following lines for ipv6 support, when it will be added in other places
	ipv4SysctlValueName := fmt.Sprintf(IPv4InterfaceArpProxySysctlTemplate, interfaceName)
	if _, err := cnisysctl.Sysctl(ipv4SysctlValueName, "1"); err != nil {
		// remove the newly added link and ignore errors, because we already are in a failed state
		_ = netlink.LinkDel(link)
		return nil, errwrap.Wrap(fmt.Errorf("failed to set proxy_arp on newly added interface %q", interfaceName), err)
	}

	if err := netlink.LinkSetUp(link); err != nil {
		// remove the newly added link and ignore errors, because we already are in a failed state
		_ = netlink.LinkDel(link)
		return nil, errwrap.Wrap(errors.New("cannot set up macvtap interface"), err)
	}
	return link, nil
}
Example #23
0
func (driver *driver) JoinEndpoint(j *netApi.JoinRequest) (*netApi.JoinResponse, error) {
	log.Debugf("Join endpoint request: %+v", j)
	log.Debugf("Joining endpoint %s:%s to %s", j.NetworkID, j.EndpointID, j.SandboxKey)

	tempName := j.EndpointID[:4]
	hostName := "vethr" + j.EndpointID[:4]

	veth := &netlink.Veth{
		LinkAttrs: netlink.LinkAttrs{
			Name:   hostName,
			TxQLen: 0,
		},
		PeerName: tempName,
	}
	log.Debugf("Adding link %+v", veth)
	if err := netlink.LinkAdd(veth); err != nil {
		log.Errorf("Unable to add link %+v:%+v", veth, err)
		return nil, err
	}
	if err := netlink.LinkSetMTU(veth, 1500); err != nil {
		log.Errorf("Error setting the MTU %s", err)
	}
	log.Debugf("Bringing link up %+v", veth)
	if err := netlink.LinkSetUp(veth); err != nil {
		log.Errorf("Unable to bring up %+v: %+v", veth, err)
		return nil, err
	}
	ep := driver.network.endpoints[j.EndpointID]
	ep.iface = hostName

	iface, _ := netlink.LinkByName(hostName)
	routeAdd(ep.ipv4Address, iface)

	for _, ipa := range ep.ipAliases {
		routeAdd(ipa, iface)
	}
	respIface := &netApi.InterfaceName{
		SrcName:   tempName,
		DstPrefix: "eth",
	}
	sandboxRoute := netApi.StaticRoute{
		Destination: "0.0.0.0/0",
		RouteType:   1, // CONNECTED
		NextHop:     "",
	}
	resp := &netApi.JoinResponse{
		InterfaceName:         respIface,
		DisableGatewayService: true,
		StaticRoutes:          []netApi.StaticRoute{sandboxRoute},
	}
	log.Infof("Join Request Response %+v", resp)

	return resp, nil
}
Example #24
0
func ensureLink(vxlan *netlink.Vxlan) (*netlink.Vxlan, error) {
	err := netlink.LinkAdd(vxlan)
	if err == syscall.EEXIST {
		// it's ok if the device already exists as long as config is similar
		existing, err := netlink.LinkByName(vxlan.Name)
		if err != nil {
			return nil, err
		}

		incompat := vxlanLinksIncompat(vxlan, existing)
		if incompat == "" {
			return existing.(*netlink.Vxlan), nil
		}

		// delete existing
		log.Warningf("%q already exists with incompatable configuration: %v; recreating device", vxlan.Name, incompat)
		if err = netlink.LinkDel(existing); err != nil {
			return nil, fmt.Errorf("failed to delete interface: %v", err)
		}

		// create new
		if err = netlink.LinkAdd(vxlan); err != nil {
			return nil, fmt.Errorf("failed to create vxlan interface: %v", err)
		}
	} else if err != nil {
		return nil, err
	}

	ifindex := vxlan.Index
	link, err := netlink.LinkByIndex(vxlan.Index)
	if err != nil {
		return nil, fmt.Errorf("can't locate created vxlan device with index %v", ifindex)
	}
	var ok bool
	if vxlan, ok = link.(*netlink.Vxlan); !ok {
		return nil, fmt.Errorf("created vxlan device with index %v is not vxlan", ifindex)
	}

	return vxlan, nil
}
Example #25
0
// Adds a macvlan interface to a container for use with the egress router feature
func addMacvlan(netns string) error {
	var defIface netlink.Link
	var err error

	// Find interface with the default route
	routes, err := netlink.RouteList(nil, netlink.FAMILY_V4)
	if err != nil {
		return fmt.Errorf("failed to read routes: %v", err)
	}

	for _, r := range routes {
		if r.Dst == nil {
			defIface, err = netlink.LinkByIndex(r.LinkIndex)
			if err != nil {
				return fmt.Errorf("failed to get default route interface: %v", err)
			}
		}
	}
	if defIface == nil {
		return fmt.Errorf("failed to find default route interface")
	}

	podNs, err := ns.GetNS(netns)
	if err != nil {
		return fmt.Errorf("could not open netns %q", netns)
	}
	defer podNs.Close()

	err = netlink.LinkAdd(&netlink.Macvlan{
		LinkAttrs: netlink.LinkAttrs{
			MTU:         defIface.Attrs().MTU,
			Name:        "macvlan0",
			ParentIndex: defIface.Attrs().Index,
			Namespace:   netlink.NsFd(podNs.Fd()),
		},
		Mode: netlink.MACVLAN_MODE_PRIVATE,
	})
	if err != nil {
		return fmt.Errorf("failed to create macvlan interface: %v", err)
	}
	return podNs.Do(func(netns ns.NetNS) error {
		l, err := netlink.LinkByName("macvlan0")
		if err != nil {
			return fmt.Errorf("failed to find macvlan interface: %v", err)
		}
		err = netlink.LinkSetUp(l)
		if err != nil {
			return fmt.Errorf("failed to set macvlan interface up: %v", err)
		}
		return nil
	})
}
Example #26
0
func (n *networks) createLink(config networkConfig) error {
	//Link creation starts from checking if current vlan interface exists
	if _, err := netlink.LinkByName(config.LinkName); err != nil {
		//Try creating the link
		la := netlink.NewLinkAttrs()
		la.Name = config.LinkName
		la.ParentIndex = n.parent.Attrs().Index
		vl := &netlink.Vlan{la, config.Vlan}
		if err := netlink.LinkAdd(vl); err != nil {
			return ErrNetlinkError{"create vlan iface", err}
		}
		if err := netlink.LinkSetUp(vl); err != nil {
			return ErrNetlinkError{"bring vlan iface up", err}
		}
	}
	//Now check if bridge exists
	if _, err := netlink.LinkByName(config.BridgeName); err != nil {
		//Try creating the bridge
		la := netlink.NewLinkAttrs()
		la.Name = config.BridgeName
		br := &netlink.Bridge{la}
		if err := netlink.LinkAdd(br); err != nil {
			return ErrNetlinkError{"create bridge", err}
		}
		//Link bridge to new interface
		if li, err := netlink.LinkByName(config.LinkName); err != nil {
			netlink.LinkDel(br)
			return ErrNetlinkError{"find iface by name (" + config.LinkName + ")", err}
		} else if err := netlink.LinkSetMaster(li, br); err != nil {
			netlink.LinkDel(br)
			return ErrNetlinkError{"set bridge master", err}
		}
		if err := netlink.LinkSetUp(br); err != nil {
			return ErrNetlinkError{"bring bridge up", err}
		}
	}

	return nil
}
Example #27
0
func Add(name string) {
	if iface.Exists(name) {
		log.Printf("reusing existing bridge %s", name)
	} else {
		log.Printf("adding bridge %s", name)

		br := netlink.NewLinkAttrs()
		br.Name = name
		if err := netlink.LinkAdd(&netlink.Bridge{br}); err != nil {
			log.Fatalf("failed to add bridge %s: %s", name, err)
		}
	}
}
func setupVerifyTest(t *testing.T) *bridgeInterface {
	inf := &bridgeInterface{}

	br := netlink.Bridge{}
	br.LinkAttrs.Name = "default0"
	if err := netlink.LinkAdd(&br); err == nil {
		inf.Link = &br
	} else {
		t.Fatalf("Failed to create bridge interface: %v", err)
	}

	return inf
}
Example #29
0
func (driver *driver) JoinEndpoint(j *api.JoinRequest) (*api.JoinResponse, error) {
	endID := j.EndpointID

	// create and attach local name to the bridge
	local := vethPair(endID[:5])
	if err := netlink.LinkAdd(local); err != nil {
		return nil, errorf("could not create veth pair: %s", err)
	}

	if maybeBridge, err := netlink.LinkByName(WeaveBridge); err != nil {
		return nil, errorf(`bridge "%s" not present; did you launch weave?`, WeaveBridge)
	} else {
		switch maybeBridge.(type) {
		case *netlink.Bridge:
			if err := netlink.LinkSetMasterByIndex(local, maybeBridge.Attrs().Index); err != nil {
				return nil, errorf(`unable to set master: %s`, err)
			}
		case *netlink.GenericLink:
			if maybeBridge.Type() != "openvswitch" {
				Log.Errorf("device %s is %+v", WeaveBridge, maybeBridge)
				return nil, errorf(`device "%s" is of type "%s"`, WeaveBridge, maybeBridge.Type())
			}
			odp.AddDatapathInterface(WeaveBridge, local.Name)
		default:
			Log.Errorf("device %s is %+v", WeaveBridge, maybeBridge)
			return nil, errorf(`device "%s" not a bridge`, WeaveBridge)
		}
	}
	if err := netlink.LinkSetUp(local); err != nil {
		return nil, errorf(`unable to bring veth up: %s`, err)
	}

	ifname := &api.InterfaceName{
		SrcName:   local.PeerName,
		DstPrefix: "ethwe",
	}

	response := &api.JoinResponse{
		InterfaceName: ifname,
	}
	if driver.nameserver != "" {
		routeToDNS := api.StaticRoute{
			Destination: driver.nameserver + "/32",
			RouteType:   types.CONNECTED,
			NextHop:     "",
		}
		response.StaticRoutes = []api.StaticRoute{routeToDNS}
	}
	Log.Infof("Join endpoint %s:%s to %s", j.NetworkID, j.EndpointID, j.SandboxKey)
	return response, nil
}
Example #30
0
func CreateVeth(vethNameHost, vethNameNSTemp string) error {
	veth := &netlink.Veth{
		LinkAttrs: netlink.LinkAttrs{
			Name: vethNameHost,
		},
		PeerName: vethNameNSTemp,
	}
	if err := netlink.LinkAdd(veth); err != nil {
		return err
	}

	err := netlink.LinkSetUp(veth)
	return err
}