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 }
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) }
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 }
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 }
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 }
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 }
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} }
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) } }
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 }
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 }
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) } }
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 }
// 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 }
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 }) }
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 }
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) } }
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) }
func (t *BaseOperations) LinkSetDown(link netlink.Link) error { return netlink.LinkSetDown(link) }
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 }
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 }
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 }
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 }
//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) }