def NetNServer(netns, cmdch, brdch, flags=os.O_CREAT): ''' The netns server supposed to be started automatically by NetNS. It has two communication channels: one simplex to forward incoming netlink packets, `rcvch`, and other synchronous duplex to get commands and send back responses, `cmdch`. Channels should support standard socket API, should be compatible with poll/select and should be able to transparently pickle objects. NetNS uses `multiprocessing.Pipe` for this purpose, but it can be any other implementation with compatible API. The first parameter, `netns`, is a netns name. Depending on the `flags`, the netns can be created automatically. The `flags` semantics is exactly the same as for `open(2)` system call. ... The server workflow is simple. The startup sequence:: 1. Create or open a netns. 2. Start `IPRoute` instance. It will be used only on the low level, the `IPRoute` will not parse any packet. 3. Start poll/select loop on `cmdch` and `IPRoute`. On the startup, the server sends via `cmdch` the status packet. It can be `None` if all is OK, or some exception. Further data handling, depending on the channel, server side:: 1. `IPRoute`: read an incoming netlink packet and send it unmodified to the peer via `rcvch`. The peer, polling `rcvch`, can handle the packet on its side. 2. `cmdch`: read tuple (cmd, argv, kwarg). If the `cmd` starts with "send", then take `argv[0]` as a packet buffer, treat it as one netlink packet and substitute PID field (offset 12, uint32) with its own. Strictly speaking, it is not mandatory for modern netlink implementations, but it is required by the protocol standard. ''' signal.signal(signal.SIGINT, signal.SIG_IGN) try: nsfd = setns(netns, flags) except OSError as e: cmdch.send({'stage': 'init', 'error': e}) return e.errno except Exception as e: cmdch.send({ 'stage': 'init', 'error': OSError(errno.ECOMM, str(e), netns) }) return 255 Server(cmdch, brdch) os.close(nsfd)
def MitogenServer(ch_out, netns, router): ch_in = mitogen.core.Receiver(router) ch_out.send(ch_in.to_sender()) trnsp_in = Transport(Channel(ch_in)) trnsp_in.file_obj.start() trnsp_out = Transport(Channel(ch_out)) return Server(trnsp_in, trnsp_out, netns)
def __init__(self, netns, flags=os.O_CREAT, target=None, libc=None): self.netns = netns self.flags = flags target = target or netns trnsp_in, self.remote_trnsp_out = [Transport(FD(x)) for x in os.pipe()] self.remote_trnsp_in, trnsp_out = [Transport(FD(x)) for x in os.pipe()] self.child = os.fork() if self.child == 0: # child process trnsp_in.close() trnsp_out.close() trnsp_in.file_obj.close() trnsp_out.file_obj.close() try: setns(self.netns, self.flags, libc=libc) except OSError as e: (self .remote_trnsp_out .send({'stage': 'init', 'error': e})) os._exit(e.errno) except Exception as e: (self. remote_trnsp_out .send({'stage': 'init', 'error': OSError(errno.ECOMM, str(e), self.netns)})) os._exit(255) try: Server(self.remote_trnsp_in, self.remote_trnsp_out, target=target) finally: os._exit(0) try: self.remote_trnsp_in.close() self.remote_trnsp_out.close() super(NetNS, self).__init__(trnsp_in, trnsp_out) self.target = target except Exception: self.close() raise atexit.register(self.close) self.marshal = MarshalRtnl()
def __init__(self, netns, flags=os.O_CREAT): self.netns = netns self.flags = flags self.trnsp_in, remote_trnsp_out = [Transport(FD(x)) for x in os.pipe()] remote_trnsp_in, self.trnsp_out = [Transport(FD(x)) for x in os.pipe()] self.child = os.fork() if self.child == 0: # child process self.trnsp_in.close() self.trnsp_out.close() try: setns(self.netns, self.flags) except OSError as e: remote_trnsp_out.send({'stage': 'init', 'error': e}) os._exit(e.errno) except Exception as e: remote_trnsp_out.send({ 'stage': 'init', 'error': OSError(errno.ECOMM, str(e), self.netns) }) os._exit(255) try: Server(remote_trnsp_in, remote_trnsp_out) finally: os._exit(0) remote_trnsp_in.close() remote_trnsp_out.close() try: super(NetNS, self).__init__() except Exception: self.close() raise atexit.register(self.close) self.marshal = MarshalRtnl()
import sys from pyroute2.remote import Server from pyroute2.remote import Transport Server(Transport(sys.stdin), Transport(sys.stdout))