// 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 }
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 }
// 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 }
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) }
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) } }
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 }
// 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) }
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 }
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 }
// 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 }
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 }
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 }
// 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 }
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) } }
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 }
// 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) }
// 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) 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) }
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 }
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) }
// 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 }
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 }
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 }
// 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 }) }
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 }
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 }
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 }
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 }