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 setupVeth(netns ns.NetNS, br *netlink.Bridge, ifName string, mtu int, hairpinMode bool) error { var hostVethName string err := netns.Do(func(hostNS ns.NetNS) error { // create the veth pair in the container and move host end into host netns hostVeth, _, err := ip.SetupVeth(ifName, mtu, hostNS) if err != nil { return err } hostVethName = hostVeth.Attrs().Name return nil }) if err != nil { return err } // need to lookup hostVeth again as its index has changed during ns move hostVeth, err := netlink.LinkByName(hostVethName) if err != nil { return fmt.Errorf("failed to lookup %q: %v", hostVethName, err) } // connect host veth end to the bridge if err = netlink.LinkSetMaster(hostVeth, br); err != nil { return fmt.Errorf("failed to connect %q to bridge %v: %v", hostVethName, br.Attrs().Name, err) } // set hairpin mode if err = netlink.LinkSetHairpin(hostVeth, hairpinMode); err != nil { return fmt.Errorf("failed to setup hairpin mode for %v: %v", hostVethName, err) } return nil }
func removeIfFromNSIfExists(netNs ns.NetNS, ifName string) error { return netNs.Do(func(_ ns.NetNS) error { l, err := netlink.LinkByName(ifName) if err != nil { if strings.Contains(err.Error(), "Link not found") { return nil } return err } return netlink.LinkDel(l) }) }
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())) }
return 0, err } defer file.Close() return getInodeFd(int(file.Fd())) } func getInodeFd(fd int) (uint64, error) { stat := &unix.Stat_t{} err := unix.Fstat(fd, stat) return stat.Ino, err } var _ = Describe("Linux namespace operations", func() { Describe("WithNetNS", func() { var ( originalNetNS ns.NetNS targetNetNS ns.NetNS ) BeforeEach(func() { var err error originalNetNS, err = ns.NewNS() Expect(err).NotTo(HaveOccurred()) targetNetNS, err = ns.NewNS() Expect(err).NotTo(HaveOccurred()) }) AfterEach(func() { Expect(targetNetNS.Close()).To(Succeed()) Expect(originalNetNS.Close()).To(Succeed())
package main import ( "github.com/containernetworking/cni/pkg/ns" "github.com/containernetworking/cni/pkg/skel" "github.com/containernetworking/cni/pkg/testutils" "github.com/vishvananda/netlink" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("ptp Operations", func() { var originalNS ns.NetNS BeforeEach(func() { // Create a new NetNS so we don't modify the host var err error originalNS, err = ns.NewNS() Expect(err).NotTo(HaveOccurred()) }) AfterEach(func() { Expect(originalNS.Close()).To(Succeed()) }) It("configures and deconfigures a ptp link with ADD/DEL", func() { const IFNAME = "ptp0"
return fmt.Sprintf("%s", veth.Attrs().HardwareAddr) } var _ = Describe("Link", func() { const ( ifaceFormatString string = "i%d" mtu int = 1400 ip4onehwaddr = "0a:58:01:01:01:01" ) var ( hostNetNS ns.NetNS containerNetNS ns.NetNS ifaceCounter int = 0 hostVeth netlink.Link containerVeth netlink.Link hostVethName string containerVethName string ip4one = net.ParseIP("1.1.1.1") ip4two = net.ParseIP("1.1.1.2") originalRandReader = rand.Reader ) BeforeEach(func() { var err error hostNetNS, err = ns.NewNS() Expect(err).NotTo(HaveOccurred()) containerNetNS, err = ns.NewNS() Expect(err).NotTo(HaveOccurred())
"fmt" "net" "os/exec" "strings" "github.com/containernetworking/cni/pkg/ns" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" "github.com/onsi/gomega/gbytes" "github.com/onsi/gomega/gexec" ) var _ = Describe("Loopback", func() { var ( networkNS ns.NetNS containerID string command *exec.Cmd environ []string ) BeforeEach(func() { command = exec.Command(pathToLoPlugin) var err error networkNS, err = ns.NewNS() Expect(err).NotTo(HaveOccurred()) environ = []string{ fmt.Sprintf("CNI_CONTAINERID=%s", containerID), fmt.Sprintf("CNI_NETNS=%s", networkNS.Path()), fmt.Sprintf("CNI_IFNAME=%s", "this is ignored"), fmt.Sprintf("CNI_ARGS=%s", "none"),
"github.com/containernetworking/cni/pkg/ns" "github.com/containernetworking/cni/pkg/skel" "github.com/containernetworking/cni/pkg/testutils" "github.com/containernetworking/cni/pkg/types" "github.com/vishvananda/netlink" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) const MASTER_NAME = "eth0" var _ = Describe("ipvlan Operations", func() { var originalNS ns.NetNS BeforeEach(func() { // Create a new NetNS so we don't modify the host var err error originalNS, err = ns.NewNS() Expect(err).NotTo(HaveOccurred()) err = originalNS.Do(func(ns.NetNS) error { defer GinkgoRecover() // Add master err = netlink.LinkAdd(&netlink.Dummy{ LinkAttrs: netlink.LinkAttrs{ Name: MASTER_NAME, },
"github.com/containernetworking/cni/pkg/ns" "github.com/containernetworking/cni/pkg/skel" "github.com/containernetworking/cni/pkg/testutils" "github.com/containernetworking/cni/pkg/types" "github.com/containernetworking/cni/pkg/utils/hwaddr" "github.com/vishvananda/netlink" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("bridge Operations", func() { var originalNS ns.NetNS BeforeEach(func() { // Create a new NetNS so we don't modify the host var err error originalNS, err = ns.NewNS() Expect(err).NotTo(HaveOccurred()) }) AfterEach(func() { Expect(originalNS.Close()).To(Succeed()) }) It("creates a bridge", func() { const IFNAME = "bridge0"
"net" "syscall" "github.com/containernetworking/cni/pkg/ns" "github.com/containernetworking/cni/pkg/skel" "github.com/containernetworking/cni/pkg/testutils" "github.com/containernetworking/cni/pkg/types" "github.com/vishvananda/netlink" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("bridge Operations", func() { var originalNS ns.NetNS BeforeEach(func() { // Create a new NetNS so we don't modify the host var err error originalNS, err = ns.NewNS() Expect(err).NotTo(HaveOccurred()) }) AfterEach(func() { Expect(originalNS.Close()).To(Succeed()) }) It("creates a bridge", func() { const IFNAME = "bridge0"
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 }) }