Ejemplo n.º 1
0
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
}
Ejemplo n.º 2
0
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))
}
Ejemplo n.º 3
0
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
}
Ejemplo n.º 4
0
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))
}
Ejemplo n.º 5
0
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)
		}
	}
}
Ejemplo n.º 6
0
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
}
Ejemplo n.º 7
0
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)
	}
}
Ejemplo n.º 8
0
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
}
Ejemplo n.º 9
0
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,
	})
}
Ejemplo n.º 10
0
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
}
Ejemplo n.º 11
0
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
}
Ejemplo n.º 12
0
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))
	}
}
Ejemplo n.º 13
0
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)
}
Ejemplo n.º 14
0
func (s *NetSetup) TearDownTest(c *C) {
	s.newNS.Close()
	s.cmd.Process.Kill()
	netns.Set(s.globalNS)
	s.globalNS.Close()
	netlink.LinkDel(s.link)
}
func nsInvoke(path string, prefunc func(nsFD int) error, postfunc func(callerFD int) error) error {
	defer InitOSContext()()

	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 ns.SetNamespace()

	// Invoked after the namespace switch.
	return postfunc(ns.ParseHandlerInt())
}
Ejemplo n.º 16
0
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
}
Ejemplo n.º 17
0
func (udp *udpProxySocket) getBackendConn(activeClients *clientCache, cliAddr net.Addr, proxier *Proxier, service string, timeout time.Duration) (net.Conn, error) {
	activeClients.mu.Lock()
	defer activeClients.mu.Unlock()

	svrConn, found := activeClients.clients[cliAddr.String()]
	if !found {
		// TODO: This could spin up a new goroutine to make the outbound connection,
		// and keep accepting inbound traffic.
		glog.Infof("New UDP connection from %s", cliAddr)
		ns, endpoint, err := proxier.loadBalancer.NextEndpoint(service, cliAddr)
		if err != nil {
			glog.Errorf("Couldn't find an endpoint for %s %v", service, err)
			return nil, err
		}
		glog.Infof("Mapped service %s to endpoint %s", service, endpoint)
		if ns.IsOpen() {
			glog.Infof("Using namespace %v for endpoint %s", ns, endpoint)
			runtime.LockOSThread()
			netns.Set(ns)
			defer runtime.UnlockOSThread()
		}
		svrConn, err = retryDial("udp", endpoint, endpointDialTimeout)
		if err != nil {
			// TODO: Try another endpoint?
			glog.Errorf("Dial failed: %v", err)
			return nil, err
		}
		activeClients.clients[cliAddr.String()] = svrConn
		go func(cliAddr net.Addr, svrConn net.Conn, activeClients *clientCache, timeout time.Duration) {
			defer util.HandleCrash()
			udp.proxyClient(cliAddr, svrConn, activeClients, timeout)
		}(cliAddr, svrConn, activeClients, timeout)
	}
	return svrConn, nil
}
Ejemplo n.º 18
0
func nsContext() func() {
	runtime.LockOSThread()
	return func() {
		if err := netns.Set(initNs); err != nil {
			panic(err)
		}
		runtime.UnlockOSThread()
	}
}
Ejemplo n.º 19
0
Archivo: utils.go Proyecto: brb/weave
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
}
Ejemplo n.º 20
0
func (n *NetNSContext) Quit() error {
	if n != nil {
		if err := netns.Set(n.origns); err != nil {
			return err
		}
		n.newns.Close()
		n.origns.Close()
	}
	return nil
}
Ejemplo n.º 21
0
// InitOSContext initializes OS context while configuring network resources
func InitOSContext() func() {
	runtime.LockOSThread()
	nsOnce.Do(nsInit)
	if err := netns.Set(initNs); err != nil {
		log.Errorf("failed to set to initial namespace, link %s, initns fd %d: %v",
			getLink(), initNs, err)
	}

	return runtime.UnlockOSThread
}
Ejemplo n.º 22
0
func RunInNs(fd netns.NsHandle, fn func() error) error {
	defer nsContext()()
	if err := netns.Set(fd); err != nil {
		return err
	}
	if err := fn(); err != nil {
		return err
	}
	return nil
}
Ejemplo n.º 23
0
// SetNamespace sets the initial namespace handler
func SetNamespace() error {
	if err := netns.Set(initNs); err != nil {
		linkInfo, linkErr := getLink()
		if linkErr != nil {
			linkInfo = linkErr.Error()
		}
		return fmt.Errorf("failed to set to initial namespace, %v, initns fd %d: %v", linkInfo, initNs, err)
	}
	return nil
}
Ejemplo n.º 24
0
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
}
Ejemplo n.º 25
0
func reexecSetupResolver() {
	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	if len(os.Args) < 4 {
		log.Error("invalid number of arguments..")
		os.Exit(1)
	}

	resolverIP, ipPort, _ := net.SplitHostPort(os.Args[2])
	_, tcpPort, _ := net.SplitHostPort(os.Args[3])
	rules := [][]string{
		{"-t", "nat", "-I", outputChain, "-d", resolverIP, "-p", "udp", "--dport", dnsPort, "-j", "DNAT", "--to-destination", os.Args[2]},
		{"-t", "nat", "-I", postroutingchain, "-s", resolverIP, "-p", "udp", "--sport", ipPort, "-j", "SNAT", "--to-source", ":" + dnsPort},
		{"-t", "nat", "-I", outputChain, "-d", resolverIP, "-p", "tcp", "--dport", dnsPort, "-j", "DNAT", "--to-destination", os.Args[3]},
		{"-t", "nat", "-I", postroutingchain, "-s", resolverIP, "-p", "tcp", "--sport", tcpPort, "-j", "SNAT", "--to-source", ":" + dnsPort},
	}

	f, err := os.OpenFile(os.Args[1], os.O_RDONLY, 0)
	if err != nil {
		log.Errorf("failed get network namespace %q: %v", os.Args[1], err)
		os.Exit(2)
	}
	defer f.Close()

	nsFD := f.Fd()
	if err = netns.Set(netns.NsHandle(nsFD)); err != nil {
		log.Errorf("setting into container net ns %v failed, %v", os.Args[1], err)
		os.Exit(3)
	}

	// insert outputChain and postroutingchain
	err = iptables.RawCombinedOutputNative("-t", "nat", "-C", "OUTPUT", "-d", resolverIP, "-j", outputChain)
	if err == nil {
		iptables.RawCombinedOutputNative("-t", "nat", "-F", outputChain)
	} else {
		iptables.RawCombinedOutputNative("-t", "nat", "-N", outputChain)
		iptables.RawCombinedOutputNative("-t", "nat", "-I", "OUTPUT", "-d", resolverIP, "-j", outputChain)
	}

	err = iptables.RawCombinedOutputNative("-t", "nat", "-C", "POSTROUTING", "-d", resolverIP, "-j", postroutingchain)
	if err == nil {
		iptables.RawCombinedOutputNative("-t", "nat", "-F", postroutingchain)
	} else {
		iptables.RawCombinedOutputNative("-t", "nat", "-N", postroutingchain)
		iptables.RawCombinedOutputNative("-t", "nat", "-I", "POSTROUTING", "-d", resolverIP, "-j", postroutingchain)
	}

	for _, rule := range rules {
		if iptables.RawCombinedOutputNative(rule...) != nil {
			log.Errorf("setting up rule failed, %v", rule)
		}
	}
}
Ejemplo n.º 26
0
// 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)
}
Ejemplo n.º 27
0
// Redirecter reexec function.
func redirecter() {
	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	if len(os.Args) < 4 {
		logrus.Error("invalid number of arguments..")
		os.Exit(1)
	}

	var ingressPorts []*PortConfig
	if os.Args[3] != "" {
		var err error
		ingressPorts, err = readPortsFromFile(os.Args[3])
		if err != nil {
			logrus.Errorf("Failed reading ingress ports file: %v", err)
			os.Exit(2)
		}
	}

	eIP, _, err := net.ParseCIDR(os.Args[2])
	if err != nil {
		logrus.Errorf("Failed to parse endpoint IP %s: %v", os.Args[2], err)
		os.Exit(3)
	}

	rules := [][]string{}
	for _, iPort := range ingressPorts {
		rule := strings.Fields(fmt.Sprintf("-t nat -A PREROUTING -d %s -p %s --dport %d -j REDIRECT --to-port %d",
			eIP.String(), strings.ToLower(PortConfig_Protocol_name[int32(iPort.Protocol)]), iPort.PublishedPort, iPort.TargetPort))
		rules = append(rules, rule)
	}

	ns, err := netns.GetFromPath(os.Args[1])
	if err != nil {
		logrus.Errorf("failed get network namespace %q: %v", os.Args[1], err)
		os.Exit(4)
	}
	defer ns.Close()

	if err := netns.Set(ns); err != nil {
		logrus.Errorf("setting into container net ns %v failed, %v", os.Args[1], err)
		os.Exit(5)
	}

	for _, rule := range rules {
		if err := iptables.RawCombinedOutputNative(rule...); err != nil {
			logrus.Errorf("setting up rule failed, %v: %v", rule, err)
			os.Exit(5)
		}
	}
}
Ejemplo n.º 28
0
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
}
Ejemplo n.º 29
0
// 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
}
Ejemplo n.º 30
0
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
}