예제 #1
0
def convert_rt_msg(msg):
    ret = rtmsg()
    ret['header']['type'] = RTNL_NEWROUTE if \
        msg['header']['type'] == RTM_ADD else \
        RTNL_DELROUTE
    ret['family'] = msg['DST']['header']['family']
    ret['attrs'] = []
    if 'address' in msg['DST']:
        ret['attrs'].append(['RTA_DST', msg['DST']['address']])
    if 'NETMASK' in msg and \
            msg['NETMASK']['header']['family'] == ret['family']:
        ret['dst_len'] = dqn2int(msg['NETMASK']['address'], ret['family'])
    if 'GATEWAY' in msg:
        if msg['GATEWAY']['header']['family'] not in (AF_INET, AF_INET6):
            # interface routes, table 255
            # discard for now
            return None
        ret['attrs'].append(['RTA_GATEWAY', msg['GATEWAY']['address']])
    if 'IFA' in msg:
        ret['attrs'].append(['RTA_SRC', msg['IFA']['address']])
    if 'IFP' in msg:
        ret['attrs'].append(['RTA_OIF', msg['IFP']['index']])
    elif msg['rtm_index'] != 0:
        ret['attrs'].append(['RTA_OIF', msg['rtm_index']])
    del ret['value']
    return ret
예제 #2
0
 def match_metrics(msg):
     if msg.get_attr('RTA_GATEWAY') != gateway1:
         return False
     mtu = (msg
            .get_attr('RTA_METRICS', rtmsg())
            .get_attr('RTAX_MTU', 0))
     return mtu == target
예제 #3
0
def convert_rt_msg(msg):
    ret = rtmsg()
    ret['header']['type'] = RTNL_NEWROUTE if \
        msg['header']['type'] == RTM_ADD else \
        RTNL_DELROUTE
    ret['family'] = msg['DST']['header']['family']
    ret['attrs'] = []
    if 'address' in msg['DST']:
        ret['attrs'].append(['RTA_DST', msg['DST']['address']])
    if 'NETMASK' in msg and \
            msg['NETMASK']['header']['family'] == ret['family']:
        ret['dst_len'] = dqn2int(msg['NETMASK']['address'], ret['family'])
    if 'GATEWAY' in msg:
        if msg['GATEWAY']['header']['family'] not in (AF_INET, AF_INET6):
            # interface routes, table 255
            # discard for now
            return None
        ret['attrs'].append(['RTA_GATEWAY', msg['GATEWAY']['address']])
    if 'IFA' in msg:
        ret['attrs'].append(['RTA_SRC', msg['IFA']['address']])
    if 'IFP' in msg:
        ret['attrs'].append(['RTA_OIF', msg['IFP']['index']])
    elif msg['rtm_index'] != 0:
        ret['attrs'].append(['RTA_OIF', msg['rtm_index']])
    del ret['value']
    return ret
예제 #4
0
 def get_routes(self, *argv, **kwarg):
     ifc = self._ifc.parse(self._ifc.run())
     rta = self._route.parse(self._route.run())
     ret = []
     for spec in rta:
         idx = ifc['links'][spec['ifname']]['index']
         spec['attrs'].append(['RTA_OIF', idx])
         msg = rtmsg().load(spec)
         del msg['value']
         ret.append(msg)
     return ret
예제 #5
0
파일: bsd.py 프로젝트: svinota/pyroute2
 def get_routes(self, *argv, **kwarg):
     ifc = self._ifc.parse(self._ifc.run())
     rta = self._route.parse(self._route.run())
     ret = []
     for spec in rta:
         if spec['ifname'] not in ifc['links']:
             continue
         idx = ifc['links'][spec['ifname']]['index']
         spec['attrs'].append(['RTA_OIF', idx])
         msg = rtmsg().load(spec)
         msg['header']['type'] = RTM_NEWROUTE
         del msg['value']
         ret.append(msg)
     return ret
예제 #6
0
파일: iproute.py 프로젝트: vnvo/pyroute2
    def route(
        self,
        action,
        prefix,
        mask,
        table=254,
        rtype="RTN_UNICAST",
        rtproto="RTPROT_STATIC",
        rtscope="RT_SCOPE_UNIVERSE",
        interface=None,
        gateway=None,
        family=AF_INET,
    ):
        """
        Route operations

        * action -- add, delete
        * prefix -- route prefix
        * mask -- route prefix mask
        * table -- routing table to use (default: 254)
        * rtype -- route type (default: "RTN_UNICAST")
        * rtproto -- routing protocol (default: "RTPROT_STATIC")
        * rtscope -- routing scope (default: "RT_SCOPE_UNIVERSE")
        * interface -- via device
        * gateway -- via address
        * family -- socket.AF_INET (default) or socket.AF_INET6

        Example:

        ip.route("add", prefix="10.0.0.0", mask=24, gateway="192.168.0.1")
        """

        actions = {"add": RTM_NEWROUTE, "delete": RTM_DELROUTE}
        action = actions.get(action, action)

        flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_CREATE | NLM_F_EXCL
        msg = rtmsg()
        msg["table"] = table
        msg["family"] = family
        msg["proto"] = rtprotos[rtproto]
        msg["type"] = rtypes[rtype]
        msg["scope"] = rtscopes[rtscope]
        msg["dst_len"] = mask
        msg["attrs"] = [("RTA_DST", prefix), ("RTA_TABLE", table)]
        if interface is not None:
            msg["attrs"].append(("RTA_OIF", interface))
        if gateway is not None:
            msg["attrs"].append(("RTA_GATEWAY", gateway))

        return self.nlm_request(msg, msg_type=action, msg_flags=flags)
예제 #7
0
 def get_routes(self, *argv, **kwarg):
     ifc = self._ifc.parse(self._ifc.run())
     rta = self._route.parse(self._route.run())
     ret = []
     for spec in rta:
         if spec['ifname'] not in ifc['links']:
             continue
         idx = ifc['links'][spec['ifname']]['index']
         spec['attrs'].append(['RTA_OIF', idx])
         msg = rtmsg().load(spec)
         msg['header']['type'] = RTM_NEWROUTE
         del msg['value']
         ret.append(msg)
     return ret
예제 #8
0
    def get_routes(self, family=AF_INET, **kwarg):
        '''
        Get all routes. You can specify the table. There
        are 255 routing classes (tables), and the kernel
        returns all the routes on each request. So the
        routine filters routes from full output.

        Example::

            ip.get_routes()  # get all the routes for all families
            ip.get_routes(family=AF_INET6)  # get only IPv6 routes
            ip.get_routes(table=254)  # get routes from 254 table
        '''

        msg_flags = NLM_F_DUMP | NLM_F_REQUEST
        msg = rtmsg()
        # you can specify the table here, but the kernel
        # will ignore this setting
        table = kwarg.get('table', DEFAULT_TABLE)
        msg['table'] = table if table <= 255 else 252

        # explicitly look for IPv6
        if any([
                kwarg.get(x, '').find(':') >= 0
                for x in ('dst', 'src', 'gateway', 'prefsrc')
        ]):
            family = AF_INET6
        msg['family'] = family

        # get a particular route
        if kwarg.get('dst', None) is not None:
            dlen = 32 if family == AF_INET else \
                128 if family == AF_INET6 else 0
            msg_flags = NLM_F_REQUEST
            msg['dst_len'] = kwarg.get('dst_len', dlen)

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

        routes = self.nlm_request(msg, RTM_GETROUTE, msg_flags)
        return [
            x for x in routes if x.get_attr('RTA_TABLE') == table
            or kwarg.get('table', None) is None
        ]
예제 #9
0
파일: iproute.py 프로젝트: Lh4cKg/pyroute2
    def get_routes(self, family=AF_INET, **kwarg):
        """
        Get all routes. You can specify the table. There
        are 255 routing classes (tables), and the kernel
        returns all the routes on each request. So the
        routine filters routes from full output.

        Example::

            ip.get_routes()  # get all the routes for all families
            ip.get_routes(family=AF_INET6)  # get only IPv6 routes
            ip.get_routes(table=254)  # get routes from 254 table
        """

        msg_flags = NLM_F_DUMP | NLM_F_REQUEST
        msg = rtmsg()
        # you can specify the table here, but the kernel
        # will ignore this setting
        table = kwarg.get("table", DEFAULT_TABLE)
        msg["table"] = table if table <= 255 else 252

        # explicitly look for IPv6
        if any([kwarg.get(x, "").find(":") >= 0 for x in ("dst", "src", "gateway", "prefsrc")]):
            family = AF_INET6
        msg["family"] = family

        # get a particular route
        if kwarg.get("dst", None) is not None:
            dlen = 32 if family == AF_INET else 128 if family == AF_INET6 else 0
            msg_flags = NLM_F_REQUEST
            msg["dst_len"] = kwarg.get("dst_len", dlen)

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

        routes = self.nlm_request(msg, RTM_GETROUTE, msg_flags)
        return [x for x in routes if x.get_attr("RTA_TABLE") == table or kwarg.get("table", None) is None]
예제 #10
0
    def get_routes(self, family=AF_UNSPEC, **kwarg):
        '''
        Get all routes. You can specify the table. There
        are 255 routing classes (tables), and the kernel
        returns all the routes on each request. So the
        routine filters routes from full output.

        Example::

            ip.get_routes()  # get all the routes for all families
            ip.get_routes(family=AF_INET6)  # get only IPv6 routes
            ip.get_routes(table=254)  # get routes from 254 table
        '''

        msg_flags = NLM_F_DUMP | NLM_F_REQUEST
        msg = rtmsg()
        msg['family'] = family
        # you can specify the table here, but the kernel
        # will ignore this setting
        table = kwarg.get('table', 0)
        msg['table'] = table if table <= 255 else 252

        # get a particular route
        if kwarg.get('dst', None) is not None:
            dlen = 32 if family == AF_INET else \
                128 if family == AF_INET6 else 0
            msg_flags = NLM_F_REQUEST
            msg['dst_len'] = kwarg.get('dst_len', dlen)

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

        routes = self.nlm_request(msg, RTM_GETROUTE, msg_flags)
        return [x for x in routes
                if x.get_attr('RTA_TABLE') == table or
                kwarg.get('table', None) is None]
예제 #11
0
파일: iproute.py 프로젝트: vnvo/pyroute2
    def get_routes(self, family=AF_UNSPEC, table=-1):
        """
        Get all routes. You can specify the table. There
        are 255 routing classes (tables), and the kernel
        returns all the routes on each request. So the
        routine filters routes from full output. By default,
        table == -1, which means that one should get all
        tables.
        """
        # moreover, the kernel returns records without
        # RTA_DST, which I don't know how to interpret :)

        msg = rtmsg()
        msg["family"] = family
        # msg['table'] = table  # you can specify the table
        # here, but the kernel will
        # ignore this setting
        routes = self.nlm_request(msg, RTM_GETROUTE)
        return [
            k
            for k in [i for i in routes if "attrs" in i]
            if [l for l in k["attrs"] if l[0] == "RTA_DST"] and (k["table"] == table or table == -1)
        ]
예제 #12
0
    def route(self,
              command,
              rtype='RTN_UNICAST',
              rtproto='RTPROT_STATIC',
              rtscope='RT_SCOPE_UNIVERSE',
              **kwarg):
        '''
        Route operations

        * command -- add, delete, change, replace
        * prefix -- route prefix
        * mask -- route prefix mask
        * rtype -- route type (default: "RTN_UNICAST")
        * rtproto -- routing protocol (default: "RTPROT_STATIC")
        * rtscope -- routing scope (default: "RT_SCOPE_UNIVERSE")
        * family -- socket.AF_INET (default) or socket.AF_INET6

        `pyroute2/netlink/rtnl/rtmsg.py` rtmsg.nla_map:

        * table -- routing table to use (default: 254)
        * gateway -- via address
        * prefsrc -- preferred source IP address
        * dst -- the same as `prefix`
        * src -- source address
        * iif -- incoming traffic interface
        * oif -- outgoing traffic interface

        etc.

        Example::

            ip.route("add", dst="10.0.0.0", mask=24, gateway="192.168.0.1")

        Commands `change` and `replace` have the same meanings, as
        in ip-route(8): `change` modifies only existing route, while
        `replace` creates a new one, if there is no such route yet.
        '''

        # 8<----------------------------------------------------
        # FIXME
        # flags should be moved to some more general place
        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
        # 8<----------------------------------------------------
        commands = {
            'add': (RTM_NEWROUTE, flags_make),
            'set': (RTM_NEWROUTE, flags_replace),
            'replace': (RTM_NEWROUTE, flags_replace),
            'change': (RTM_NEWROUTE, flags_change),
            'del': (RTM_DELROUTE, flags_make),
            'remove': (RTM_DELROUTE, flags_make),
            'delete': (RTM_DELROUTE, flags_make)
        }
        (command, flags) = commands.get(command, command)
        msg = rtmsg()
        # table is mandatory; by default == 254
        # if table is not defined in kwarg, save it there
        # also for nla_attr:
        table = kwarg.get('table', 254)
        msg['table'] = table if table <= 255 else 252
        msg['family'] = kwarg.get('family', AF_INET)
        msg['proto'] = rtprotos[rtproto]
        msg['type'] = rtypes[rtype]
        msg['scope'] = rtscopes[rtscope]
        msg['dst_len'] = kwarg.get('dst_len', None) or \
            kwarg.get('mask', 0)
        msg['attrs'] = []
        # FIXME
        # deprecated "prefix" support:
        if 'prefix' in kwarg:
            kwarg['dst'] = kwarg['prefix']

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

        return self.nlm_request(msg, msg_type=command, msg_flags=flags)
예제 #13
0
    def route(self, command,
              rtype='RTN_UNICAST',
              rtproto='RTPROT_STATIC',
              rtscope='RT_SCOPE_UNIVERSE',
              **kwarg):
        '''
        Route operations

        * command -- add, delete
        * prefix -- route prefix
        * mask -- route prefix mask
        * rtype -- route type (default: "RTN_UNICAST")
        * rtproto -- routing protocol (default: "RTPROT_STATIC")
        * rtscope -- routing scope (default: "RT_SCOPE_UNIVERSE")
        * index -- via device index
        * family -- socket.AF_INET (default) or socket.AF_INET6

        `pyroute2/netlink/rtnl/rtmsg.py` rtmsg.nla_map:

        * table -- routing table to use (default: 254)
        * gateway -- via address
        * prefsrc -- preferred source IP address

        etc.

        Example::

            ip.route("add", dst="10.0.0.0", mask=24, gateway="192.168.0.1")
        '''

        # 8<----------------------------------------------------
        # FIXME
        # flags should be moved to some more general place
        flags_base = NLM_F_REQUEST | NLM_F_ACK
        flags_make = flags_base | NLM_F_CREATE | NLM_F_EXCL
        flags_replace = flags_base | NLM_F_REPLACE
        # 8<----------------------------------------------------
        commands = {'add': (RTM_NEWROUTE, flags_make),
                    'set': (RTM_NEWROUTE, flags_replace),
                    'delete': (RTM_DELROUTE, flags_make)}
        (command, flags) = commands.get(command, command)
        msg = rtmsg()
        # table is mandatory; by default == 254
        # if table is not defined in kwarg, save it there
        # also for nla_attr:
        table = kwarg.get('table', 254)
        msg['table'] = table if table <= 255 else 252
        msg['family'] = kwarg.get('family', AF_INET)
        msg['proto'] = rtprotos[rtproto]
        msg['type'] = rtypes[rtype]
        msg['scope'] = rtscopes[rtscope]
        msg['dst_len'] = kwarg.get('dst_len', None) or \
            kwarg.get('mask', 0)
        msg['attrs'] = []
        # FIXME
        # deprecated "prefix" support:
        if 'prefix' in kwarg:
            kwarg['dst'] = kwarg['prefix']

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

        return self.nlm_request(msg, msg_type=command,
                                msg_flags=flags)
예제 #14
0
    def rule(self, command, table, priority=32000, rtype='RTN_UNICAST',
             rtscope='RT_SCOPE_UNIVERSE', family=AF_INET, src=None):
        '''
        Rule operations

        * command  - add, delete
        * table    - 0 < table id < 253
        * priority - 0 < rule's priority < 32766
        * rtype    - type of rule, default 'RTN_UNICAST'
        * 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

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

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

        Example::
            iproute.rule('add', 11, 32001, 'RTN_UNREACHABLE')

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

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

        Will create::
            #ip ru sh
            ...
            32004: from 10.64.75.141 lookup 14
            ...
        '''
        if table < 0 or table > 254:
            raise 'unsupported table number'

        commands = {'add': RTM_NEWRULE,
                    'delete': RTM_DELRULE}
        command = commands.get(command, command)

        msg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_CREATE | NLM_F_EXCL
        msg = rtmsg()
        msg['table'] = table
        msg['family'] = family
        msg['type'] = rtypes[rtype]
        msg['scope'] = rtscopes[rtscope]
        msg['attrs'] = [['RTA_TABLE', table]]
        msg['attrs'].append(['RTA_PRIORITY', priority])
        msg['dst_len'] = 0
        msg['src_len'] = 0
        if src is not None:
            msg['attrs'].append(['RTA_SRC', src])
            addr_len = {
                AF_INET6: 128,
                AF_INET:  32}[family]
            msg['src_len'] = addr_len
        return self.nlm_request(msg, msg_type=command,
                                msg_flags=msg_flags)
예제 #15
0
    def rule(self,
             command,
             table,
             priority=32000,
             rtype='RTN_UNICAST',
             rtscope='RT_SCOPE_UNIVERSE',
             family=AF_INET,
             src=None):
        '''
        Rule operations

        * command  - add, delete
        * table    - 0 < table id < 253
        * priority - 0 < rule's priority < 32766
        * rtype    - type of rule, default 'RTN_UNICAST'
        * 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

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

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

        Example::
            iproute.rule('add', 11, 32001, 'RTN_UNREACHABLE')

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

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

        Will create::
            #ip ru sh
            ...
            32004: from 10.64.75.141 lookup 14
            ...
        '''
        if table < 0 or table > 254:
            raise 'unsupported table number'

        commands = {'add': RTM_NEWRULE, 'delete': RTM_DELRULE}
        command = commands.get(command, command)

        msg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_CREATE | NLM_F_EXCL
        msg = rtmsg()
        msg['table'] = table
        msg['family'] = family
        msg['type'] = rtypes[rtype]
        msg['scope'] = rtscopes[rtscope]
        msg['attrs'] = [['RTA_TABLE', table]]
        msg['attrs'].append(['RTA_PRIORITY', priority])
        msg['dst_len'] = 0
        msg['src_len'] = 0
        if src is not None:
            msg['attrs'].append(['RTA_SRC', src])
            addr_len = {AF_INET6: 128, AF_INET: 32}[family]
            msg['src_len'] = addr_len
        return self.nlm_request(msg, msg_type=command, msg_flags=msg_flags)
예제 #16
0
    def route(self, command, **kwarg):
        '''
        Route operations.

        * command -- add, delete, change, replace
        * rtype -- route type (default: "RTN_UNICAST")
        * rtproto -- routing protocol (default: "RTPROT_STATIC")
        * rtscope -- routing scope (default: "RT_SCOPE_UNIVERSE")
        * family -- socket.AF_INET (default) or socket.AF_INET6
        * mask -- route prefix mask

        `pyroute2/netlink/rtnl/rtmsg.py` rtmsg.nla_map:

        * table -- routing table to use (default: 254)
        * gateway -- via address
        * prefsrc -- preferred source IP address
        * dst -- the same as `prefix`
        * src -- source address
        * iif -- incoming traffic interface
        * oif -- outgoing traffic interface

        etc.

        Example::

            ip.route("add", dst="10.0.0.0", mask=24, gateway="192.168.0.1")

        Commands `change` and `replace` have the same meanings, as
        in ip-route(8): `change` modifies only existing route, while
        `replace` creates a new one, if there is no such route yet.

        It is possible to set also route metrics. There are two ways
        to do so. The first is to use 'raw' NLA notation::

            ip.route("add",
                     dst="10.0.0.0",
                     mask=24,
                     gateway="192.168.0.1",
                     metrics={"attrs": [["RTAX_MTU", 1400],
                                        ["RTAX_HOPLIMIT", 16]]})

        The second way is to use `IPRouteRequest` helper::

            from pyroute2.netlink.rtnl.req import IPRouteRequest
            ...
            ip.route("add", **IPRouteRequest({"dst": "10.0.0.0/24",
                                              "gateway": "192.168.0.1",
                                              "metrics": {"mtu": 1400,
                                                          "hoplimit": 16}}))

        The `IPRouteRequest` helper is useful also to manage
        mulptipath routes::

            from pyroute2.netlink.rtnl.req import IPRouteRequest
            ...
            request = {"dst": "10.0.0.0/24",
                       "multipath": [{"gateway": "192.168.0.1",
                                      "hops": 2},
                                     {"gateway": "192.168.0.2",
                                      "hops": 1},
                                     {"gateway": "192.168.0.3"}]}
            ip.route("add", **IPRouteRequest(request))
        '''

        # 8<----------------------------------------------------
        # FIXME
        # flags should be moved to some more general place
        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
        # 8<----------------------------------------------------
        commands = {
            'add': (RTM_NEWROUTE, flags_make),
            'set': (RTM_NEWROUTE, flags_replace),
            'replace': (RTM_NEWROUTE, flags_replace),
            'change': (RTM_NEWROUTE, flags_change),
            'del': (RTM_DELROUTE, flags_make),
            'remove': (RTM_DELROUTE, flags_make),
            'delete': (RTM_DELROUTE, flags_make)
        }
        (command, flags) = commands.get(command, command)
        msg = rtmsg()
        # table is mandatory; by default == 254
        # if table is not defined in kwarg, save it there
        # also for nla_attr:
        table = kwarg.get('table', 254)
        msg['table'] = table if table <= 255 else 252
        msg['family'] = kwarg.pop('family', AF_INET)
        msg['proto'] = rtprotos[kwarg.pop('rtproto', 'RTPROT_STATIC')]
        msg['type'] = rtypes[kwarg.pop('rtype', 'RTN_UNICAST')]
        msg['scope'] = rtscopes[kwarg.pop('rtscope', 'RT_SCOPE_UNIVERSE')]
        msg['dst_len'] = kwarg.pop('dst_len', None) or kwarg.pop('mask', 0)
        msg['src_len'] = kwarg.pop('src_len', 0)
        msg['tos'] = kwarg.pop('tos', 0)
        msg['flags'] = kwarg.pop('flags', 0)
        msg['attrs'] = []
        # FIXME
        # deprecated "prefix" support:
        if 'prefix' in kwarg:
            logging.warning('`prefix` argument is deprecated, use `dst`')
            kwarg['dst'] = kwarg['prefix']

        for key in kwarg:
            nla = rtmsg.name2nla(key)
            if kwarg[key] is not None:
                msg['attrs'].append([nla, kwarg[key]])
                # fix IP family, if needed
                if msg['family'] == AF_UNSPEC:
                    if key in ('dst', 'src', 'gateway', 'prefsrc', 'newdst') \
                            and isinstance(kwarg[key], basestring):
                        msg['family'] = AF_INET6 if kwarg[key].find(':') >= 0 \
                            else AF_INET
                    elif key == 'multipath' and len(kwarg[key]) > 0:
                        hop = kwarg[key][0]
                        attrs = hop.get('attrs', [])
                        for attr in attrs:
                            if attr[0] == 'RTA_GATEWAY':
                                msg['family'] = AF_INET6 if \
                                    attr[1].find(':') >= 0 else AF_INET
                                break

        ret = self.nlm_request(msg, msg_type=command, msg_flags=flags)
        if 'match' in kwarg:
            return self._match(kwarg['match'], ret)
        else:
            return ret
예제 #17
0
파일: iproute.py 프로젝트: Lh4cKg/pyroute2
    def rule(
        self,
        command,
        table,
        priority=32000,
        rtype="RTN_UNICAST",
        rtscope="RT_SCOPE_UNIVERSE",
        family=AF_INET,
        src=None,
        src_len=None,
        dst=None,
        dst_len=None,
        fwmark=None,
    ):
        """
        Rule operations

        * command  - add, delete
        * table    - 0 < table id < 253
        * priority - 0 < rule's priority < 32766
        * rtype    - type of rule, default 'RTN_UNICAST'
        * 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

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

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

        Example::
            iproute.rule('add', 11, 32001, 'RTN_UNREACHABLE')

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

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

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

        Example::
            iproute.rule('add', 15, 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', 15, 32006, dst='10.64.75.141', fwmark=10)

        Will create::
            #ip ru sh
            ...
            32006: from 10.64.75.141 fwmark 0xa lookup 15
            ...
        """
        if table < 1:
            raise ValueError("unsupported table number")

        commands = {"add": RTM_NEWRULE, "del": RTM_DELRULE, "remove": RTM_DELRULE, "delete": RTM_DELRULE}
        command = commands.get(command, command)

        msg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_CREATE | NLM_F_EXCL
        msg = rtmsg()
        msg["table"] = table if table <= 255 else 252
        msg["family"] = family
        msg["type"] = rtypes[rtype]
        msg["scope"] = rtscopes[rtscope]
        msg["attrs"] = [["RTA_TABLE", table]]
        msg["attrs"].append(["RTA_PRIORITY", priority])
        if fwmark is not None:
            msg["attrs"].append(["RTA_PROTOINFO", fwmark])
        addr_len = {AF_INET6: 128, AF_INET: 32}[family]
        if dst_len is not None and dst_len >= 0 and dst_len <= addr_len:
            msg["dst_len"] = dst_len
        else:
            msg["dst_len"] = 0
        if src_len is not None and src_len >= 0 and src_len <= addr_len:
            msg["src_len"] = src_len
        else:
            msg["src_len"] = 0
        if src is not None:
            msg["attrs"].append(["RTA_SRC", src])
            if src_len is None:
                msg["src_len"] = addr_len
        if dst is not None:
            msg["attrs"].append(["RTA_DST", dst])
            if dst_len is None:
                msg["dst_len"] = addr_len

        return self.nlm_request(msg, msg_type=command, msg_flags=msg_flags)
예제 #18
0
파일: iproute.py 프로젝트: Lh4cKg/pyroute2
    def route(self, command, rtype="RTN_UNICAST", rtproto="RTPROT_STATIC", rtscope="RT_SCOPE_UNIVERSE", **kwarg):
        """
        Route operations

        * command -- add, delete, change, replace
        * prefix -- route prefix
        * mask -- route prefix mask
        * rtype -- route type (default: "RTN_UNICAST")
        * rtproto -- routing protocol (default: "RTPROT_STATIC")
        * rtscope -- routing scope (default: "RT_SCOPE_UNIVERSE")
        * family -- socket.AF_INET (default) or socket.AF_INET6

        `pyroute2/netlink/rtnl/rtmsg.py` rtmsg.nla_map:

        * table -- routing table to use (default: 254)
        * gateway -- via address
        * prefsrc -- preferred source IP address
        * dst -- the same as `prefix`
        * src -- source address
        * iif -- incoming traffic interface
        * oif -- outgoing traffic interface

        etc.

        Example::

            ip.route("add", dst="10.0.0.0", mask=24, gateway="192.168.0.1")

        Commands `change` and `replace` have the same meanings, as
        in ip-route(8): `change` modifies only existing route, while
        `replace` creates a new one, if there is no such route yet.
        """

        # 8<----------------------------------------------------
        # FIXME
        # flags should be moved to some more general place
        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
        # 8<----------------------------------------------------
        commands = {
            "add": (RTM_NEWROUTE, flags_make),
            "set": (RTM_NEWROUTE, flags_replace),
            "replace": (RTM_NEWROUTE, flags_replace),
            "change": (RTM_NEWROUTE, flags_change),
            "del": (RTM_DELROUTE, flags_make),
            "remove": (RTM_DELROUTE, flags_make),
            "delete": (RTM_DELROUTE, flags_make),
        }
        (command, flags) = commands.get(command, command)
        msg = rtmsg()
        # table is mandatory; by default == 254
        # if table is not defined in kwarg, save it there
        # also for nla_attr:
        table = kwarg.get("table", 254)
        msg["table"] = table if table <= 255 else 252
        msg["family"] = kwarg.get("family", AF_INET)
        msg["proto"] = rtprotos[rtproto]
        msg["type"] = rtypes[rtype]
        msg["scope"] = rtscopes[rtscope]
        msg["dst_len"] = kwarg.get("dst_len", None) or kwarg.get("mask", 0)
        msg["attrs"] = []
        # FIXME
        # deprecated "prefix" support:
        if "prefix" in kwarg:
            kwarg["dst"] = kwarg["prefix"]

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

        return self.nlm_request(msg, msg_type=command, msg_flags=flags)
예제 #19
0
    def route(self, command, **kwarg):
        '''
        Route operations.

        * command -- add, delete, change, replace
        * rtype -- route type (default: "RTN_UNICAST")
        * rtproto -- routing protocol (default: "RTPROT_STATIC")
        * rtscope -- routing scope (default: "RT_SCOPE_UNIVERSE")
        * family -- socket.AF_INET (default) or socket.AF_INET6
        * mask -- route prefix mask

        `pyroute2/netlink/rtnl/rtmsg.py` rtmsg.nla_map:

        * table -- routing table to use (default: 254)
        * gateway -- via address
        * prefsrc -- preferred source IP address
        * dst -- the same as `prefix`
        * src -- source address
        * iif -- incoming traffic interface
        * oif -- outgoing traffic interface

        etc.

        Example::

            ip.route("add", dst="10.0.0.0", mask=24, gateway="192.168.0.1")

        Commands `change` and `replace` have the same meanings, as
        in ip-route(8): `change` modifies only existing route, while
        `replace` creates a new one, if there is no such route yet.

        It is possible to set also route metrics. There are two ways
        to do so. The first is to use 'raw' NLA notation::

            ip.route("add",
                     dst="10.0.0.0",
                     mask=24,
                     gateway="192.168.0.1",
                     metrics={"attrs": [["RTAX_MTU", 1400],
                                        ["RTAX_HOPLIMIT", 16]]})

        The second way is to use `IPRouteRequest` helper::

            from pyroute2.netlink.rtnl.req import IPRouteRequest
            ...
            ip.route("add", **IPRouteRequest({"dst": "10.0.0.0/24",
                                              "gateway": "192.168.0.1",
                                              "metrics": {"mtu": 1400,
                                                          "hoplimit": 16}}))

        The `IPRouteRequest` helper is useful also to manage
        mulptipath routes::

            from pyroute2.netlink.rtnl.req import IPRouteRequest
            ...
            request = {"dst": "10.0.0.0/24",
                       "multipath": [{"gateway": "192.168.0.1",
                                      "hops": 2},
                                     {"gateway": "192.168.0.2",
                                      "hops": 1},
                                     {"gateway": "192.168.0.3"}]}
            ip.route("add", **IPRouteRequest(request))
        '''

        # 8<----------------------------------------------------
        # FIXME
        # flags should be moved to some more general place
        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
        # 8<----------------------------------------------------
        commands = {'add': (RTM_NEWROUTE, flags_make),
                    'set': (RTM_NEWROUTE, flags_replace),
                    'replace': (RTM_NEWROUTE, flags_replace),
                    'change': (RTM_NEWROUTE, flags_change),
                    'del': (RTM_DELROUTE, flags_make),
                    'remove': (RTM_DELROUTE, flags_make),
                    'delete': (RTM_DELROUTE, flags_make)}
        (command, flags) = commands.get(command, command)
        msg = rtmsg()
        # table is mandatory; by default == 254
        # if table is not defined in kwarg, save it there
        # also for nla_attr:
        table = kwarg.get('table', 254)
        msg['table'] = table if table <= 255 else 252
        msg['family'] = kwarg.pop('family', AF_INET)
        msg['proto'] = rtprotos[kwarg.pop('rtproto', 'RTPROT_STATIC')]
        msg['type'] = rtypes[kwarg.pop('rtype', 'RTN_UNICAST')]
        msg['scope'] = rtscopes[kwarg.pop('rtscope', 'RT_SCOPE_UNIVERSE')]
        msg['dst_len'] = kwarg.pop('dst_len', None) or kwarg.pop('mask', 0)
        msg['src_len'] = kwarg.pop('src_len', 0)
        msg['tos'] = kwarg.pop('tos', 0)
        msg['flags'] = kwarg.pop('flags', 0)
        msg['attrs'] = []
        # FIXME
        # deprecated "prefix" support:
        if 'prefix' in kwarg:
            logging.warning('`prefix` argument is deprecated, use `dst`')
            kwarg['dst'] = kwarg['prefix']

        for key in kwarg:
            nla = rtmsg.name2nla(key)
            if kwarg[key] is not None:
                msg['attrs'].append([nla, kwarg[key]])
                # fix IP family, if needed
                if msg['family'] == AF_UNSPEC:
                    if key in ('dst', 'src', 'gateway', 'prefsrc', 'newdst') \
                            and isinstance(kwarg[key], basestring):
                        msg['family'] = AF_INET6 if kwarg[key].find(':') >= 0 \
                            else AF_INET
                    elif key == 'multipath' and len(kwarg[key]) > 0:
                        hop = kwarg[key][0]
                        attrs = hop.get('attrs', [])
                        for attr in attrs:
                            if attr[0] == 'RTA_GATEWAY':
                                msg['family'] = AF_INET6 if \
                                    attr[1].find(':') >= 0 else AF_INET
                                break

        ret = self.nlm_request(msg, msg_type=command, msg_flags=flags)
        if 'match' in kwarg:
            return self._match(kwarg['match'], ret)
        else:
            return ret
예제 #20
0
    def route(self, command, **kwarg):
        '''
        Route operations.

        * command -- add, delete, change, replace
        * rtype -- route type (default: "RTN_UNICAST")
        * rtproto -- routing protocol (default: "RTPROT_STATIC")
        * rtscope -- routing scope (default: "RT_SCOPE_UNIVERSE")
        * family -- socket.AF_INET (default) or socket.AF_INET6
        * mask -- route prefix mask

        `pyroute2/netlink/rtnl/rtmsg.py` rtmsg.nla_map:

        * table -- routing table to use (default: 254)
        * gateway -- via address
        * prefsrc -- preferred source IP address
        * dst -- the same as `prefix`
        * src -- source address
        * iif -- incoming traffic interface
        * oif -- outgoing traffic interface

        etc.

        Example::

            ip.route("add", dst="10.0.0.0", mask=24, gateway="192.168.0.1")

        Commands `change` and `replace` have the same meanings, as
        in ip-route(8): `change` modifies only existing route, while
        `replace` creates a new one, if there is no such route yet.
        '''

        # 8<----------------------------------------------------
        # FIXME
        # flags should be moved to some more general place
        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
        # 8<----------------------------------------------------
        commands = {'add': (RTM_NEWROUTE, flags_make),
                    'set': (RTM_NEWROUTE, flags_replace),
                    'replace': (RTM_NEWROUTE, flags_replace),
                    'change': (RTM_NEWROUTE, flags_change),
                    'del': (RTM_DELROUTE, flags_make),
                    'remove': (RTM_DELROUTE, flags_make),
                    'delete': (RTM_DELROUTE, flags_make)}
        (command, flags) = commands.get(command, command)
        msg = rtmsg()
        # table is mandatory; by default == 254
        # if table is not defined in kwarg, save it there
        # also for nla_attr:
        table = kwarg.get('table', 254)
        msg['table'] = table if table <= 255 else 252
        msg['family'] = kwarg.pop('family', AF_INET)
        msg['proto'] = rtprotos[kwarg.pop('rtproto', 'RTPROT_STATIC')]
        msg['type'] = rtypes[kwarg.pop('rtype', 'RTN_UNICAST')]
        msg['scope'] = rtscopes[kwarg.pop('rtscope', 'RT_SCOPE_UNIVERSE')]
        msg['dst_len'] = kwarg.pop('dst_len', None) or kwarg.pop('mask', 0)
        msg['attrs'] = []
        # FIXME
        # deprecated "prefix" support:
        if 'prefix' in kwarg:
            logging.warning('`prefix` argument is deprecated, use `dst`')
            kwarg['dst'] = kwarg['prefix']

        for key in kwarg:
            nla = rtmsg.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
예제 #21
0
    def rule(self,
             command,
             table,
             priority=32000,
             rtype='RTN_UNICAST',
             rtscope='RT_SCOPE_UNIVERSE',
             family=AF_INET,
             src=None,
             src_len=None,
             dst=None,
             dst_len=None,
             fwmark=None):
        '''
        Rule operations

        * command  - add, delete
        * table    - 0 < table id < 253
        * priority - 0 < rule's priority < 32766
        * rtype    - type of rule, default 'RTN_UNICAST'
        * 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

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

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

        Example::
            iproute.rule('add', 11, 32001, 'RTN_UNREACHABLE')

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

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

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

        Example::
            iproute.rule('add', 15, 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', 15, 32006, dst='10.64.75.141', fwmark=10)

        Will create::
            #ip ru sh
            ...
            32006: from 10.64.75.141 fwmark 0xa lookup 15
            ...
        '''
        if table < 1:
            raise ValueError('unsupported table number')

        commands = {
            'add': RTM_NEWRULE,
            'del': RTM_DELRULE,
            'remove': RTM_DELRULE,
            'delete': RTM_DELRULE
        }
        command = commands.get(command, command)

        msg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_CREATE | NLM_F_EXCL
        msg = rtmsg()
        msg['table'] = table if table <= 255 else 252
        msg['family'] = family
        msg['type'] = rtypes[rtype]
        msg['scope'] = rtscopes[rtscope]
        msg['attrs'] = [['RTA_TABLE', table]]
        msg['attrs'].append(['RTA_PRIORITY', priority])
        if fwmark is not None:
            msg['attrs'].append(['RTA_PROTOINFO', fwmark])
        addr_len = {AF_INET6: 128, AF_INET: 32}[family]
        if (dst_len is not None and dst_len >= 0 and dst_len <= addr_len):
            msg['dst_len'] = dst_len
        else:
            msg['dst_len'] = 0
        if (src_len is not None and src_len >= 0 and src_len <= addr_len):
            msg['src_len'] = src_len
        else:
            msg['src_len'] = 0
        if src is not None:
            msg['attrs'].append(['RTA_SRC', src])
            if src_len is None:
                msg['src_len'] = addr_len
        if dst is not None:
            msg['attrs'].append(['RTA_DST', dst])
            if dst_len is None:
                msg['dst_len'] = addr_len

        return self.nlm_request(msg, msg_type=command, msg_flags=msg_flags)