Developer’s guide to Netlink and pyroute2

Protocol sample: RTNL

RTNL is a netlink protocol, used to get and set information about different network objects – addresses, routes, interfaces etc.

RTNL protocol-specific data in messages depends on the object type. E.g., complete packet with the interface address information:

nlmsg header:
    + uint32 length
    + uint16 type
    + uint16 flags
    + uint32 sequence number
    + uint32 pid
ifaddrmsg structure:
    + unsigned char ifa_family
    + unsigned char ifa_prefixlen
    + unsigned char ifa_flags
    + unsigned char ifa_scope
    + uint32 ifa_index
[ optional NLA tree ]

NLA for this kind of packets can be of type IFA_ADDRESS, IFA_LOCAL etc. – please refer to the corresponding source.

Other objects types require different structures, sometimes really complex. All these structures are described in sources.

Create and send a message

Using high-level interfaces like IPRoute or IPDB, you will never need to manually construct and send netlink messages. But in the case you really need it, it is simple as well.

Having a description class, like ifaddrmsg from above, you need to:

  • instantiate it
  • fill the fields
  • encode the packet
  • send the encoded data

The code:

from pyroute2.netlink import NLM_F_REQUEST
from pyroute2.netlink import NLM_F_ACK
from pyroute2.netlink import NLM_F_CREATE
from pyroute2.netlink import NLM_F_EXCL
from pyroute2.netlink.iproute import RTM_NEWADDR
from pyroute2.netlink.rtnl.ifaddrmsg import ifaddrmsg

##
# add an addr to an interface
#

# create the message
msg = ifaddrmsg()

# fill the protocol-specific fields
msg['index'] = index  # index of the interface
msg['family'] = AF_INET  # address family
msg['prefixlen'] = 24  # the address mask
msg['scope'] = scope  # see /etc/iproute2/rt_scopes

# attach NLA -- it MUST be a list / mutable
msg['attrs'] = [['IFA_LOCAL', '192.168.0.1'],
                ['IFA_ADDRESS', '192.162.0.1']]

# fill generic netlink fields
msg['header']['sequence_number'] = nonce  # an unique seq number
msg['header']['pid'] = os.getpid()
msg['header']['type'] = RTM_NEWADDR
msg['header']['flags'] = NLM_F_REQUEST |\
                         NLM_F_ACK |\
                         NLM_F_CREATE |\
                         NLM_F_EXCL

# encode the packet
msg.encode()

# send the buffer
nlsock.send(msg.buf.getvalue())

Please notice, that NLA list MUST be mutable.

Table Of Contents

Previous topic

changelog

Next topic

IPRoute module

This Page