# Module architecture

## Sockets

The idea behind the pyroute2 framework is pretty simple. The library provides socket objects, that have:

- shortcuts to establish netlink connections

- extra methods to run netlink queries

- some magic to handle packet bursts

- another magic to transparently mangle netlink messages

In other sense any netlink socket is just an ordinary socket with fileno(), recv(), sendto() etc. Of course, one can use it in poll().

There is an inheritance diagram of Linux netlink sockets, provided by the library:

digraph inheritancedec35aa693 { bgcolor=transparent; rankdir=LR; ratio=auto; size="8.0, 12.0"; "AcpiEventSocket" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "EventSocket" -> "AcpiEventSocket" [arrowsize=0.5,style="setlinewidth(0.5)"]; "BatchSocket" [URL="nlsocket.html#pyroute2.netlink.nlsocket.BatchSocket",fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",target="_top"]; "NetlinkSocketBase" -> "BatchSocket" [arrowsize=0.5,style="setlinewidth(0.5)"]; "DQuotSocket" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "EventSocket" -> "DQuotSocket" [arrowsize=0.5,style="setlinewidth(0.5)"]; "DevlinkSocket" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "GenericNetlinkSocket" -> "DevlinkSocket" [arrowsize=0.5,style="setlinewidth(0.5)"]; "DiagSocket" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",tooltip="Usage::"]; "NetlinkSocket" -> "DiagSocket" [arrowsize=0.5,style="setlinewidth(0.5)"]; "EventSocket" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "GenericNetlinkSocket" -> "EventSocket" [arrowsize=0.5,style="setlinewidth(0.5)"]; "GenericNetlinkSocket" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",tooltip="Low-level socket interface. Provides all the"]; "NetlinkSocket" -> "GenericNetlinkSocket" [arrowsize=0.5,style="setlinewidth(0.5)"]; "IPBatch" [URL="iproute.html#pyroute2.iproute.linux.IPBatch",fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",target="_top",tooltip="Netlink requests compiler. Does not send any requests, but"]; "RTNL_API" -> "IPBatch" [arrowsize=0.5,style="setlinewidth(0.5)"]; "IPBatchSocket" -> "IPBatch" [arrowsize=0.5,style="setlinewidth(0.5)"]; "IPBatchSocket" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "IPRSocketBase" -> "IPBatchSocket" [arrowsize=0.5,style="setlinewidth(0.5)"]; "BatchSocket" -> "IPBatchSocket" [arrowsize=0.5,style="setlinewidth(0.5)"]; "IPQSocket" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",tooltip="Low-level socket interface. Provides all the"]; "NetlinkSocket" -> "IPQSocket" [arrowsize=0.5,style="setlinewidth(0.5)"]; "IPRSocket" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",tooltip="The simplest class, that connects together the netlink parser and"]; "IPRSocketBase" -> "IPRSocket" [arrowsize=0.5,style="setlinewidth(0.5)"]; "NetlinkSocket" -> "IPRSocket" [arrowsize=0.5,style="setlinewidth(0.5)"]; "IPRSocketBase" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "IPRoute" [URL="iproute.html#pyroute2.iproute.linux.IPRoute",fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",target="_top",tooltip="Regular ordinary utility class, see RTNL API for the list of methods."]; "LAB_API" -> "IPRoute" [arrowsize=0.5,style="setlinewidth(0.5)"]; "RTNL_API" -> "IPRoute" [arrowsize=0.5,style="setlinewidth(0.5)"]; "IPRSocket" -> "IPRoute" [arrowsize=0.5,style="setlinewidth(0.5)"]; "IPSet" [URL="ipset.html#pyroute2.ipset.IPSet",fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",target="_top",tooltip="NFNetlink socket (family=NETLINK_NETFILTER)."]; "NetlinkSocket" -> "IPSet" [arrowsize=0.5,style="setlinewidth(0.5)"]; "IW" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "NL80211" -> "IW" [arrowsize=0.5,style="setlinewidth(0.5)"]; "LAB_API" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "NFCTSocket" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "NetlinkSocket" -> "NFCTSocket" [arrowsize=0.5,style="setlinewidth(0.5)"]; "NFTSocket" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",tooltip="NFNetlink socket (family=NETLINK_NETFILTER)."]; "NetlinkSocket" -> "NFTSocket" [arrowsize=0.5,style="setlinewidth(0.5)"]; "NL80211" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "GenericNetlinkSocket" -> "NL80211" [arrowsize=0.5,style="setlinewidth(0.5)"]; "NetNS" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",tooltip="NetNS is the IPRoute API with network namespace support."]; "RTNL_API" -> "NetNS" [arrowsize=0.5,style="setlinewidth(0.5)"]; "RemoteSocket" -> "NetNS" [arrowsize=0.5,style="setlinewidth(0.5)"]; "NetlinkSocket" [URL="nlsocket.html#pyroute2.netlink.nlsocket.NetlinkSocket",fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",target="_top"]; "NetlinkSocketBase" -> "NetlinkSocket" [arrowsize=0.5,style="setlinewidth(0.5)"]; "NetlinkSocketBase" [URL="nlsocket.html#pyroute2.netlink.nlsocket.NetlinkSocketBase",fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",target="_top",tooltip="Generic netlink socket."]; "NlEthtool" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "GenericNetlinkSocket" -> "NlEthtool" [arrowsize=0.5,style="setlinewidth(0.5)"]; "RTNL_API" [URL="iproute.html#pyroute2.iproute.linux.RTNL_API",fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",target="_top",tooltip="`RTNL_API` should not be instantiated by itself. It is intended"]; "RawIPRSocket" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "RawIPRSocketBase" -> "RawIPRSocket" [arrowsize=0.5,style="setlinewidth(0.5)"]; "NetlinkSocket" -> "RawIPRSocket" [arrowsize=0.5,style="setlinewidth(0.5)"]; "RawIPRSocketBase" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "RawIPRoute" [URL="iproute.html#pyroute2.iproute.linux.RawIPRoute",fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",target="_top",tooltip="The same as `IPRoute`, but does not use the netlink proxy."]; "RTNL_API" -> "RawIPRoute" [arrowsize=0.5,style="setlinewidth(0.5)"]; "RawIPRSocket" -> "RawIPRoute" [arrowsize=0.5,style="setlinewidth(0.5)"]; "RemoteIPRoute" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "RTNL_API" -> "RemoteIPRoute" [arrowsize=0.5,style="setlinewidth(0.5)"]; "RemoteSocket" -> "RemoteIPRoute" [arrowsize=0.5,style="setlinewidth(0.5)"]; "RemoteSocket" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "NetlinkSocketBase" -> "RemoteSocket" [arrowsize=0.5,style="setlinewidth(0.5)"]; "ShellIPR" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "RTNL_API" -> "ShellIPR" [arrowsize=0.5,style="setlinewidth(0.5)"]; "RemoteSocket" -> "ShellIPR" [arrowsize=0.5,style="setlinewidth(0.5)"]; "TaskStats" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "GenericNetlinkSocket" -> "TaskStats" [arrowsize=0.5,style="setlinewidth(0.5)"]; "ThermalEventSocket" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "EventSocket" -> "ThermalEventSocket" [arrowsize=0.5,style="setlinewidth(0.5)"]; "UeventSocket" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "NetlinkSocket" -> "UeventSocket" [arrowsize=0.5,style="setlinewidth(0.5)"]; "WireGuard" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "GenericNetlinkSocket" -> "WireGuard" [arrowsize=0.5,style="setlinewidth(0.5)"]; }

### under the hood

Let’s assume we use an IPRoute object to get the interface list of the system:

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

The get_links() method is provided by the IPRouteMixin class. It chooses the message to send (ifinfmsg), prepares required fields and passes it to the next layer:

    result.extend(self.nlm_request(msg, RTM_GETLINK, msg_flags))

The nlm_request() is a method of the NetlinkSocketBase class. It wraps the pair request/response in one method. The request is done via put(), response comes with get(). These methods hide under the hood the asynchronous nature of the netlink protocol, where the response can come whenever – the time and packet order are not guaranteed. But one can use the sequence_number field of a netlink message to match responses, and the pair put()/get() does it.

### cache thread

Sometimes it is preferable to get incoming messages asap and parse them only when there is time for that. For that case the NetlinkSocketBase provides a possibility to start a dedicated cache thread, that will collect and queue incoming messages as they arrive. The thread doesn’t affect the socket behaviour: it will behave exactly in the same way, the only difference is that recv() will return already cached in the userspace message. To start the thread, one should call bind() with async_cache=True:

    ipr = IPRoute()
    ipr.bind(async_cache=True)
    ...  # do some stuff
    ipr.close()

### message mangling

An interesting feature of the IPRSocketBase is a netlink proxy code, that allows to register callbacks for different message types. The callback API is simple. The callback must accept the message as a binary data, and must return a dictionary with two keys, verdict and data. The verdict can be:

> - for sendto(): forward, return or error

> - for recv(): forward or error

E.g.:

    msg = ifinfmsg(data)
    msg.decode()
    ...  # mangle msg
    msg.reset()
    msg.encode()
    return {'verdict': 'forward',
            'data': msg.buf.getvalue()}

The error verdict raises an exception from data. The forward verdict causes the data to be passed. The return verdict is valid only in sendto() callbacks and means that the data should not be passed to the kernel, but instead it must be returned to the user.

This magic allows the library to transparently support ovs, teamd, tuntap calls via netlink. The corresponding callbacks transparently route the call to an external utility or to ioctl() API.

How to register callbacks, see IPRSocketBase init. The _sproxy serves sendto() mangling, the _rproxy serves the recv() mangling. Later this API can become public.

## Netlink messages

To handle the data going through the sockets, the library uses different message classes. To create a custom message type, one should inherit:

> - nlmsg to create a netlink message class

> - genlmsg to create generic netlink message class

> - nla to create a NLA class

The messages hierarchy:

digraph inheritanceaed10c5c1a { bgcolor=transparent; rankdir=LR; ratio=auto; size="8.0, 12.0"; "acpimsg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "genlmsg" -> "acpimsg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "ctrlmsg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",tooltip="Netlink control message"]; "genlmsg" -> "ctrlmsg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "devlinkcmd" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "genlmsg" -> "devlinkcmd" [arrowsize=0.5,style="setlinewidth(0.5)"]; "dquotmsg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "genlmsg" -> "dquotmsg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "ethtool_linkinfo_msg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "genlmsg" -> "ethtool_linkinfo_msg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "ethtool_linkmode_msg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "genlmsg" -> "ethtool_linkmode_msg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "ethtool_linkstate_msg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "genlmsg" -> "ethtool_linkstate_msg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "ethtool_strset_msg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "genlmsg" -> "ethtool_strset_msg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "ethtool_wol_msg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "genlmsg" -> "ethtool_wol_msg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "fibmsg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",tooltip="IP rule message"]; "nlmsg" -> "fibmsg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "genlmsg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",tooltip="Generic netlink message"]; "nlmsg" -> "genlmsg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "ifaddrmsg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",tooltip="IP address information"]; "nlmsg" -> "ifaddrmsg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "ifinfbase" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",tooltip="Network interface message."]; "ifinfmsg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "ifinfbase" -> "ifinfmsg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "nlmsg" -> "ifinfmsg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "ifinfveth" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "ifinfbase" -> "ifinfveth" [arrowsize=0.5,style="setlinewidth(0.5)"]; "nla" -> "ifinfveth" [arrowsize=0.5,style="setlinewidth(0.5)"]; "ifstatsmsg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "nlmsg" -> "ifstatsmsg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "inet_addr_codec" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "nlmsg" -> "inet_addr_codec" [arrowsize=0.5,style="setlinewidth(0.5)"]; "inet_diag_msg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "inet_addr_codec" -> "inet_diag_msg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "inet_diag_req" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "inet_addr_codec" -> "inet_diag_req" [arrowsize=0.5,style="setlinewidth(0.5)"]; "ipq_base_msg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "nlmsg" -> "ipq_base_msg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "ipq_mode_msg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "nlmsg" -> "ipq_mode_msg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "ipq_packet_msg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "ipq_base_msg" -> "ipq_packet_msg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "ipq_verdict_msg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "ipq_base_msg" -> "ipq_verdict_msg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "ipset_msg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",tooltip="Since the support just begins to be developed,"]; "nfgen_msg" -> "ipset_msg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "iw_event" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "nla" -> "iw_event" [arrowsize=0.5,style="setlinewidth(0.5)"]; "ndmsg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",tooltip="ARP cache update message"]; "nlmsg" -> "ndmsg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "ndtmsg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",tooltip="Neighbour table message"]; "nlmsg" -> "ndtmsg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "nfct_msg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "nfgen_msg" -> "nfct_msg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "nfct_stats" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "nfgen_msg" -> "nfct_stats" [arrowsize=0.5,style="setlinewidth(0.5)"]; "nfct_stats_cpu" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "nfgen_msg" -> "nfct_stats_cpu" [arrowsize=0.5,style="setlinewidth(0.5)"]; "nfgen_msg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "nlmsg" -> "nfgen_msg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "nft_chain_msg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "nfgen_msg" -> "nft_chain_msg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "nft_contains_expr" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "nft_gen_msg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "nfgen_msg" -> "nft_gen_msg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "nft_rule_msg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "nfgen_msg" -> "nft_rule_msg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "nft_contains_expr" -> "nft_rule_msg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "nft_set_msg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "nfgen_msg" -> "nft_set_msg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "nft_contains_expr" -> "nft_set_msg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "nft_table_msg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "nfgen_msg" -> "nft_table_msg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "nft_contains_expr" -> "nft_table_msg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "nh" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "rtmsg_base" -> "nh" [arrowsize=0.5,style="setlinewidth(0.5)"]; "nla" -> "nh" [arrowsize=0.5,style="setlinewidth(0.5)"]; "nl80211cmd" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "genlmsg" -> "nl80211cmd" [arrowsize=0.5,style="setlinewidth(0.5)"]; "nla" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",tooltip="Main NLA class"]; "nla_base" -> "nla" [arrowsize=0.5,style="setlinewidth(0.5)"]; "nlmsg_atoms" -> "nla" [arrowsize=0.5,style="setlinewidth(0.5)"]; "nla_base" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",tooltip="Generic NLA base class."]; "nla_header" -> "nla_base" [arrowsize=0.5,style="setlinewidth(0.5)"]; "nlmsg_base" -> "nla_base" [arrowsize=0.5,style="setlinewidth(0.5)"]; "nlmsg_encoder_generic" -> "nla_base" [arrowsize=0.5,style="setlinewidth(0.5)"]; "nlmsg_decoder_generic" -> "nla_base" [arrowsize=0.5,style="setlinewidth(0.5)"]; "nla_header" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "nlflags" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "nlmsg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",tooltip="Main netlink message class"]; "nlmsg_base" -> "nlmsg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "nlmsg_encoder_generic" -> "nlmsg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "nlmsg_decoder_generic" -> "nlmsg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "nlmsg_atoms" -> "nlmsg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "nlmsg_atoms" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",tooltip="A collection of base NLA types"]; "nlmsg_base" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",tooltip="Netlink base class. You do not need to inherit it directly, unless"]; "nlmsg_decoder_generic" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "nlmsg_encoder_generic" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "nsidmsg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "rtgenmsg" -> "nsidmsg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "nsinfmsg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",tooltip="Fake message type to represent network namespace information."]; "nlmsg" -> "nsinfmsg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "rtgenmsg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "nlmsg" -> "rtgenmsg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "rtmsg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "rtmsg_base" -> "rtmsg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "nlmsg" -> "rtmsg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "rtmsg_base" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",tooltip="Route message"]; "nlflags" -> "rtmsg_base" [arrowsize=0.5,style="setlinewidth(0.5)"]; "taskstatsmsg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "genlmsg" -> "taskstatsmsg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "tcmd" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "genlmsg" -> "tcmd" [arrowsize=0.5,style="setlinewidth(0.5)"]; "tcmsg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "nlmsg" -> "tcmsg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "thermal_msg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "genlmsg" -> "thermal_msg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "ueventmsg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "nlmsg" -> "ueventmsg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "unix_diag_msg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "nlmsg" -> "unix_diag_msg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "unix_diag_req" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "nlmsg" -> "unix_diag_req" [arrowsize=0.5,style="setlinewidth(0.5)"]; "wgmsg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "genlmsg" -> "wgmsg" [arrowsize=0.5,style="setlinewidth(0.5)"]; }

## PF_ROUTE messages

PF_ROUTE socket is used to receive notifications from the BSD kernel. The PF_ROUTE messages:

digraph inheritanced553a8d5f3 { bgcolor=transparent; rankdir=LR; ratio=auto; size="8.0, 12.0"; "bsdmsg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "nlmsg_base" -> "bsdmsg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "if_announcemsg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "bsdmsg" -> "if_announcemsg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "if_msg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "bsdmsg" -> "if_msg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "ifa_msg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "ifa_msg_base" -> "ifa_msg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "rt_msg" -> "ifa_msg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "ifa_msg_base" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "bsdmsg" -> "ifa_msg_base" [arrowsize=0.5,style="setlinewidth(0.5)"]; "ifma_msg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "ifma_msg_base" -> "ifma_msg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "rt_msg" -> "ifma_msg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "ifma_msg_base" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "bsdmsg" -> "ifma_msg_base" [arrowsize=0.5,style="setlinewidth(0.5)"]; "nlmsg_base" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",tooltip="Netlink base class. You do not need to inherit it directly, unless"]; "rt_msg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "rt_msg_base" -> "rt_msg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "rt_msg_base" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "bsdmsg" -> "rt_msg_base" [arrowsize=0.5,style="setlinewidth(0.5)"]; "rt_slot" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "nlmsg_base" -> "rt_slot" [arrowsize=0.5,style="setlinewidth(0.5)"]; }

## IPDB

The IPDB module implements high-level logic to manage some of the system network settings. It is completely agnostic to the netlink object’s nature, the only requirement is that the netlink transport must provide RTNL API.

So, using proper mixin classes one can create a custom RTNL-compatible transport. E.g., this way IPDB can work over NetNS objects, providing the network management within some network namespace — while itself it runs in the main namespace.

The IPDB architecture is not too complicated, but it implements some useful transaction magic, see commit() methods of the Transactional objects.

digraph inheritancebd2219997f { bgcolor=transparent; rankdir=LR; ratio=auto; size="8.0, 12.0"; "BaseRoute" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",tooltip="Persistent transactional route object"]; "Transactional" -> "BaseRoute" [arrowsize=0.5,style="setlinewidth(0.5)"]; "Dotkeys" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",tooltip="This is a sick-minded hack of dict, intended to be an eye-candy."]; "Encap" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "Transactional" -> "Encap" [arrowsize=0.5,style="setlinewidth(0.5)"]; "IPDB" [URL="ipdb.html#pyroute2.ipdb.main.IPDB",fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",target="_top",tooltip="The class that maintains information about network setup"]; "IPaddrSet" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",tooltip="LinkedSet child class with different target filter. The"]; "LinkedSet" -> "IPaddrSet" [arrowsize=0.5,style="setlinewidth(0.5)"]; "Interface" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",tooltip="Objects of this class represent network interface and"]; "Transactional" -> "Interface" [arrowsize=0.5,style="setlinewidth(0.5)"]; "LinkedSet" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",tooltip="Utility class, used by `Interface` to track ip addresses"]; "MPLSRoute" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "BaseRoute" -> "MPLSRoute" [arrowsize=0.5,style="setlinewidth(0.5)"]; "MPLSTable" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "RoutingTable" -> "MPLSTable" [arrowsize=0.5,style="setlinewidth(0.5)"]; "Metrics" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "Transactional" -> "Metrics" [arrowsize=0.5,style="setlinewidth(0.5)"]; "NextHopSet" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "LinkedSet" -> "NextHopSet" [arrowsize=0.5,style="setlinewidth(0.5)"]; "Route" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "BaseRoute" -> "Route" [arrowsize=0.5,style="setlinewidth(0.5)"]; "RoutingTable" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "RoutingTableSet" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "Rule" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",tooltip="Persistent transactional rule object"]; "Transactional" -> "Rule" [arrowsize=0.5,style="setlinewidth(0.5)"]; "RulesDict" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "Transactional" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled",tooltip="Utility class that implements common transactional logic."]; "Dotkeys" -> "Transactional" [arrowsize=0.5,style="setlinewidth(0.5)"]; "Via" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "Transactional" -> "Via" [arrowsize=0.5,style="setlinewidth(0.5)"]; }

## Internet protocols

Beside of the netlink protocols, the library implements a limited set of supplementary internet protocol to play with.

digraph inheritance15756ada77 { bgcolor=transparent; rankdir=LR; ratio=auto; size="8.0, 12.0"; "dhcp4msg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "dhcpmsg" -> "dhcp4msg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "dhcpmsg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "msg" -> "dhcpmsg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "ethmsg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "msg" -> "ethmsg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "ip4msg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "msg" -> "ip4msg" [arrowsize=0.5,style="setlinewidth(0.5)"]; "msg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "udp4_pseudo_header" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "msg" -> "udp4_pseudo_header" [arrowsize=0.5,style="setlinewidth(0.5)"]; "udpmsg" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=10,height=0.25,shape=box,style="setlinewidth(0.5),filled"]; "msg" -> "udpmsg" [arrowsize=0.5,style="setlinewidth(0.5)"]; }