Ejemplo n.º 1
0
    def rule(self, command, *argv, **kwarg):
        '''
        Rule operations

            - command — add, delete
            - table — 0 < table id < 253
            - priority — 0 < rule's priority < 32766
            - action — type of rule, default 'FR_ACT_NOP' (see fibmsg.py)
            - rtscope — routing scope, default RT_SCOPE_UNIVERSE
                `(RT_SCOPE_UNIVERSE|RT_SCOPE_SITE|\
                RT_SCOPE_LINK|RT_SCOPE_HOST|RT_SCOPE_NOWHERE)`
            - family — rule's family (socket.AF_INET (default) or
                socket.AF_INET6)
            - src — IP source for Source Based (Policy Based) routing's rule
            - dst — IP for Destination Based (Policy Based) routing's rule
            - src_len — Mask for Source Based (Policy Based) routing's rule
            - dst_len — Mask for Destination Based (Policy Based) routing's
                rule
            - iifname — Input interface for Interface Based (Policy Based)
                routing's rule
            - oifname — Output interface for Interface Based (Policy Based)
                routing's rule

        Example::
            ip.rule('add', table=10, priority=32000)

        Will create::
            #ip ru sh
            ...
            32000: from all lookup 10
            ....

        Example::
            iproute.rule('add',
                         table=11,
                         priority=32001,
                         action='FR_ACT_UNREACHABLE')

        Will create::
            #ip ru sh
            ...
            32001: from all lookup 11 unreachable
            ....

        Example::
            iproute.rule('add',
                         table=14,
                         priority=32004,
                         src='10.64.75.141')

        Will create::
            #ip ru sh
            ...
            32004: from 10.64.75.141 lookup 14
            ...

        Example::
            iproute.rule('add',
                         table=15,
                         priority=32005,
                         dst='10.64.75.141',
                         dst_len=24)

        Will create::
            #ip ru sh
            ...
            32005: from 10.64.75.141/24 lookup 15
            ...

        Example::
            iproute.rule('add',
                         table=15,
                         priority=32006,
                         dst='10.64.75.141',
                         fwmark=10)

        Will create::
            #ip ru sh
            ...
            32006: from 10.64.75.141 fwmark 0xa lookup 15
            ...
        '''
        flags_base = NLM_F_REQUEST | NLM_F_ACK
        flags_make = flags_base | NLM_F_CREATE | NLM_F_EXCL
        flags_change = flags_base | NLM_F_REPLACE
        flags_replace = flags_change | NLM_F_CREATE

        commands = {'add': (RTM_NEWRULE, flags_make),
                    'del': (RTM_DELRULE, flags_make),
                    'remove': (RTM_DELRULE, flags_make),
                    'delete': (RTM_DELRULE, flags_make),
                    'change': (RTM_NEWRULE, flags_change),
                    'replace': (RTM_NEWRULE, flags_replace)}
        if isinstance(command, int):
            command = (command, flags_make)
        command, flags = commands.get(command, command)

        if argv:
            # this code block will be removed in some release
            logging.warning('rule(): positional parameters are deprecated')
            names = ['table', 'priority', 'action', 'family',
                     'src', 'src_len', 'dst', 'dst_len', 'fwmark',
                     'iifname', 'oifname']
            kwarg.update(dict(zip(names, argv)))
        msg = fibmsg()
        table = kwarg.get('table', 254)
        msg['table'] = table if table <= 255 else 252
        msg['family'] = family = kwarg.get('family', AF_INET)
        msg['action'] = FR_ACT_NAMES[kwarg.get('action', 'FR_ACT_NOP')]
        msg['attrs'] = [['FRA_TABLE', table]]
        msg['attrs'].append(['FRA_PRIORITY', kwarg.get('priority', 32000)])
        if 'fwmark' in kwarg:
            msg['attrs'].append(['FRA_FWMARK', kwarg['fwmark']])
        if 'dst_len' in kwarg:
            msg['dst_len'] = kwarg['dst_len']
        if 'src_len' in kwarg:
            msg['src_len'] = kwarg['src_len']
        addr_len = {AF_INET6: 128, AF_INET:  32}.get(family, 0)
        if 'src' in kwarg:
            msg['attrs'].append(['FRA_SRC', kwarg['src']])
            if kwarg.get('src_len') is None:
                msg['src_len'] = addr_len
        if 'dst' in kwarg:
            msg['attrs'].append(['FRA_DST', kwarg['dst']])
            if kwarg.get('dst_len') is None:
                msg['dst_len'] = addr_len
        if 'iifname' in kwarg:
            msg['attrs'].append(['FRA_IIFNAME', kwarg['iifname']])
        if 'oifname' in kwarg:
            msg['attrs'].append(['FRA_OIFNAME', kwarg['oifname']])

        ret = self.nlm_request(msg, msg_type=command, msg_flags=flags)

        if 'match' in kwarg:
            return self._match(kwarg['match'], ret)
        else:
            return ret
Ejemplo n.º 2
0
    def rule(self, command, *argv, **kwarg):
        '''
        Rule operations

            - command — add, delete
            - table — 0 < table id < 253
            - priority — 0 < rule's priority < 32766
            - action — type of rule, default 'FR_ACT_NOP' (see fibmsg.py)
            - rtscope — routing scope, default RT_SCOPE_UNIVERSE
                `(RT_SCOPE_UNIVERSE|RT_SCOPE_SITE|\
                RT_SCOPE_LINK|RT_SCOPE_HOST|RT_SCOPE_NOWHERE)`
            - family — rule's family (socket.AF_INET (default) or
                socket.AF_INET6)
            - src — IP source for Source Based (Policy Based) routing's rule
            - dst — IP for Destination Based (Policy Based) routing's rule
            - src_len — Mask for Source Based (Policy Based) routing's rule
            - dst_len — Mask for Destination Based (Policy Based) routing's
                rule
            - iifname — Input interface for Interface Based (Policy Based)
                routing's rule
            - oifname — Output interface for Interface Based (Policy Based)
                routing's rule

        All packets route via table 10::

            # 32000: from all lookup 10
            # ...
            ip.rule('add', table=10, priority=32000)

        Default action::

            # 32001: from all lookup 11 unreachable
            # ...
            iproute.rule('add',
                         table=11,
                         priority=32001,
                         action='FR_ACT_UNREACHABLE')

        Use source address to choose a routing table::

            # 32004: from 10.64.75.141 lookup 14
            # ...
            iproute.rule('add',
                         table=14,
                         priority=32004,
                         src='10.64.75.141')

        Use dst address to choose a routing table::

            # 32005: from 10.64.75.141/24 lookup 15
            # ...
            iproute.rule('add',
                         table=15,
                         priority=32005,
                         dst='10.64.75.141',
                         dst_len=24)

        Match fwmark::

            # 32006: from 10.64.75.141 fwmark 0xa lookup 15
            # ...
            iproute.rule('add',
                         table=15,
                         priority=32006,
                         dst='10.64.75.141',
                         fwmark=10)
        '''
        flags_base = NLM_F_REQUEST | NLM_F_ACK
        flags_make = flags_base | NLM_F_CREATE | NLM_F_EXCL
        flags_change = flags_base | NLM_F_REPLACE
        flags_replace = flags_change | NLM_F_CREATE

        commands = {
            'add': (RTM_NEWRULE, flags_make),
            'del': (RTM_DELRULE, flags_make),
            'remove': (RTM_DELRULE, flags_make),
            'delete': (RTM_DELRULE, flags_make),
            'change': (RTM_NEWRULE, flags_change),
            'replace': (RTM_NEWRULE, flags_replace)
        }
        if isinstance(command, int):
            command = (command, flags_make)
        command, flags = commands.get(command, command)

        if argv:
            # this code block will be removed in some release
            logging.warning('rule(): positional parameters are deprecated')
            names = [
                'table', 'priority', 'action', 'family', 'src', 'src_len',
                'dst', 'dst_len', 'fwmark', 'iifname', 'oifname'
            ]
            kwarg.update(dict(zip(names, argv)))
        msg = fibmsg()
        table = kwarg.get('table', 254)
        msg['table'] = table if table <= 255 else 252
        msg['family'] = family = kwarg.pop('family', AF_INET)
        msg['action'] = FR_ACT_NAMES[kwarg.pop('action', 'FR_ACT_NOP')]
        msg['attrs'] = []

        addr_len = {AF_INET6: 128, AF_INET: 32}.get(family, 0)
        if 'priority' not in kwarg:
            kwarg['priority'] = 32000
        if ('src' in kwarg) and (kwarg.get('src_len') is None):
            kwarg['src_len'] = addr_len
        if ('dst' in kwarg) and (kwarg.get('dst_len') is None):
            kwarg['dst_len'] = addr_len

        msg['dst_len'] = kwarg.get('dst_len', 0)
        msg['src_len'] = kwarg.get('src_len', 0)

        for key in kwarg:
            nla = fibmsg.name2nla(key)
            if kwarg[key] is not None:
                msg['attrs'].append([nla, kwarg[key]])

        ret = self.nlm_request(msg, msg_type=command, msg_flags=flags)

        if 'match' in kwarg:
            return self._match(kwarg['match'], ret)
        else:
            return ret