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 createMacvlan(conf *NetConf, ifName string, netns ns.NetNS) error { mode, err := modeFromString(conf.Mode) if err != nil { return err } m, err := netlink.LinkByName(conf.Master) if err != nil { return fmt.Errorf("failed to lookup master %q: %v", conf.Master, err) } // due to kernel bug we have to create with tmpName or it might // collide with the name on the host and error out tmpName, err := ip.RandomVethName() if err != nil { return err } mv := &netlink.Macvlan{ LinkAttrs: netlink.LinkAttrs{ MTU: conf.MTU, Name: tmpName, ParentIndex: m.Attrs().Index, Namespace: netlink.NsFd(int(netns.Fd())), }, Mode: mode, } if err := netlink.LinkAdd(mv); err != nil { return fmt.Errorf("failed to create macvlan: %v", err) } return netns.Do(func(_ ns.NetNS) error { // TODO: duplicate following lines for ipv6 support, when it will be added in other places ipv4SysctlValueName := fmt.Sprintf(IPv4InterfaceArpProxySysctlTemplate, tmpName) if _, err := sysctl.Sysctl(ipv4SysctlValueName, "1"); err != nil { // remove the newly added link and ignore errors, because we already are in a failed state _ = netlink.LinkDel(mv) return fmt.Errorf("failed to set proxy_arp on newly added interface %q: %v", tmpName, err) } err := renameLink(tmpName, ifName) if err != nil { _ = netlink.LinkDel(mv) return fmt.Errorf("failed to rename macvlan to %q: %v", ifName, err) } return nil }) }
func createIpvlan(conf *NetConf, ifName string, netns ns.NetNS) error { mode, err := modeFromString(conf.Mode) if err != nil { return err } m, err := netlink.LinkByName(conf.Master) if err != nil { return fmt.Errorf("failed to lookup master %q: %v", conf.Master, err) } // due to kernel bug we have to create with tmpname or it might // collide with the name on the host and error out tmpName, err := ip.RandomVethName() if err != nil { return err } mv := &netlink.IPVlan{ LinkAttrs: netlink.LinkAttrs{ MTU: conf.MTU, Name: tmpName, ParentIndex: m.Attrs().Index, Namespace: netlink.NsFd(int(netns.Fd())), }, Mode: mode, } if err := netlink.LinkAdd(mv); err != nil { return fmt.Errorf("failed to create ipvlan: %v", err) } return netns.Do(func(_ ns.NetNS) error { err := renameLink(tmpName, ifName) if err != nil { return fmt.Errorf("failed to rename ipvlan to %q: %v", ifName, err) } return nil }) }
// SetupVeth sets up a virtual ethernet link. // Should be in container netns, and will switch back to hostNS to set the host // veth end up. func SetupVeth(contVethName string, mtu int, hostNS ns.NetNS) (hostVeth, contVeth netlink.Link, err error) { var hostVethName string hostVethName, contVeth, err = makeVeth(contVethName, mtu) if err != nil { return } if err = netlink.LinkSetUp(contVeth); err != nil { err = fmt.Errorf("failed to set %q up: %v", contVethName, err) return } hostVeth, err = netlink.LinkByName(hostVethName) if err != nil { err = fmt.Errorf("failed to lookup %q: %v", hostVethName, err) return } if err = netlink.LinkSetNsFd(hostVeth, int(hostNS.Fd())); err != nil { err = fmt.Errorf("failed to move veth to host netns: %v", err) return } err = hostNS.Do(func(_ ns.NetNS) error { hostVeth, err := netlink.LinkByName(hostVethName) if err != nil { return fmt.Errorf("failed to lookup %q in %q: %v", hostVethName, hostNS.Path(), err) } if err = netlink.LinkSetUp(hostVeth); err != nil { return fmt.Errorf("failed to set %q up: %v", hostVethName, err) } return nil }) return }
func getInodeNS(netns ns.NetNS) (uint64, error) { return getInodeFd(int(netns.Fd())) }
func setupVF(conf *NetConf, ifName string, netns ns.NetNS) error { masterName := conf.Master vfIdx := conf.VF m, err := netlink.LinkByName(masterName) if err != nil { return fmt.Errorf("failed to lookup master %q: %v", conf.Master, err) } vfDir := fmt.Sprintf("/sys/class/net/%s/device/virtfn%d/net", masterName, vfIdx) if _, err := os.Lstat(vfDir); err != nil { return err } infos, err := ioutil.ReadDir(vfDir) if err != nil { return err } if len(infos) != 1 { return fmt.Errorf("Mutiple network devices in directory %s", vfDir) } // VF NIC name vfDevName := infos[0].Name() vfDev, err := netlink.LinkByName(vfDevName) if err != nil { return fmt.Errorf("failed to lookup vf device %q: %v", vfDevName, err) } // set hardware address if conf.MAC != "" { macAddr, err := net.ParseMAC(conf.MAC) if err != nil { return err } if err = netlink.LinkSetVfHardwareAddr(m, conf.VF, macAddr); err != nil { return fmt.Errorf("failed to set vf %d macaddress: %v", conf.VF, err) } } if conf.Vlan != 0 { if err = netlink.LinkSetVfVlan(m, conf.VF, conf.Vlan); err != nil { return fmt.Errorf("failed to set vf %d vlan: %v", conf.VF, err) } } if err = netlink.LinkSetUp(vfDev); err != nil { return fmt.Errorf("failed to setup vf %d device: %v", conf.VF, err) } // move VF device to ns if err = netlink.LinkSetNsFd(vfDev, int(netns.Fd())); err != nil { return fmt.Errorf("failed to move vf %d to netns: %v", conf.VF, err) } return netns.Do(func(_ ns.NetNS) error { err := renameLink(vfDevName, ifName) if err != nil { return fmt.Errorf("failed to rename vf %d device %q to %q: %v", conf.VF, vfDevName, ifName, err) } return nil }) }