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.
Module contents:
The simplest class, that connects together the netlink parser and a generic Python socket implementation. Provides method get() to receive the next message from netlink socket and parse it. It is just simple socket-like class, it implements no buffering or like that. It spawns no additional threads, leaving this up to developers.
Please note, that netlink is an asynchronous protocol with non-guaranteed delivery. You should be fast enough to get all the messages in time. If the message flow rate is higher than the speed you parse them with, exceeding messages will be dropped.
Usage
Threadless RT netlink monitoring with blocking I/O calls:
>>> from pyroute2 import IPRSocket
>>> from pprint import pprint
>>> s = IPRSocket()
>>> s.bind()
>>> pprint(s.get())
[{'attrs': [('RTA_TABLE', 254),
('RTA_DST', '2a00:1450:4009:808::1002'),
('RTA_GATEWAY', 'fe80:52:0:2282::1fe'),
('RTA_OIF', 2),
('RTA_PRIORITY', 0),
('RTA_CACHEINFO', {'rta_clntref': 0,
'rta_error': 0,
'rta_expires': 0,
'rta_id': 0,
'rta_lastuse': 5926,
'rta_ts': 0,
'rta_tsage': 0,
'rta_used': 1})],
'dst_len': 128,
'event': 'RTM_DELROUTE',
'family': 10,
'flags': 512,
'header': {'error': None,
'flags': 0,
'length': 128,
'pid': 0,
'sequence_number': 0,
'type': 25},
'proto': 9,
'scope': 0,
'src_len': 0,
'table': 254,
'tos': 0,
'type': 1}]
>>>
It is required to call IPRSocket.bind() after creation. The call subscribes the NetlinkSocket to default RTNL groups (RTNL_GROUPS) or to a requested group set.
Proxy get() request
Proxy put() request
Utility function to get interface type.
Unfortunately, we can not rely on RTNL or even ioctl(). RHEL doesn’t support interface type in RTNL and doesn’t provide extended (private) interface flags via ioctl().
False – sysfs info unavailable
None – type not known