Modules in progress

There are several modules in the very initial development state, and the help with them will be particularly valuable. You are more than just welcome to help with:

IPSet module

ipset support.

This module is tested with hash:ip, hash:net, list:set and several other ipset structures (like hash:net,iface). There is no guarantee that this module is working with all available ipset modules.

It supports almost all kernel commands (create, destroy, flush, rename, swap, test...)

class pyroute2.ipset.IPSet(version=6, attr_revision=None, nfgen_family=2)

NFNetlink socket (family=NETLINK_NETFILTER).

Implements API to the ipset functionality.

add(name, entry, family=2, exclusive=True, comment=None, timeout=None, etype='ip', **kwargs)

Add a member to the ipset.

etype is the entry type that you add to the ipset. It’s related to the ipset type. For example, use “ip” for one hash:ip or bitmap:ip ipset.

When your ipset store a tuple, like “hash:net,iface”, you must use a comma a separator (etype=”net,iface”)

create(name, stype='hash:ip', family=2, exclusive=True, counters=False, comment=False, maxelem=65536, forceadd=False, hashsize=None, timeout=None)

Create an ipset name of type stype, by default hash:ip.

Common ipset options are supported:

  • exclusive – if set, raise an error if the ipset exists
  • counters – enable data/packets counters
  • comment – enable comments capability
  • maxelem – max size of the ipset
  • forceadd – you should refer to the ipset manpage
  • hashsize – size of the hashtable (if any)
  • timeout – enable and set a default value for entries (if not None)
delete(name, entry, family=2, exclusive=True, etype='ip')

Delete a member from the ipset.

See add method for more information on etype.

destroy(name=None)

Destroy one or all ipset (when name is None)

flush(name=None)

Flush all ipsets. When name is set, flush only this ipset.

get_supported_revisions(stype, family=2)

Return minimum and maximum of revisions supported by the kernel

headers(name)

Get headers of the named ipset. It can be used to test if one ipset exists, since it returns a no such file or directory.

list(*argv, **kwarg)

List installed ipsets. If name is provided, list the named ipset or return an empty list.

Be warned: netlink does not return an error if given name does not exit, you will receive an empty list.

rename(name_src, name_dst)

Rename the ipset.

swap(set_a, set_b)

Swap two ipsets

test(name, entry, family=2, etype='ip')

Test if a member is part of an ipset

See add method for more information on etype.

IW module

Experimental wireless module — nl80211 support.

Disclaimer

Unlike IPRoute, which is mostly usable, though is far from complete yet, the IW module is in the very initial state. Neither the module itself, nor the message class cover the nl80211 functionality reasonably enough. So if you’re going to use it, brace yourself — debug is coming.

Messages

nl80211 messages are defined here:

pyroute2/netlink/nl80211/__init__.py

Pls notice NLAs of type hex. On the early development stage hex allows to inspect incoming data as a hex dump and, occasionally, even make requests with such NLAs. But it’s not a production way.

The type hex in the NLA definitions means that this particular NLA is not handled yet properly. If you want to use some NLA which is defined as hex yet, pls find out a specific type, patch the message class and submit your pull request on github.

If you’re not familiar with NLA types, take a look at RTNL definitions:

pyroute2/netlink/rtnl/ndmsg.py

and so on.

Communication with the kernel

There are several methods of the communication with the kernel.

  • sendto() — lowest possible, send a raw binary data
  • put() — send a netlink message
  • nlm_request() — send a message, return the response
  • get() — get a netlink message
  • recv() — get a raw binary data from the kernel

There are no errors on put() usually. Any permission denied, any invalid value errors are returned from the kernel with netlink also. So if you do put(), but don’t do get(), be prepared to miss errors.

The preferred method for the communication is nlm_request(). It tracks the message ID, returns the corresponding response. In the case of errors nlm_request() raises an exception. To get the response on any operation with nl80211, use flag NLM_F_ACK.

Reverse it

If you’re too lazy to read the kernel sources, but still need something not implemented here, you can use reverse engineering on a reference implementation. E.g.:

# strace -e trace=network -f -x -s 4096 \
        iw phy phy0 interface add test type monitor

Will dump all the netlink traffic between the program iw and the kernel. Three first packets are the generic netlink protocol discovery, you can ignore them. All that follows, is the nl80211 traffic:

sendmsg(3, {msg_name(12)={sa_family=AF_NETLINK, ... },
    msg_iov(1)=[{"\x30\x00\x00\x00\x1b\x00\x05 ...", 48}],
    msg_controllen=0, msg_flags=0}, 0) = 48
recvmsg(3, {msg_name(12)={sa_family=AF_NETLINK, ... },
    msg_iov(1)=[{"\x58\x00\x00\x00\x1b\x00\x00 ...", 16384}],
    msg_controllen=0, msg_flags=0}, 0) = 88
...

With -s 4096 you will get the full dump. Then copy the strings from msg_iov to a file, let’s say data, and run the decoder:

$ pwd
/home/user/Projects/pyroute2
$ export PYTHONPATH=`pwd`
$ python scripts/decoder.py pyroute2.netlink.nl80211.nl80211cmd data

You will get the session decoded:

{'attrs': [['NL80211_ATTR_WIPHY', 0],
           ['NL80211_ATTR_IFNAME', 'test'],
           ['NL80211_ATTR_IFTYPE', 6]],
 'cmd': 7,
 'header': {'flags': 5,
            'length': 48,
            'pid': 3292542647,
            'sequence_number': 1430426434,
            'type': 27},
 'reserved': 0,
 'version': 0}
{'attrs': [['NL80211_ATTR_IFINDEX', 23811],
           ['NL80211_ATTR_IFNAME', 'test'],
           ['NL80211_ATTR_WIPHY', 0],
           ['NL80211_ATTR_IFTYPE', 6],
           ['NL80211_ATTR_WDEV', 4],
           ['NL80211_ATTR_MAC', 'a4:4e:31:43:1c:7c'],
           ['NL80211_ATTR_GENERATION', '02:00:00:00']],
 'cmd': 7,
 'header': {'flags': 0,
            'length': 88,
            'pid': 3292542647,
            'sequence_number': 1430426434,
            'type': 27},
 'reserved': 0,
 'version': 1}

Now you know, how to do a request and what you will get as a response. Sample collected data is in the scripts directory.

Submit changes

Please do not hesitate to submit the changes on github. Without your patches this module will not evolve.

Network settings daemon – pyrouted

Pyrouted is a standalone project of a system service, that utilizes the pyroute2 library. It consists of a daemon controlled by systemd and a CLI utility that communicates with the daemon via UNIX socket.

It is an extremely simple and basic network interface setup tool.