func cmdAdd(args *skel.CmdArgs) error { n, err := loadConf(args.StdinData) if err != nil { return err } netns, err := ns.GetNS(args.Netns) if err != nil { return fmt.Errorf("failed to open netns %q: %v", netns, err) } defer netns.Close() if err = createMacvlan(n, args.IfName, netns); err != nil { return err } // run the IPAM plugin and get back the config to apply result, err := ipam.ExecAdd(n.IPAM.Type, args.StdinData) if err != nil { return err } if result.IP4 == nil { return errors.New("IPAM plugin returned missing IPv4 config") } err = netns.Do(func(_ ns.NetNS) error { return ipam.ConfigureIface(args.IfName, result) }) if err != nil { return err } result.DNS = n.DNS return result.Print() }
func (e *podEnv) podNSLoad() (ns.NetNS, error) { podNSPath, err := e.podNSPathLoad() if err != nil && !podNSerrorOK(podNSPath, err) { return nil, err } else { podNS, err := ns.GetNS(podNSPath) if err != nil && !podNSerrorOK(podNSPath, err) { return nil, err } return podNS, 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 (e *podEnv) podNSLoad() error { podNSPath, err := e.podNSPathLoad() if err != nil && !podNSerrorOK(podNSPath, err) { return err } else { podNS, err := ns.GetNS(podNSPath) if err != nil && !podNSerrorOK(podNSPath, err) { return err } e.podNS = podNS return nil } }
// For a given container, returns host veth name, container veth MAC, and pod IP func getVethInfo(netns, containerIfname string) (string, string, string, error) { var ( peerIfindex int contVeth netlink.Link err error podIP string ) containerNs, err := ns.GetNS(netns) if err != nil { return "", "", "", fmt.Errorf("failed to get container netns: %v", err) } defer containerNs.Close() err = containerNs.Do(func(ns.NetNS) error { contVeth, err = netlink.LinkByName(containerIfname) if err != nil { return err } peerIfindex = contVeth.Attrs().ParentIndex addrs, err := netlink.AddrList(contVeth, syscall.AF_INET) if err != nil { return fmt.Errorf("failed to get container IP addresses: %v", err) } if len(addrs) == 0 { return fmt.Errorf("container had no addresses") } podIP = addrs[0].IP.String() return nil }) if err != nil { return "", "", "", fmt.Errorf("failed to inspect container interface: %v", err) } hostVeth, err := netlink.LinkByIndex(peerIfindex) if err != nil { return "", "", "", fmt.Errorf("failed to get host veth: %v", err) } return hostVeth.Attrs().Name, contVeth.Attrs().HardwareAddr.String(), podIP, nil }
func ReleaseVF(conf *NetConf) error { netns, err := ns.GetNS(conf.NetNs) if err != nil { return fmt.Errorf("failed to open netns %q: %v", netns, err) } defer netns.Close() initns, err := ns.GetCurrentNS() if err != nil { return fmt.Errorf("failed to open init ns: %v", err) } defer initns.Close() err = netns.Do(func(_ ns.NetNS) error { return releaseVF(conf, conf.IfName, initns) }) return nil }
func SetupVF(conf *NetConf) error { netns, err := ns.GetNS(conf.NetNs) if err != nil { return fmt.Errorf("failed to open netns %q: %v", netns, err) } defer netns.Close() if err = setupVF(conf, conf.IfName, netns); err != nil { return err } err = netns.Do(func(_ ns.NetNS) error { return configureIface(conf) }) if err != nil { return err } return nil }
for _, netnsPath := range allNetNSInCurrentProcess() { netnsInode, err := getInode(netnsPath) Expect(err).NotTo(HaveOccurred()) Expect(netnsInode).NotTo(Equal(createdNetNSInode)) } }) It("fails when the path is not a namespace", func() { tempFile, err := ioutil.TempFile("", "nstest") Expect(err).NotTo(HaveOccurred()) defer tempFile.Close() nspath := tempFile.Name() defer os.Remove(nspath) _, err = ns.GetNS(nspath) Expect(err).To(HaveOccurred()) Expect(err).To(BeAssignableToTypeOf(ns.NSPathNotNSErr{})) Expect(err).NotTo(BeAssignableToTypeOf(ns.NSPathNotExistErr{})) }) }) Describe("closing a network namespace", func() { It("should prevent further operations", func() { createdNetNS, err := ns.NewNS() Expect(err).NotTo(HaveOccurred()) err = createdNetNS.Close() Expect(err).NotTo(HaveOccurred()) err = createdNetNS.Do(func(ns.NetNS) error { return nil })
func cmdAdd(args *skel.CmdArgs) error { n, err := loadNetConf(args.StdinData) if err != nil { return err } if n.IsDefaultGW { n.IsGW = true } br, err := setupBridge(n) if err != nil { return err } netns, err := ns.GetNS(args.Netns) if err != nil { return fmt.Errorf("failed to open netns %q: %v", args.Netns, err) } defer netns.Close() if err = setupVeth(netns, br, args.IfName, n.MTU, n.HairpinMode); err != nil { return err } // run the IPAM plugin and get back the config to apply result, err := ipam.ExecAdd(n.IPAM.Type, args.StdinData) if err != nil { return err } // TODO: make this optional when IPv6 is supported if result.IP4 == nil { return errors.New("IPAM plugin returned missing IPv4 config") } if result.IP4.Gateway == nil && n.IsGW { result.IP4.Gateway = calcGatewayIP(&result.IP4.IP) } if err := netns.Do(func(_ ns.NetNS) error { // set the default gateway if requested if n.IsDefaultGW { _, defaultNet, err := net.ParseCIDR("0.0.0.0/0") if err != nil { return err } for _, route := range result.IP4.Routes { if defaultNet.String() == route.Dst.String() { if route.GW != nil && !route.GW.Equal(result.IP4.Gateway) { return fmt.Errorf( "isDefaultGateway ineffective because IPAM sets default route via %q", route.GW, ) } } } result.IP4.Routes = append( result.IP4.Routes, types.Route{Dst: *defaultNet, GW: result.IP4.Gateway}, ) // TODO: IPV6 } if err := ipam.ConfigureIface(args.IfName, result); err != nil { return err } if err := ip.SetHWAddrByIP(args.IfName, result.IP4.IP.IP, nil /* TODO IPv6 */); err != nil { return err } return nil }); err != nil { return err } if n.IsGW { gwn := &net.IPNet{ IP: result.IP4.Gateway, Mask: result.IP4.IP.Mask, } if err = ensureBridgeAddr(br, gwn, n.ForceAddress); err != nil { return err } if err := ip.SetHWAddrByIP(n.BrName, gwn.IP, nil /* TODO IPv6 */); err != nil { return err } if err := ip.EnableIP4Forward(); err != nil { return fmt.Errorf("failed to enable forwarding: %v", err) } } if n.IPMasq { chain := utils.FormatChainName(n.Name, args.ContainerID) comment := utils.FormatComment(n.Name, args.ContainerID) if err = ip.SetupIPMasq(ip.Network(&result.IP4.IP), chain, comment); err != nil { return err } } result.DNS = n.DNS return result.Print() }
Protocol: syscall.RTPROT_BOOT, Table: syscall.RT_TABLE_MAIN, Type: syscall.RTN_UNICAST, }))) session, err = DeleteContainer(netconf, netnspath, "") Expect(err).ShouldNot(HaveOccurred()) Eventually(session).Should(gexec.Exit()) // Make sure there are no endpoints anymore endpoints, err = calicoClient.WorkloadEndpoints().List(api.WorkloadEndpointMetadata{}) Expect(err).ShouldNot(HaveOccurred()) Expect(endpoints.Items).Should(HaveLen(0)) // Make sure the interface has been removed from the namespace targetNs, _ := ns.GetNS(netnspath) err = targetNs.Do(func(_ ns.NetNS) error { _, err = netlink.LinkByName("eth0") return err }) Expect(err).Should(HaveOccurred()) Expect(err.Error()).Should(Equal("Link not found")) // Make sure the interface has been removed from the host _, err = netlink.LinkByName("cali" + containerID) Expect(err).Should(HaveOccurred()) Expect(err.Error()).Should(Equal("Link not found")) }) }) })
func cmdAdd(args *skel.CmdArgs) error { n, err := loadNetConf(args.StdinData) if err != nil { return err } log.Debugf("Args %s", args) c, err := cnc.NewDefaultClient() if err != nil { return fmt.Errorf("error while starting cilium-client: %s", err) } netNs, err := ns.GetNS(args.Netns) if err != nil { return fmt.Errorf("failed to open netns %q: %s", args.Netns, err) } defer netNs.Close() if err := removeIfFromNSIfExists(netNs, args.IfName); err != nil { return fmt.Errorf("failed removing interface %q from namespace %q: %s", args.IfName, args.Netns, err) } var ep endpoint.Endpoint veth, peer, tmpIfName, err := plugins.SetupVeth(args.ContainerID, n.MTU, &ep) if err != nil { return err } defer func() { if err != nil { if err = netlink.LinkDel(veth); err != nil { log.Warningf("failed to clean up veth %q: %s", veth.Name, err) } } }() if err = netlink.LinkSetNsFd(*peer, int(netNs.Fd())); err != nil { return fmt.Errorf("unable to move veth pair %q to netns: %s", peer, err) } err = netNs.Do(func(_ ns.NetNS) error { err := renameLink(tmpIfName, args.IfName) if err != nil { return fmt.Errorf("failed to rename %q to %q: %s", tmpIfName, args.IfName, err) } return nil }) req := ipam.IPAMReq{} ipamConf, err := c.AllocateIP(ipam.CNIIPAMType, req) if err != nil { return err } defer func() { if err != nil && ipamConf != nil { if ipamConf.IP6 != nil { req := ipam.IPAMReq{IP: &ipamConf.IP6.IP.IP} if err = c.ReleaseIP(ipam.CNIIPAMType, req); err != nil { log.Warningf("failed to release allocated IPv6 of container ID %q: %s", args.ContainerID, err) } } if ipamConf.IP4 != nil { req := ipam.IPAMReq{IP: &ipamConf.IP4.IP.IP} if err = c.ReleaseIP(ipam.CNIIPAMType, req); err != nil { log.Warningf("failed to release allocated IPv4 of container ID %q: %s", args.ContainerID, err) } } } }() if err = netNs.Do(func(_ ns.NetNS) error { return configureIface(args.IfName, ipamConf) }); err != nil { return err } ep.IPv6 = addressing.DeriveCiliumIPv6(ipamConf.IP6.IP.IP) if ipamConf.IP4 != nil { ep.IPv4 = addressing.DeriveCiliumIPv4(ipamConf.IP4.IP.IP) } ep.NodeIP = ipamConf.IP6.Gateway ep.DockerID = args.ContainerID ep.SetID() if err = c.EndpointJoin(ep); err != nil { return fmt.Errorf("unable to create eBPF map: %s", err) } return createCNIReply(ipamConf) }