Exemplo n.º 1
0
 def __init__(self, ospf_priority=1, id=None, namespaced=True,
              *args, **kwargs):
     """
     :param id: Router id, set automatically if None
     :param namespaced: Run the router in a new network namespace?
     """
     # Create new router id if needed
     if not id:
         Router.ID += 1
         id = 'r%d' % Router.ID
     super(Router, self).__init__(id, *args, **kwargs)
     # Basic routers have lowest priority
     self.ospf_priority = ospf_priority
     self.name = self.id
     self.ns = NetworkNamespace() if namespaced else RootNamespace()
     self.router = FibbingRouter(self)
Exemplo n.º 2
0
 def __init__(self, ospf_priority=1, id=None, namespaced=True,
              *args, **kwargs):
     """
     :param id: Router id, set automatically if None
     :param namespaced: Run the router in a new network namespace?
     """
     # Create new router id if needed
     if not id:
         Router.ID += 1
         id = 'r%d' % Router.ID
     super(Router, self).__init__(id, *args, **kwargs)
     # Basic routers have lowest priority
     self.ospf_priority = ospf_priority
     self.name = self.id
     self.ns = NetworkNamespace() if namespaced else RootNamespace()
     self.router = FibbingRouter(self)
Exemplo n.º 3
0
    def __init__(self, id=None, namespaced=True, *args, **kwargs):
        """
        :param id: Router id, set automatically if None
        :param namespaced: Run the router in a new network namespace?
        """
        # Create new router id if needed
        if not id:
            Router.ID += 1
            id = 'r%d' % Router.ID
        super(Router, self).__init__(id, *args, **kwargs)
        # Basic routers have lowest priority
        self.ospf_priority = 1
        self.ns = NetworkNamespace() if namespaced else RootNamespace()

        # Generate temp filepaths needed by Quagga
        def path(name, ext):
            return '%s/%s_%s.%s' % (RUN, name, self.id, ext)

        self.zebra_pid = path('zebra', 'pid')
        self.zebra_api = path('zserv', 'api')
        self.ospfd_pid = path('ospf', 'pid')
        self.ospf_cfg = path('ospf', 'conf')
        self.zebra_cfg = path('zebra', 'conf')
        self.vtysh = VTYSH('localhost', OSPFD_PORT, node=self)
Exemplo n.º 4
0
class Router(Node):
    """
    A fibbing router
    """
    ID = 0

    def __init__(self, id=None, namespaced=True, *args, **kwargs):
        """
        :param id: Router id, set automatically if None
        :param namespaced: Run the router in a new network namespace?
        """
        # Create new router id if needed
        if not id:
            Router.ID += 1
            id = 'r%d' % Router.ID
        super(Router, self).__init__(id, *args, **kwargs)
        # Basic routers have lowest priority
        self.ospf_priority = 1
        self.ns = NetworkNamespace() if namespaced else RootNamespace()

        # Generate temp filepaths needed by Quagga
        def path(name, ext):
            return '%s/%s_%s.%s' % (RUN, name, self.id, ext)

        self.zebra_pid = path('zebra', 'pid')
        self.zebra_api = path('zserv', 'api')
        self.ospfd_pid = path('ospf', 'pid')
        self.ospf_cfg = path('ospf', 'conf')
        self.zebra_cfg = path('zebra', 'conf')
        self.vtysh = VTYSH('localhost', OSPFD_PORT, node=self)

    def delete(self):
        """
        Delete this node and its associate resources
        """
        self.ns.call('sysctl', '-w', 'net.ipv4.ip_forward=0')
        # Stop ospfd
        pid = read_pid(self.ospfd_pid)
        if pid:
            log.debug('Killing ospfd')
            self.ns.call('kill', '-9', pid)
        del_file(self.ospf_cfg)
        del_file(self.ospfd_pid)
        # Stop zebra
        pid = read_pid(self.zebra_pid)
        if pid:
            log.debug('Killing zebra')
            self.ns.call('kill', '-9', pid)
        del_file(self.zebra_cfg)
        del_file(self.zebra_pid)
        del_file(self.zebra_api)
        # Delete associated namespace
        self.ns.delete()

    def add_port(self, port):
        super(Router, self).add_port(port)
        # Move the port into our network namespace
        return self.ns.capture_port(port)

    def __str__(self):
        """
        :return: nsname: port | port | port
        """
        return '%s: %s' % (self.ns.name,
                           ' | '.join([str(port)
                                      for port in self.interfaces.values()]))

    def start(self, *extra_args):
        """
        Startup this router processes
        """
        super(Router, self).start()
        # Create a configuration node for this router
        cfg_node = _ConfigNode(self)
        # Generate ospf/zebra conf
        self.create_ospf_conf(cfg_node)
        self.create_zebra_conf(cfg_node)
        # Enable ipv4 forwarding
        self.ns.call('sysctl', '-w', 'net.ipv4.ip_forward=1')
        # Start zebra/ospf
        self.ns.call(ZEBRA_EXEC, '-f', self.zebra_cfg, '-i', self.zebra_pid,
                     '-z', self.zebra_api, '-d', '-k')
        self.ns.call(OSPFD_EXEC, '-f', self.ospf_cfg, '-i', self.ospfd_pid,
                     '-z', self.zebra_api, '-d', *extra_args)

    def create_zebra_conf(self, confignode):
        self.render(ZEBRA_CFG_TEMPLATE, self.zebra_cfg, node=confignode)

    def create_ospf_conf(self, confignode):
        self.render(OSPF_CFG_TEMPLATE, self.ospf_cfg, node=confignode)

    def call(self, *args, **kwargs):
        # Redirect the call to happen inside this namespace
        return self.ns.call(*args, **kwargs)

    def pipe(self, *args, **kwargs):
        return self.ns.pipe(*args, **kwargs)

    @staticmethod
    def render(template, dest, **kwargs):
        """
        Render a Mako template passing it optional arguments
        """
        log.debug('Generating %s\n' % dest)
        try:
            text = Template(filename=template).render(**kwargs)
            with closing(open(dest, 'w')) as f:
                f.write(text)
        except:
            # Display template errors in a less cryptic way
            log.error('Couldn''t render a config file (%s)',
                      os.path.basename(template))
            log.error(exceptions.text_error_template().render())

    def _fibbing(self, *args, **kwargs):
        cmd = ['ip', 'ospf', 'fibbing']
        if 'no' in kwargs and kwargs['no']:
            cmd.insert(0, 'no')
        cmd.extend(args)
        self.vtysh(*cmd, configure=True)

    def advertize(self, prefix, via, metric):
        self._fibbing(prefix, 'via', via, 'cost', metric)

    def retract(self, prefix):
        self._fibbing(prefix, no=True)
Exemplo n.º 5
0
class Router(Node):
    """
    A fibbing router
    """
    ID = 0

    def __init__(self, ospf_priority=1, id=None, namespaced=True,
                 *args, **kwargs):
        """
        :param id: Router id, set automatically if None
        :param namespaced: Run the router in a new network namespace?
        """
        # Create new router id if needed
        if not id:
            Router.ID += 1
            id = 'r%d' % Router.ID
        super(Router, self).__init__(id, *args, **kwargs)
        # Basic routers have lowest priority
        self.ospf_priority = ospf_priority
        self.name = self.id
        self.ns = NetworkNamespace() if namespaced else RootNamespace()
        self.router = FibbingRouter(self)

    def delete(self):
        self.router.delete()
        self.ns.delete()

    def add_port(self, port):
        super(Router, self).add_port(port)
        # Move the port into our network namespace
        return self.ns.capture_port(port)

    def __str__(self):
        """
        :return: nsname: port | port | port
        """
        return '%s: %s' % (self.ns.name,
                           ' | '.join([str(port)
                                      for port in self.interfaces.values()]))

    def start(self, *extra_args):
        """
        Startup this router processes
        """
        super(Router, self).start()
        self.router.start(*extra_args)

    def call(self, *args, **kwargs):
        # Redirect the call to happen inside this namespace
        return self.ns.call(*args, **kwargs)

    def pipe(self, *args, **kwargs):
        return self.ns.pipe(*args, **kwargs)

    def _fibbing(self, *args, **kwargs):
        cmd = ['ip', 'ospf', 'fibbing']
        if kwargs.get('no', False):
            cmd.insert(0, 'no')
        cmd.extend(args)
        self.router.vtysh(*cmd, configure=True)

    def advertize(self, prefix, via, metric):
        self._fibbing(prefix, 'via', via, 'cost', metric)

    def retract(self, prefix):
        self._fibbing(prefix, no=True)

    def vtysh(self, *args, **kwargs):
        log.debug('vtysh call: %s', ' '.join(args))
        return self.router.vtysh(*args, **kwargs)
Exemplo n.º 6
0
class Router(Node):
    """
    A fibbing router
    """
    ID = 0

    def __init__(self, ospf_priority=1, id=None, namespaced=True,
                 *args, **kwargs):
        """
        :param id: Router id, set automatically if None
        :param namespaced: Run the router in a new network namespace?
        """
        # Create new router id if needed
        if not id:
            Router.ID += 1
            id = 'r%d' % Router.ID
        super(Router, self).__init__(id, *args, **kwargs)
        # Basic routers have lowest priority
        self.ospf_priority = ospf_priority
        self.name = self.id
        self.ns = NetworkNamespace() if namespaced else RootNamespace()
        self.router = FibbingRouter(self)

    def delete(self):
        self.router.delete()
        self.ns.delete()

    def add_port(self, port):
        super(Router, self).add_port(port)
        # Move the port into our network namespace
        return self.ns.capture_port(port)

    def __str__(self):
        """
        :return: nsname: port | port | port
        """
        return '%s: %s' % (self.ns.name,
                           ' | '.join([str(port)
                                      for port in self.interfaces.values()]))

    def start(self, *extra_args):
        """
        Startup this router processes
        """
        super(Router, self).start()
        self.router.start(*extra_args)

    def call(self, *args, **kwargs):
        # Redirect the call to happen inside this namespace
        return self.ns.call(*args, **kwargs)

    def pipe(self, *args, **kwargs):
        return self.ns.pipe(*args, **kwargs)

    def _fibbing(self, *args, **kwargs):
        cmd = ['ip', 'ospf', 'fibbing']
        if kwargs.get('no', False):
            cmd.insert(0, 'no')
        cmd.extend(args)
        self.router.vtysh(*cmd, configure=True)

    def advertize(self, prefix, via, metric, ttl):
        self._fibbing(str(prefix), 'via', str(via), 'cost', str(metric),
                      'ttl', str(ttl))

    def retract(self, prefix):
        self._fibbing(prefix, no=True)

    def vtysh(self, *args, **kwargs):
        log.debug('vtysh call: %s', ' '.join(args))
        return self.router.vtysh(*args, **kwargs)