Coder Social home page Coder Social logo

svinota / pyroute2 Goto Github PK

View Code? Open in Web Editor NEW
912.0 48.0 244.0 8.39 MB

Python Netlink and PF_ROUTE library — network configuration and monitoring

Home Page: https://pyroute2.org/

License: Other

Python 99.11% Makefile 0.17% Shell 0.09% Awk 0.01% CSS 0.26% JavaScript 0.25% HTML 0.10%
netlink python rtnl namespace nl80211 nfnetlink network linux netns genl generic-netlink network-namespace bsd openbsd freebsd wireguard

pyroute2's Introduction

Pyroute2

Pyroute2 is a pure Python netlink library. The core requires only Python stdlib, no 3rd party libraries. The library was started as an RTNL protocol implementation, so the name is pyroute2, but now it supports many netlink protocols. Some supported netlink families and protocols:

  • rtnl, network settings --- addresses, routes, traffic controls
  • nfnetlink --- netfilter API
  • ipq --- simplest userspace packet filtering, iptables QUEUE target
  • devlink --- manage and monitor devlink-enabled hardware
  • generic --- generic netlink families
  • uevent --- same uevent messages as in udev

Netfilter API:

  • ipset --- IP sets
  • nftables --- packet filtering
  • nfct --- connection tracking

Generic netlink:

  • ethtool --- low-level network interface setup
  • wireguard --- VPN setup
  • nl80211 --- wireless functions API (basic support)
  • taskstats --- extended process statistics
  • acpi_events --- ACPI events monitoring
  • thermal_events --- thermal events monitoring
  • VFS_DQUOT --- disk quota events monitoring

On the low level the library provides socket objects with an extended API. The additional functionality aims to:

  • Help to open/bind netlink sockets
  • Discover generic netlink protocols and multicast groups
  • Construct, encode and decode netlink and PF_ROUTE messages

Supported systems

Pyroute2 runs natively on Linux and emulates some limited subset of RTNL netlink API on BSD systems on top of PF_ROUTE notifications and standard system tools.

Other platforms are not supported.

NDB -- high level RTNL API

Key features:

  • Data integrity
  • Transactions with commit/rollback changes
  • State synchronization
  • Multiple sources, including netns and remote systems

A "Hello world" example:

from pyroute2 import NDB

with NDB() as ndb:
    with ndb.interfaces['eth0'] as eth0:
        # set one parameter
        eth0.set(state='down')
        eth0.commit()  # make sure that the interface is down
        # or multiple parameters at once
        eth0.set(ifname='hello_world!', state='up')
        eth0.commit()  # rename, bring up and wait for success
    # --> <-- here you can be sure that the interface is up & renamed

More examples:

from pyroute2 import NDB

ndb = NDB(log='debug')

for record in ndb.interfaces.summary():
    print(record.ifname, record.address, record.state)

if_dump = ndb.interfaces.dump()
if_dump.select_records(state='up')
if_dump.select_fields('index', 'ifname', 'kind')
for line in if_dump.format('json'):
    print(line)

addr_summary = ndb.addresses.summary()
addr_summary.select_records(ifname='eth0')
for line in addr_summary.format('csv'):
    print(line)

with ndb.interfaces.create(ifname='br0', kind='bridge') as br0:
    br0.add_port('eth0')
    br0.add_port('eth1')
    br0.add_ip('10.0.0.1/24')
    br0.add_ip('192.168.0.1/24')
    br0.set(
        br_stp_state=1,  # set STP on
        br_group_fwd_mask=0x4000,  # set LLDP forwarding
        state='up',  # bring the interface up
    )
# --> <-- commit() will be run by the context manager

# operate on netns:
ndb.sources.add(netns='testns')  # connect to a namespace

with (
    ndb.interfaces.create(
        ifname='veth0',  # create veth
        kind='veth',
        peer={
            'ifname': 'eth0',  # setup peer
            'net_ns_fd': 'testns',  # in a namespace
        },
        state='up',
    )
) as veth0:
    veth0.add_ip(address='172.16.230.1', prefixlen=24)

with ndb.interfaces.wait(
    target='testns', ifname='eth0'
) as peer:  # wait for the peer
    peer.set(state='up')  # bring it up
    peer.add_ip('172.16.230.2/24')  # add address

IPRoute -- Low level RTNL API

Low-level IPRoute utility --- Linux network configuration. The IPRoute class is a 1-to-1 RTNL mapping. There are no implicit interface lookups and so on.

Get notifications about network settings changes with IPRoute:

from pyroute2 import IPRoute
with IPRoute() as ipr:
    # With IPRoute objects you have to call bind() manually
    ipr.bind()
    for message in ipr.get():
        print(message)

More examples:

from socket import AF_INET
from pyroute2 import IPRoute

# get access to the netlink socket
ipr = IPRoute()
# no monitoring here -- thus no bind()

# print interfaces
for link in ipr.get_links():
    print(link)

# create VETH pair and move v0p1 to netns 'test'
ipr.link('add', ifname='v0p0', peer='v0p1', kind='veth')
# wait for the devices:
peer, veth = ipr.poll(
    ipr.link, 'dump', timeout=5, ifname=lambda x: x in ('v0p0', 'v0p1')
)
ipr.link('set', index=peer['index'], net_ns_fd='test')

# bring v0p0 up and add an address
ipr.link('set', index=veth['index'], state='up')
ipr.addr('add', index=veth['index'], address='10.0.0.1', prefixlen=24)

# release Netlink socket
ip.close()

Network namespace examples

Network namespace manipulation:

from pyroute2 import netns
# create netns
netns.create('test')
# list
print(netns.listnetns())
# remove netns
netns.remove('test')

Create veth interfaces pair and move to netns:

from pyroute2 import IPRoute

with IPRoute() as ipr:

    # create interface pair
    ipr.link('add', ifname='v0p0', kind='veth',  peer='v0p1')

    # wait for the peer
    (peer,) = ipr.poll(ipr.link, 'dump', timeout=5, ifname='v0p1')

    # move the peer to the 'test' netns:
    ipr.link('set', index=peer['index'], net_ns_fd='test')

List interfaces in some netns:

from pyroute2 import NetNS
from pprint import pprint

ns = NetNS('test')
pprint(ns.get_links())
ns.close()

More details and samples see in the documentation.

Installation

Using pypi:

pip install pyroute2

Using git:

pip install git+https://github.com/svinota/pyroute2.git

Using source, requires make and nox

git clone https://github.com/svinota/pyroute2.git
cd pyroute2
make install

Requirements

Python >= 3.8

pyroute2's People

Contributors

atzm avatar azaugg avatar blechschmidt avatar brianbaboch avatar cdaymand avatar celebdor avatar centromere avatar chantra avatar cherusk avatar creasyw avatar cscarpitta avatar cunha avatar dependabot[bot] avatar etene avatar ffourcot avatar hegusung avatar inemajo avatar kleinweby avatar liske avatar matshch avatar matthewkazmar avatar paulsd avatar robpol86 avatar roolebo avatar ryan3thompson avatar svenauhagen avatar svinota avatar vic063 avatar xdjackiexd avatar yegorich avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pyroute2's Issues

allow "route" function to accept prefered source ip

Currently it is not possible to insert a route with preferred source IP address. This little patch allows that. Please include it in the official code if possible.

--- iproute.py.original 2013-06-25 12:37:21.000000000 +0200 +++ iproute.py 2013-06-25 12:38:06.000000000 +0200 @@ -467,7 +467,7 @@ def route(self, action, prefix, mask, table=254, rtype='RTN_UNICAST', rtproto='RTPROT_STATIC', rtscope='RT_SCOPE_UNIVERSE', index=None, - gateway=None, family=AF_INET): - gateway=None, family=AF_INET, source=None): ''' Route operations

@@ -481,6 +481,7 @@
* index -- via device index
* gateway -- via address
* family -- socket.AF_INET (default) or socket.AF_INET6

  •             * source -- source IP address
    
     Example:
    

@@ -505,6 +506,8 @@
msg['attrs'].append(['RTA_OIF', index])
if gateway is not None:
msg['attrs'].append(['RTA_GATEWAY', gateway])

  •    if source is not None:
    
  •        msg['attrs'].append(['RTA_PREFSRC', source])
    
     return self.nlm_request(msg, msg_type=action,
                             msg_flags=flags)
    

Thank you,
Ondrej

commit does not wait for devices' creation

when i try to add a device and then add a bridge and set this device as bridge's port, it sometimes fails with:

CommitException: ports target is not set

i think that problem is that commit does not wait for devices' creation and because of it, it is not able to find (not yet created) device in interfaces.

flush table

Is there a way to run a command which looks like :
ip route flush table MyTable
using pyroute2 ?

interface creation on RHEL6 may fail

dummy interface creation on RHEL6 may fail due to incorrect message reassembling. Should be fixed asap, 'cause this issue can be more serious.

TaskStats module

Hi. I was trying to run the example for the TaskStats module and get this error. It's a Ubuntu 12.10 64-bit VM (3.5.0-17-generic).

As a background, I'm looking to build a tool that'll listen on netlink for the taskstats as the process ends (as opposed to the mode where you query each PID).

Thanks!

import os
from pyroute2 import TaskStats
ts = TaskStats()
Traceback (most recent call last):
File "", line 1, in
File "pyroute2/netlink/taskstats.py", line 158, in init
self.io_thread.marshal.msg_map[GENL_ID_CTRL] = ctrlmsg
AttributeError: 'TaskStats' object has no attribute 'io_thread'

ipdb incorrect exception

When running as user:

In [11]: ip.interfaces.virbr0.add_ip('192.168.125.2/24').add_ip('192.168.125.2/24').up().commit()
---------------------------------------------------------------------------
CommitException                           Traceback (most recent call last)
<ipython-input-11-83a0b34d1a5a> in <module>()
----> 1 ip.interfaces.virbr0.add_ip('192.168.125.2/24').add_ip('192.168.125.2/24').up().commit()

/home/peet/Projects/pyroute2/pyroute2/netlink/ipdb/__init__.py in commit(self, tid, transaction, rollback)
   1153             if error is not None:
   1154                 error.transaction = transaction
-> 1155                 raise error
   1156 
   1157             return self

CommitException: ipaddr target is not set

Must be: permission denied

compat mode: check existence of bondings

IPDB in compat mode must test existence of bonding interfaces. Right now it will try to create ones even if required name exists; this will lead to IPDB data inconsistence.

Fedora 20 policy filtering fail

$ uname -r
3.14.2-200.fc20.x86_64

Test debug:

test_tc.TestIngress.test_filter ... > /home/peet/Projects/pyroute2/tests/test_tc.py(80)test_filter()
-> prs = [x for x in fls
(Pdb) l
 75                        keys=['0x0/0x0+12'])
 76             fls = self.ip.get_filters(index=self.interface, parent=0xffff0000)
 77             # assert there are filters
 78             assert fls
 79             # assert there is one police rule:
 80  ->         prs = [x for x in fls
 81                    if x.get_attr('TCA_OPTIONS') is not None and
 82                    x.get_attr('TCA_OPTIONS').get_attr('TCA_U32_POLICE')
 83                    is not None][0]
 84             # assert the police rule has specified parameters
 85             options = prs.get_attr('TCA_OPTIONS')
(Pdb) fls
[{'info': 3277312, 'index': 1104, 'handle': 0, 'family': 0, 'parent': 4294901760, 'pad1': 0, 'pad2': 0, 'attrs': [['TCA_KIND', 'u32']], 'event': 'RTM_NEWTFILTER'},
 {'info': 3277312, 'index': 1104, 'handle': 2147483648, 'family': 0, 'parent': 4294901760, 'pad1': 0, 'pad2': 0, 'attrs': [['TCA_KIND', 'u32'], ['TCA_OPTIONS', {'attrs': [['TCA_U32_DIVISOR', 1]]}]], 'event': 'RTM_NEWTFILTER'},
 {'info': 3277312, 'index': 1104, 'handle': 2147485696, 'family': 0, 'parent': 4294901760, 'pad1': 0, 'pad2': 0, 'attrs': [['TCA_KIND', 'u32'], ['TCA_OPTIONS', {'attrs': [['TCA_U32_SEL', {'off': 0, 'offshift': 0, 'keys': [{'key_mask': 0, 'key_off': 12, 'key_val': 0, 'key_offmask': 0}], '__align': 0, 'hoff': 0, 'offmask': 0, 'hmask': 0, 'nkeys': 1, 'offoff': 0, 'flags': 1}], ['TCA_U32_HASH', 2147483648], ['TCA_U32_CLASSID', 1], ['TCA_U32_ACT', '80:00:00:00:0b:00:01:00:70:6f:6c:69:63:65:00:00:30:00:04:00:14:00:01:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:18:00:03:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:40:00:02:00:3c:00:01:00:04:00:00:00:02:00:00:00:00:00:00:00:00:20:a1:07:f8:07:00:00:00:00:00:00:00:00:00:00:e2:04:00:00:00:00:00:00:00:00:00:00:00:00:00:00:01:00:00:00:01:00:00:00:00:00:00:00'], ['TCA_U32_PCNT', {'rcnt': 0, 'rhit': 0, 'kcnts': 0}]]}], ['TCA_STATS', {'pps': 0, 'qlen': 0, 'bytes': 0, 'drop': 0, 'packets': 0, 'overlimits': 0, 'bps': 0, 'backlog': 0}]], 'event': 'RTM_NEWTFILTER'}]
(Pdb) 

Expected results:

(Pdb) fls
[{'info': 3277312, 'index': 1704, 'handle': 0, 'family': 0, 'parent': 4294901760, 'pad1': 0, 'pad2': 0, 'attrs': [['TCA_KIND', 'u32']], 'event': 'RTM_NEWTFILTER'},
 {'info': 3277312, 'index': 1704, 'handle': 2147483648, 'family': 0, 'parent': 4294901760, 'pad1': 0, 'pad2': 0, 'attrs': [['TCA_KIND', 'u32'], ['TCA_OPTIONS', {'attrs': [['TCA_U32_DIVISOR', 1]]}]], 'event': 'RTM_NEWTFILTER'},
 {'info': 3277312, 'index': 1704, 'handle': 2147485696, 'family': 0, 'parent': 4294901760, 'pad1': 0, 'pad2': 0, 'attrs': [['TCA_KIND', 'u32'], ['TCA_OPTIONS', {'attrs': [['TCA_U32_SEL', {'off': 0, 'offshift': 0, 'keys': [{'key_mask': 0, 'key_off': 12, 'key_val': 0, 'key_offmask': 0}], '__align': 0, 'hoff': 0, 'offmask': 0, 'hmask': 0, 'nkeys': 1, 'offoff': 0, 'flags': 1}], ['TCA_U32_HASH', 2147483648], ['TCA_U32_CLASSID', 1], ['TCA_U32_POLICE', {'attrs': [['TCA_POLICE_TBF', {'burst': 128000000, 'rate': 1250, 'rate_cell_log': 3, 'rate___reserved': 0, 'index': 6, 'rate_mpu': 0, 'capab': 0, 'peak_overhead': 0, 'bindcnt': 1, 'peak_cell_log': 0, 'rate_overhead': 0, 'rate_cell_align': -1, 'peak_cell_align': 0, 'peak_mpu': 0, 'peak___reserved': 0, 'refcnt': 1, 'mtu': 2040, 'limit': 0, 'action': 2, 'peak': 0}]]}], ['TCA_U32_PCNT', {'rcnt': 0, 'rhit': 0, 'kcnts': 0}]]}], ['TCA_STATS', {'pps': 0, 'qlen': 0, 'bytes': 0, 'drop': 0, 'packets': 0, 'overlimits': 0, 'bps': 0, 'backlog': 0}]], 'event': 'RTM_NEWTFILTER'}]

TCA_POLICE_TBF is missing. Instead there is TCA_U32_ACT.

IPv6 addresses on bridges

There is an issue with IPv6 address assignment:

>>> from pyroute2 import IPDB
>>> ip = IPDB()
>>> i = ip.create(kind='bridge', ifname='dala').commit()
>>> i.add_ip('fdb3:84e5:4ff4:55e4::1/64').commit()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "pyroute2/netlink/ipdb/__init__.py", line 1231, in commit
    raise error
pyroute2.netlink.ipdb.CommitException: ipaddr target is not set

Platform: ANY

Issue adding tc policy transfer limits

There appears to be an issue when adding a TC policy using:

tc("add-class", "htb", 2, 0x10010, parent=0x10001, rate=5mbit, ceil=10mbit)

When I filter traffic into this class I can never exceed the "rate". I can replicate every time and using the TC equivalent works perfectly.

«port update» possible race

On bond port removal:

    assert ip.interfaces.bala_port1.if_master is None
AssertionError

Should be fixed by d6678a8 (see also #45), but occasionaly was met in a test-cycle.

kernel-driven races for bridge code on RHEL6.5

Add a hardcoded timeout for RHEL6.5 (at least) to fix that:

    Traceback (most recent call last):
      File "/usr/share/vdsm/supervdsmServer", line 101, in wrapper
        res = func(*args, **kwargs)
      File "/usr/share/vdsm/supervdsmServer", line 201, in addNetwork
        return addNetwork(bridge, **options)
      File "/usr/share/vdsm/network/api.py", line 247, in wrapped
        ret = func(**attrs)
      File "/usr/share/vdsm/network/api.py", line 336, in addNetwork
        netEnt.configure(**options)
      File "/usr/share/vdsm/network/models.py", line 169, in configure
        self.configurator.configureBridge(self, **opts)
      File "/usr/share/vdsm/network/configurators/iproute2.py", line 74, in configureBridge
        self.configApplier.addBridgePort(bridge)
      File "/usr/share/vdsm/network/configurators/pyroute_two.py", line 101, in addBridgePort
        i.add_port(self.ip.interfaces[bridge.port.name])
      File "/usr/lib/python2.6/site-packages/pyroute2/netlink/ipdb/__init__.py", line 625, in __exit__
        self.commit()
      File "/usr/lib/python2.6/site-packages/pyroute2/netlink/ipdb/__init__.py", line 1222, in commit
        raise error
    AssertionError

ptrace plugin does not operate on 32bit arch

Reproducible on RHEL i386:

$ ./examples/trace_ip_link.py 
Traceback (most recent call last):
  File "/home/peet/Project/pyroute2/pyroute2/netlink/plugins/plugin_ptrace.py", line 194, in main
    self.runDebugger()
  File "/home/peet/Project/pyroute2/pyroute2/netlink/plugins/plugin_ptrace.py", line 189, in runDebugger
    self.syscall(process)
  File "/home/peet/Project/pyroute2/pyroute2/netlink/plugins/plugin_ptrace.py", line 50, in syscall
    syscall = state.event(self.syscall_options)
  File "/usr/lib/python2.6/site-packages/python_ptrace-0.6.4-py2.6.egg/ptrace/debugger/syscall_state.py", line 15, in event
    return self.enter(options)
  File "/usr/lib/python2.6/site-packages/python_ptrace-0.6.4-py2.6.egg/ptrace/debugger/syscall_state.py", line 24, in enter
    self.syscall.enter(regs)
  File "/usr/lib/python2.6/site-packages/python_ptrace-0.6.4-py2.6.egg/ptrace/syscall/ptrace_syscall.py", line 37, in enter
    setupSocketCall(self, self.process, self[0], self[1].value)
  File "/usr/lib/python2.6/site-packages/python_ptrace-0.6.4-py2.6.egg/ptrace/syscall/socketcall.py", line 52, in setupSocketCall
    function.restype, formats = SYSCALL_PROTOTYPES[function.name]
KeyError: 's'
WARNING:root:Terminate <PtraceProcess #3026>

broker.py is not waiting for all threads to be finished

I did not dig now very deep into it.

If I run a script which adds and removes some IPs form an interface the scripts ends before all threads are done yet.
Would be nice if loop.py would catch this and block until all threads are finished.

Exception in thread Thread-1 (most likely raised during interpreter shutdown):
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 552, in __bootstrap_inner
File "/usr/local/lib/python2.7/dist-packages/pyroute2/iocore/broker.py", line 152, in run
File "/usr/lib/python2.7/threading.py", line 404, in wait
File "/usr/lib/python2.7/threading.py", line 259, in wait
<type 'exceptions.TypeError'>: 'NoneType' object is not callable

ipdb: iterating mutable sequence

test_ipdb.TestFork.test_routes ... Exception in thread Thread-123:
Traceback (most recent call last):
  File "/usr/lib64/python3.2/threading.py", line 740, in _bootstrap_inner
    self.run()
  File "/usr/lib64/python3.2/threading.py", line 693, in run
    self._target(*self._args, **self._kwargs)
  File "/home/peet/Projects/pyroute2/pyroute2/netlink/ipdb/__init__.py", line 1866, in serve_forever
    self.update_routes([msg])
  File "/home/peet/Projects/pyroute2/pyroute2/netlink/ipdb/__init__.py", line 1768, in update_routes
    self.routes.load(msg)
  File "/home/peet/Projects/pyroute2/pyroute2/netlink/ipdb/__init__.py", line 1425, in load
    ret.load(msg)
  File "/home/peet/Projects/pyroute2/pyroute2/netlink/ipdb/__init__.py", line 1309, in load
    self[norm] = value
  File "/home/peet/Projects/pyroute2/pyroute2/netlink/ipdb/__init__.py", line 487, in decorated
    ret = f(self, direct, *argv, **kwarg)
  File "/home/peet/Projects/pyroute2/pyroute2/netlink/ipdb/__init__.py", line 718, in __setitem__
    for tn in self._transactions.values():
RuntimeError: dictionary changed size during iteration

sometimes following exception is shown, sometimes now

Traceback (most recent call last):
File "/usr/local/lib/python2.6/dist-packages/pyroute2/netlink/init.py", line 441, in _feed_buffers
self.parse(buf.getvalue(), marshal, sock)
File "/usr/local/lib/python2.6/dist-packages/pyroute2/netlink/init.py", line 608, in parse
msg['header']['host'] = _repr_sockets([sock], 'remote')[0]
File "/usr/local/lib/python2.6/dist-packages/pyroute2/netlink/init.py", line 175, in _repr_sockets
ret.append('netlink://%s' % (i.family))
File "/usr/lib/python2.6/socket.py", line 214, in
family = property(lambda self: self._sock.family, doc="the socket family")
File "/usr/lib/python2.6/socket.py", line 167, in _dummy
raise error(EBADF, 'Bad file descriptor')
error: [Errno 9] Bad file descriptor

Linux namespaces support

We have to support configuration of lxc containers in some way. Since pyroute2 has client-server architecture, one can start "servers" in containers and connect to it through any reasonable transport, like tcp/ip, unix sockets or like that.

And -- there should be some out-of-the-box support for starting such servers in namespaces.

Equality goes crazy

Example code:

 from pyroute2 import IPRoute
 IPRoute().get_links() == IPRoute().get_links() 

Output:

 /usr/local/lib/python2.7/dist-packages/pyroute2/netlink/generic.py in __eq__(self, value)
       180                 ...
       181         '''
 --> 182         return self.getvalue() == value
       183 
       184     @classmethod

      RuntimeError: maximum recursion depth exceeded while calling a Python object

taskstats tests

taskstats module should be covered by the regression test cycle

«port add» possible race

On a port addition:

assert ip.interfaces.bala_port1.if_master == \
    ip.interfaces.bala.index
AssertionError

add-filter: wrong protocol

Akilesh K:

I noted that if i give protocol = socket.AF_INET the resulting filter showed up as protocol x25. Right now i just hard coded protocol = 3 which makes the protocol all in backend.

Adding secondary ip address fails if in the same subnet as primary

Given an interface with his config (from ip ad ls):

5: virbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether fe:54:00:64:ee:54 brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0

from pyroute2 import IPRoute
ip = IPRoute()
dev = ip.link_lookup(ifname='virbr0')[0]
ip.addr('add', dev, address='192.168.122.2', mask=24)
Traceback (most recent call last):
File "", line 1, in
File "/usr/local/lib/python2.7/dist-packages/pyroute2/netlink/iproute.py", line 450, in addr
return self.nlm_request(msg, msg_type=command, msg_flags=flags)
File "/usr/local/lib/python2.7/dist-packages/pyroute2/netlink/init.py", line 1135, in nlm_request
result = self.get(nonce)
File "/usr/local/lib/python2.7/dist-packages/pyroute2/netlink/init.py", line 1096, in get
raise msg['header']['error']
pyroute2.netlink.NetlinkError: (22, 'Invalid argument')

For different subnet it works:

ip.addr('add', dev, address='192.168.123.2', mask=24)
[{'index': 5, 'family': 2, 'flags': 128, 'attrs': [('IFA_ADDRESS', '192.168.123.2'), ('IFA_LOCAL', '192.168.123.2'), ('IFA_LABEL', 'virbr0')], 'prefixlen': 24, 'scope': 254, 'event': 'RTM_NEWADDR'}]

I suspect the first case fails because it must be added with the secondary flag. Here's the state after the above is run:

5: virbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether fe:54:00:64:ee:54 brd ff:ff:ff:ff:ff:ff
inet 192.168.123.2/24 scope host virbr0
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0

If I add the address using "ip" command line:

ip add add 192.168.122.2/24 dev virbr0

Then "ip add ls":

5: virbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether fe:54:00:64:ee:54 brd ff:ff:ff:ff:ff:ff
inet 192.168.123.2/24 scope host virbr0
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
inet 192.168.122.2/24 scope global secondary virbr0

Note the "secondary" on the 192.168.122.2/24

Interestingly, if all addresses are added through pyroute2, the problem does not occur:

ip.addr('add', dev, address='192.168.123.3', mask=24)
[{'index': 5, 'family': 2, 'flags': 129, 'attrs': [('IFA_ADDRESS', '192.168.123.3'), ('IFA_LOCAL', '192.168.123.3'), ('IFA_LABEL', 'virbr0')], 'prefixlen': 24, 'scope': 254, 'event': 'RTM_NEWADDR'}]

I think pyroute2 assumes that the first ip.addr call is primary, and subsequent ones are secondary, when this is not the case if you are adding addresses to an interface with existing addresses in the same subnet.

ipdb: targets double-exception

Not critical in IPDB:

test_ipdb.TestMisc.test_context_exception_in_code ... Exception in thread Thread-253:
Traceback (most recent call last):
  File "/usr/lib64/python3.3/threading.py", line 637, in _bootstrap_inner
    self.run()
  File "/usr/lib64/python3.3/threading.py", line 594, in run
    self._target(*self._args, **self._kwargs)
  File "/home/peet/Projects/pyroute2/pyroute2/netlink/ipdb/__init__.py", line 1858, in serve_forever
    self.device_put(msg)
  File "/home/peet/Projects/pyroute2/pyroute2/netlink/ipdb/__init__.py", line 1756, in device_put
    device.load(msg)
  File "/home/peet/Projects/pyroute2/pyroute2/netlink/ipdb/__init__.py", line 865, in load
    self[name] = value
  File "/home/peet/Projects/pyroute2/pyroute2/netlink/ipdb/__init__.py", line 483, in decorated
    ret = f(self, direct, *argv, **kwarg)
  File "/home/peet/Projects/pyroute2/pyroute2/netlink/ipdb/__init__.py", line 717, in __setitem__
    get(key, lambda x, y: x == y)(value, tn[key]):
KeyError: 'flags'

ok

non specified port for IPRSocket results in assertion failure

After update from 0.2.6 to 0.2.9 I got following failure:

[root@intel-sdp-01 lnst]# python
Python 2.7.5 (default, Feb 11 2014, 07:46:25) 
[GCC 4.8.2 20140120 (Red Hat 4.8.2-13)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from pyroute2 import IPRSocket
>>> s = IPRSocket()
>>> s.close()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/site-packages/pyroute2/netlink/__init__.py", line 220, in close
    assert self.port is not None
AssertionError

IPDB.release() is leaking pipes

See the example code below - from my understanding ipdb.release() should've cleaned up everything, but lsof shows that there are FIFO pipes being left behind.

>>> from pyroute2 import IPDB
>>> while 1:
...     ipdb=IPDB()
...     ipdb.release()
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "/usr/local/lib/python2.7/dist-packages/pyroute2/netlink/ipdb/__init__.py", line 1461, in __init__
  File "/usr/local/lib/python2.7/dist-packages/pyroute2/netlink/ipdb/__init__.py", line 1665, in device_put
  File "/usr/local/lib/python2.7/dist-packages/pyroute2/netlink/ipdb/__init__.py", line 844, in load
  File "/usr/local/lib/python2.7/dist-packages/pyroute2/netlink/ipdb/__init__.py", line 263, in get_interface_type
OSError: [Errno 24] Too many open files: '/sys/class/net/lo/'

vlan as bridge's port raises AssertionError

from pyroute2 import IPDB

ip = IPDB()

try:
    master = ip.create(ifname='dummy_12', kind='dummy').commit()

    ip.create(kind='vlan', ifname='vlan_101', link=master, vlan_id=101).commit()

    with ip.create(kind='bridge', ifname='bridge_33') as i:
        i.add_port(ip.interfaces['vlan_101'])
finally:
    for d in ['dummy_12', 'vlan_101', 'bridge_33']:
        try:
            ip.interfaces[d].remove().commit()
        except:
            pass

    ip.release()

raises

Traceback (most recent call last):
  File "pyroute2vlan.py", line 11, in <module>
    i.add_port(ip.interfaces['vlan_101'])
  File "/usr/lib/python2.6/site-packages/pyroute2/netlink/ipdb/__init__.py", line 630, in __exit__
    self.commit()
  File "/usr/lib/python2.6/site-packages/pyroute2/netlink/ipdb/__init__.py", line 1271, in commit
    raise error
AssertionError

get_routes does not return default route

Function "get_routes" from iproute.py does not return default route, which is quote important route and should be returned.

It is caused by condition "... if l[0] == 'RTA_DST'] ..." on line 260. Default route does not have RTA_DST attribute.

Please remove this condition.

Thanks
Ondrej

pyroute2.netlink.ipdb.CommitException: target flags is not set

Hi,

I sometimes get the exception below when configuring an interface:

Traceback (most recent call last):
  File "test.py", line 8, in <module>
    ipif.commit()
  File "/usr/local/lib/python2.7/dist-packages/pyroute2/netlink/ipdb/__init__.py", line 1155, in commit
    raise error
pyroute2.netlink.ipdb.CommitException: target flags is not set

I can reproduce this reliably with this code snippet:

from pyroute2 import IPDB

while True:
        ipdb = IPDB()
        ipif = ipdb.interfaces['eth0']
        ipif.up()
        ipif.add_ip('192.168.100.8', 24)
        ipif.commit()
        ipdb.release()

(I am using pyroute2 0.2.11)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.