func programGateway(path string, gw net.IP) error { runtime.LockOSThread() defer runtime.UnlockOSThread() origns, err := netns.Get() if err != nil { return err } defer origns.Close() f, err := os.OpenFile(path, os.O_RDONLY, 0) if err != nil { return fmt.Errorf("failed get network namespace %q: %v", path, err) } defer f.Close() nsFD := f.Fd() if err = netns.Set(netns.NsHandle(nsFD)); err != nil { return err } defer netns.Set(origns) gwRoutes, err := netlink.RouteGet(gw) if err != nil { return fmt.Errorf("route for the gateway could not be found: %v", err) } return netlink.RouteAdd(&netlink.Route{ Scope: netlink.SCOPE_UNIVERSE, LinkIndex: gwRoutes[0].LinkIndex, Gw: gw, }) }
func setUpVLan(cid, ips string, pid int, veth netlink.Link) bool { runtime.LockOSThread() defer runtime.UnlockOSThread() origns, err := netns.Get() if err != nil { logs.Info("Get orignal namespace failed", err) return false } defer origns.Close() ns, err := netns.GetFromPid(pid) if err != nil { logs.Info("Get container namespace failed", err) return false } netns.Set(ns) defer ns.Close() defer netns.Set(origns) if err := BindAndSetup(veth, ips); err != nil { logs.Info("Bind and setup NIC failed", err) DelVlan(veth) return false } logs.Info("Add vlan device success", cid[:12]) return true }
func createGlobalInstance(t *testing.T) { var err error defer close(start) origns, err = netns.Get() if err != nil { t.Fatal(err) } if netutils.IsRunningInContainer() { testns = origns } else { testns, err = netns.New() if err != nil { t.Fatal(err) } } netOption := options.Generic{ netlabel.GenericData: options.Generic{ "BridgeName": "network", "AllowNonDefaultBridge": true, }, } net, err := createTestNetwork(bridgeNetType, "network", netOption) if err != nil { t.Fatal("new network") } _, err = net.CreateEndpoint("ep1") if err != nil { t.Fatal("createendpoint") } }
func nsInvoke(path string, prefunc func(nsFD int) error, postfunc func(callerFD int) error) error { runtime.LockOSThread() defer runtime.UnlockOSThread() origns, err := netns.Get() if err != nil { return err } defer origns.Close() f, err := os.OpenFile(path, os.O_RDONLY, 0) if err != nil { return fmt.Errorf("failed get network namespace %q: %v", path, err) } defer f.Close() nsFD := f.Fd() // Invoked before the namespace switch happens but after the namespace file // handle is obtained. if err := prefunc(int(nsFD)); err != nil { return fmt.Errorf("failed in prefunc: %v", err) } if err = netns.Set(netns.NsHandle(nsFD)); err != nil { return err } defer netns.Set(origns) // Invoked after the namespace switch. return postfunc(int(origns)) }
func checkSandbox(t *testing.T, info libnetwork.EndpointInfo) { origns, err := netns.Get() if err != nil { t.Fatalf("Could not get the current netns: %v", err) } defer origns.Close() key := info.Sandbox().Key() f, err := os.OpenFile(key, os.O_RDONLY, 0) if err != nil { t.Fatalf("Failed to open network namespace path %q: %v", key, err) } defer f.Close() runtime.LockOSThread() defer runtime.UnlockOSThread() nsFD := f.Fd() if err = netns.Set(netns.NsHandle(nsFD)); err != nil { t.Fatalf("Setting to the namespace pointed to by the sandbox %s failed: %v", key, err) } defer netns.Set(origns) _, err = netlink.LinkByName("eth0") if err != nil { t.Fatalf("Could not find the interface eth0 inside the sandbox: %v", err) } _, err = netlink.LinkByName("eth1") if err != nil { t.Fatalf("Could not find the interface eth1 inside the sandbox: %v", err) } }
func createNetworkNamespace(path string, osCreate bool) (*Info, error) { runtime.LockOSThread() defer runtime.UnlockOSThread() origns, err := netns.Get() if err != nil { return nil, err } defer origns.Close() if err := createNamespaceFile(path); err != nil { return nil, err } cmd := &exec.Cmd{ Path: reexec.Self(), Args: append([]string{"netns-create"}, path), Stdout: os.Stdout, Stderr: os.Stderr, } if osCreate { cmd.SysProcAttr = &syscall.SysProcAttr{} cmd.SysProcAttr.Cloneflags = syscall.CLONE_NEWNET } if err := cmd.Run(); err != nil { return nil, fmt.Errorf("namespace creation reexec command failed: %v", err) } interfaces := []*Interface{} info := &Info{Interfaces: interfaces} return info, nil }
func NewNetNSProbe(g *graph.Graph, n *graph.Node, runPath ...string) (*NetNSProbe, error) { if uid := os.Geteuid(); uid != 0 { return nil, errors.New("NetNS probe has to be run as root") } path := "/var/run/netns" if len(runPath) > 0 && runPath[0] != "" { path = runPath[0] } rootNs, err := netns.Get() if err != nil { return nil, errors.New("Failed to get root namespace") } defer rootNs.Close() var stats syscall.Stat_t if err := syscall.Fstat(int(rootNs), &stats); err != nil { return nil, errors.New("Failed to stat root namespace") } return &NetNSProbe{ Graph: g, Root: n, nsnlProbes: make(map[string]*NetNsNetLinkTopoUpdater), pathToNetNS: make(map[string]*NetNs), runPath: path, rootNsDev: stats.Dev, }, nil }
func nsInvoke(path string, inNsfunc func(callerFD int) error) error { runtime.LockOSThread() defer runtime.UnlockOSThread() origns, err := netns.Get() if err != nil { return err } defer origns.Close() f, err := os.OpenFile(path, os.O_RDONLY, 0) if err != nil { return fmt.Errorf("failed get network namespace %q: %v", path, err) } defer f.Close() nsFD := f.Fd() if err = netns.Set(netns.NsHandle(nsFD)); err != nil { return err } defer netns.Set(origns) // Invoked after the namespace switch. return inNsfunc(int(origns)) }
func NewNetNsContext(path string) (*NetNSContext, error) { runtime.LockOSThread() origns, err := netns.Get() if err != nil { return nil, fmt.Errorf("Error while getting current ns: %s", err.Error()) } newns, err := netns.GetFromPath(path) if err != nil { origns.Close() return nil, fmt.Errorf("Error while opening %s: %s", path, err.Error()) } if err = netns.Set(newns); err != nil { newns.Close() origns.Close() return nil, fmt.Errorf("Error while switching from root ns to %s: %s", path, err.Error()) } return &NetNSContext{ origns: origns, newns: newns, }, nil }
// Init initializes a new network namespace func Init() { var err error initNs, err = netns.Get() if err != nil { log.Errorf("could not get initial namespace: %v", err) } }
func setupNetNs(nsPath string) (*os.Process, error) { runtime.LockOSThread() defer runtime.UnlockOSThread() origns, err := netns.Get() if err != nil { return nil, err } defer origns.Close() f, err := os.OpenFile(nsPath, os.O_RDONLY, 0) if err != nil { return nil, fmt.Errorf("failed to get network namespace %q: %v", nsPath, err) } defer f.Close() nsFD := f.Fd() if err := netns.Set(netns.NsHandle(nsFD)); err != nil { return nil, fmt.Errorf("failed to set network namespace %q: %v", nsPath, err) } defer netns.Set(origns) cmd := exec.Command("/bin/sh", "-c", "while true; do sleep 1; done") if err := cmd.Start(); err != nil { return nil, fmt.Errorf("failed to start netns process: %v", err) } return cmd.Process, nil }
func addRoute(cid, CIDR, ifc string, pid int) bool { runtime.LockOSThread() defer runtime.UnlockOSThread() origins, err := netns.Get() if err != nil { logs.Info("Get orignal namespace failed", err) return false } defer origins.Close() ns, err := netns.GetFromPid(pid) if err != nil { logs.Info("Get container namespace failed", err) return false } netns.Set(ns) defer ns.Close() defer netns.Set(origins) if err := addRouteByLink(CIDR, ifc); err != nil { logs.Info("Add route failed", err) return false } logs.Info("Add route success", cid[:12], CIDR, ifc) return true }
func verifySandbox(t *testing.T, s Sandbox, ifaceSuffixes []string) { _, ok := s.(*networkNamespace) if !ok { t.Fatalf("The sandox interface returned is not of type networkNamespace") } origns, err := netns.Get() if err != nil { t.Fatalf("Could not get the current netns: %v", err) } defer origns.Close() f, err := os.OpenFile(s.Key(), os.O_RDONLY, 0) if err != nil { t.Fatalf("Failed top open network namespace path %q: %v", s.Key(), err) } defer f.Close() runtime.LockOSThread() defer runtime.UnlockOSThread() nsFD := f.Fd() if err = netns.Set(netns.NsHandle(nsFD)); err != nil { t.Fatalf("Setting to the namespace pointed to by the sandbox %s failed: %v", s.Key(), err) } defer netns.Set(origns) for _, suffix := range ifaceSuffixes { _, err = netlink.LinkByName(sboxIfaceName + suffix) if err != nil { t.Fatalf("Could not find the interface %s inside the sandbox: %v", sboxIfaceName+suffix, err) } } }
func setDefaultRoute(cid, gateway string, pid int) bool { runtime.LockOSThread() defer runtime.UnlockOSThread() origins, err := netns.Get() if err != nil { logs.Info("Get orignal namespace failed", err) return false } defer origins.Close() ns, err := netns.GetFromPid(pid) if err != nil { logs.Info("Get container namespace failed", err) return false } netns.Set(ns) defer ns.Close() defer netns.Set(origins) if err := delDefaultRoute(); err != nil { logs.Info("Delete default routing table failed", err) return false } if err := addDefaultRoute(gateway); err != nil { logs.Info("Add default route failed", err) return false } logs.Info("Set default route success", cid[:12], gateway) return true }
func createGlobalInstance(t *testing.T) { var err error defer close(start) origns, err = netns.Get() if err != nil { t.Fatal(err) } if netutils.IsRunningInContainer() { testns = origns } else { testns, err = netns.New() if err != nil { t.Fatal(err) } } netOption := options.Generic{ netlabel.GenericData: options.Generic{ "BridgeName": "network", "AllowNonDefaultBridge": true, }, } net1, err := controller.NetworkByName("testhost") if err != nil { t.Fatal(err) } net2, err := createTestNetwork("bridge", "network2", netOption) if err != nil { t.Fatal(err) } _, err = net1.CreateEndpoint("pep1") if err != nil { t.Fatal(err) } _, err = net2.CreateEndpoint("pep2") if err != nil { t.Fatal(err) } _, err = net2.CreateEndpoint("pep3") if err != nil { t.Fatal(err) } if sboxes[first-1], err = controller.NewSandbox(fmt.Sprintf("%drace", first), libnetwork.OptionUseDefaultSandbox()); err != nil { t.Fatal(err) } for thd := first + 1; thd <= last; thd++ { if sboxes[thd-1], err = controller.NewSandbox(fmt.Sprintf("%drace", thd)); err != nil { t.Fatal(err) } } }
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 (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 }
// Init initializes a new network namespace func Init() { var err error initNs, err = netns.Get() if err != nil { log.Errorf("could not get initial namespace: %v", err) } initNl, err = netlink.NewHandle(getSupportedNlFamilies()...) if err != nil { log.Errorf("could not create netlink handle on initial namespace: %v", err) } }
func (tcp *tcpProxySocket) ProxyLoop(service string, proxier *Proxier) { info, found := proxier.getServiceInfo(service) if !found { glog.Errorf("Failed to find service: %s", service) return } for { if !info.isActive() { break } // Block until a connection is made. inConn, err := tcp.Accept() if err != nil { glog.Errorf("Accept failed: %v", err) continue } glog.Infof("Accepted TCP connection from %v to %v", inConn.RemoteAddr(), inConn.LocalAddr()) ns, endpoint, err := proxier.loadBalancer.NextEndpoint(service, inConn.RemoteAddr()) if err != nil { glog.Errorf("Couldn't find an endpoint for %s %v", service, err) inConn.Close() continue } glog.Infof("Mapped service %s to endpoint %s", service, endpoint) // TODO: This could spin up a new goroutine to make the outbound connection, // and keep accepting inbound traffic. if ns.IsOpen() { glog.Infof("Using namespace %v for endpoint %s", ns, endpoint) runtime.LockOSThread() defer runtime.UnlockOSThread() origns, err := netns.Get() if err != nil { glog.Errorf("Failed to get original ns: %v", err) continue } err = netns.Set(ns) if err != nil { glog.Errorf("Failed to set ns: %v", err) continue } defer netns.Set(origns) } outConn, err := retryDial("tcp", endpoint, endpointDialTimeout) if err != nil { // TODO: Try another endpoint? glog.Errorf("Dial failed: %v", err) inConn.Close() continue } // Spin up an async copy loop. proxyTCP(inConn.(*net.TCPConn), outConn.(*net.TCPConn)) } }
func createGlobalInstance(t *testing.T) { var err error defer close(start) origns, err = netns.Get() if err != nil { t.Fatal(err) } if netutils.IsRunningInContainer() { testns = origns } else { testns, err = netns.New() if err != nil { t.Fatal(err) } } netOption := options.Generic{ netlabel.GenericData: options.Generic{ "BridgeName": "network", "AllowNonDefaultBridge": true, }, } net1, err := controller.NetworkByName("testhost") if err != nil { t.Fatal(err) } net2, err := createTestNetwork("bridge", "network2", netOption) if err != nil { t.Fatal(err) } _, err = net1.CreateEndpoint("pep1") if err != nil { t.Fatal(err) } _, err = net2.CreateEndpoint("pep2") if err != nil { t.Fatal(err) } _, err = net2.CreateEndpoint("pep3") if err != nil { t.Fatal(err) } }
// Init initializes a new network namespace func Init() { var err error initNs, err = netns.Get() if err != nil { logrus.Errorf("could not get initial namespace: %v", err) } initNl, err = netlink.NewHandle(getSupportedNlFamilies()...) if err != nil { logrus.Errorf("could not create netlink handle on initial namespace: %v", err) } err = initNl.SetSocketTimeout(NetlinkSocketsTimeout) if err != nil { logrus.Warnf("Failed to set the timeout on the default netlink handle sockets: %v", err) } }
func (nu *NetNsNetLinkTopoUpdater) Start(path string) { name := getNetNSName(path) logging.GetLogger().Debugf("Starting NetLinkTopoUpdater for NetNS: %s", name) runtime.LockOSThread() defer runtime.UnlockOSThread() origns, err := netns.Get() if err != nil { logging.GetLogger().Errorf("Error while switching from root ns to %s: %s", name, err.Error()) return } defer origns.Close() time.Sleep(1 * time.Second) newns, err := netns.GetFromPath(path) if err != nil { logging.GetLogger().Errorf("Error while switching from root ns to %s: %s", name, err.Error()) return } defer newns.Close() err = netns.Set(newns) if err != nil { logging.GetLogger().Errorf("Error while switching from root ns to %s: %s", name, err.Error()) return } /* start a netlinks updater inside this namespace */ nu.Lock() nu.nlProbe = NewNetLinkProbe(nu.Graph, nu.Root) nu.Unlock() /* NOTE(safchain) don't Start just Run, need to keep it alive for the time life of the netns * and there is no need to have a new goroutine here */ nu.nlProbe.Run() nu.Lock() nu.nlProbe = nil nu.Unlock() logging.GetLogger().Debugf("NetLinkTopoUpdater stopped for NetNS: %s", name) netns.Set(origns) }
func Exec(fd *os.File, cb func() error) error { runtime.LockOSThread() defer runtime.UnlockOSThread() newns := vishnetns.NsHandle(int(fd.Fd())) origns, _ := vishnetns.Get() defer origns.Close() if err := vishnetns.Set(newns); err != nil { return fmt.Errorf("set netns: %s", err) } err := cb() mustSetNs(origns) // if this happens we definitely can't recover return err }
// NewNs creates a new network namespace and returns a handle to it. The caller // is responsible for calling Close on the handle when done with it. func NewNs() netns.NsHandle { runtime.LockOSThread() defer runtime.UnlockOSThread() origns, err := netns.Get() if err != nil { panic(err) } n, err := netns.New() if err != nil { panic(err) } if err := netns.Set(origns); err != nil { panic(err) } return n }
func EnterDockerNetNs(container *docker.Container) error { var err error origNs, err = netns.Get() if err != nil { return log.Criticalf("could not obtain current netns. netns not supported?: %s", err) } // netns.GetFromDocker() does not work for recent dockers. // So we use netns.GetFromPid() directly. // https://github.com/vishvananda/netns/pull/10 newNs, err = netns.GetFromPid(container.State.Pid) if err != nil { return log.Criticalf("Could not get netns for container %s (pid=%d). The container has exited??: %s", container.ID, container.State.Pid, err) } runtime.LockOSThread() netns.Set(newNs) return nil }
func WithNetNS(ns netns.NsHandle, work func() error) error { runtime.LockOSThread() defer runtime.UnlockOSThread() oldNs, err := netns.Get() if err == nil { defer oldNs.Close() err = netns.Set(ns) if err == nil { defer netns.Set(oldNs) err = work() } } return nil }
func networkStatsFromNs(pid int) ([]info.InterfaceStats, error) { // Lock the OS Thread so we only change the ns for this thread exclusively runtime.LockOSThread() defer runtime.UnlockOSThread() stats := []info.InterfaceStats{} // Save the current network namespace origns, _ := netns.Get() defer origns.Close() // Switch to the pid netns pidns, err := netns.GetFromPid(pid) defer pidns.Close() if err != nil { return stats, nil } netns.Set(pidns) // Defer setting back to original ns defer netns.Set(origns) ifaceStats, err := scanInterfaceStats() if err != nil { return stats, fmt.Errorf("couldn't read network stats: %v", err) } ifaces, err := net.Interfaces() if err != nil { return stats, fmt.Errorf("cannot find interfaces: %v", err) } for _, iface := range ifaces { if iface.Flags&net.FlagUp != 0 && iface.Flags&net.FlagLoopback == 0 { if s, ok := ifaceStats[iface.Name]; ok { stats = append(stats, s) } } } return stats, nil }
// GetNetlinkSocketAt opens a netlink socket in the network namespace newNs // and positions the thread back into the network namespace specified by curNs, // when done. If curNs is close, the function derives the current namespace and // moves back into it when done. If newNs is close, the socket will be opened // in the current network namespace. func GetNetlinkSocketAt(newNs, curNs netns.NsHandle, protocol int) (*NetlinkSocket, error) { var err error if newNs.IsOpen() { runtime.LockOSThread() defer runtime.UnlockOSThread() if !curNs.IsOpen() { if curNs, err = netns.Get(); err != nil { return nil, fmt.Errorf("could not get current namespace while creating netlink socket: %v", err) } defer curNs.Close() } if err := netns.Set(newNs); err != nil { return nil, fmt.Errorf("failed to set into network namespace %d while creating netlink socket: %v", newNs, err) } defer netns.Set(curNs) } return getNetlinkSocket(protocol) }
func createGlobalInstance(t *testing.T) { var err error defer close(start) origns, err = netns.Get() if err != nil { t.Fatal(err) } if netutils.IsRunningInContainer() { testns = origns } else { testns, err = netns.New() if err != nil { t.Fatal(err) } } ctrlr, err = libnetwork.New() if err != nil { t.Fatal(err) } err = ctrlr.ConfigureNetworkDriver(bridgeNetType, getEmptyGenericOption()) if err != nil { t.Fatal("configure driver") } net, err := ctrlr.NewNetwork(bridgeNetType, "network1") if err != nil { t.Fatal("new network") } _, err = net.CreateEndpoint("ep1") if err != nil { t.Fatal("createendpoint") } }
func (proxier *Proxier) AddService(service, protocol string, port int) (int, error) { glog.Infof("Adding proxy %s on %s:%d", service, proxier.address, port) if proxier.ns.IsOpen() { glog.Infof("Using namespace %v for proxy %s", proxier.ns, service) runtime.LockOSThread() defer runtime.UnlockOSThread() origns, err := netns.Get() if err != nil { return 0, err } err = netns.Set(proxier.ns) if err != nil { return 0, err } defer netns.Set(origns) } sock, err := newProxySocket(protocol, proxier.address, port) if err != nil { return 0, err } _, portStr, err := net.SplitHostPort(sock.Addr().String()) if err != nil { return 0, err } portNum, err := strconv.Atoi(portStr) if err != nil { return 0, err } proxier.setServiceInfo(service, &serviceInfo{ port: portNum, protocol: protocol, active: true, socket: sock, timeout: udpIdleTimeout, }) proxier.startAccepting(service, sock) return portNum, err }