pyroute2 Documentation

repository·master·Indexed 22 days ago

https://github.com/svinota/pyroute2

A pure Python networking framework for interacting with Linux networking subsystems such as RTNL and Netfilter, as well as protocols like DHCP and 9p2000. It features an asyncio-based core providing both asynchronous and synchronous APIs, tools for creating custom Netlink messages, and utilities like pyroute2-decoder and dhcp-server-detector.

Tokens
33.3K
Snippets
113
Records
170
Agent score
77%

What's inside pyroute2

  1. Overview of pyroute2 supported protocols

    master
    • rtnl: network settings (addresses, routes, traffic controls)
    • nfnetlink: netfilter API
    • ipq: userspace packet filtering (iptables QUEUE target)
    • devlink: manage and monitor devlink-enabled hardware
    • generic: generic netlink families
    • uevent: uevent messages

    Netfilter API

    • ipset: IP sets
    • nftables: packet filtering
    • nfct: connection tracking
    • ethtool: low-level network interface setup
    • wireguard: VPN setup
    • nl80211: wireless functions API
    • taskstats: extended process statistics
    • acpi_events: ACPI events monitoring
    • thermal_events: thermal events monitoring
    • VFS_DQUOT: disk quota events monitoring

    Other Protocols

    • dhcp: dynamic host configuration protocol for IPv4
    • 9p2000: Plan9 file system protocol
  2. Overview of pyroute2.minimal

    master

    The pyroute2.minimal module is a lightweight, pure Python subset of the full pyroute2 library. It is designed for users who only require a limited set of netlink capabilities without the overhead of the complete library.

    It provides:

    • A netlink parser
    • Basic network namespace (netns) management
    • Implementations for specific netlink protocols
  3. How the asynchronous core works in pyroute2

    master

    Starting from version 0.9.1, pyroute2 is built on an asynchronous core using asyncio. The core manages netlink sockets via asyncio transports and protocols to handle the complexities of the netlink protocol, such as unordered packets and overlapping multi-packet responses.

    Key architectural components of the AsyncCoreSocket include:

    • AsyncCoreSocket.socket: A thread-local socket-like object.
    • AsyncCoreSocket.transport: A thread-local asyncio.Transport.
    • AsyncCoreSocket.protocol: A thread-local asyncio.Protocol.
    • AsyncCoreSocket.msg_queue: A thread-local asyncio queue for received data.
    • AsyncCoreSocket.enqueue(): A synchronous routine used by the transport to put packets into the msg_queue.
    • AsyncCoreSocket.get(): An asynchronous routine that retrieves packets from the queue and reassembles them into complete responses.
    • AsyncCoreSocket.marshal: A protocol-specific parser for converting binary data into netlink messages.
  4. Handling NLMSG_ERROR responses

    master

    Some kernel subsystems return NLMSG_ERROR messages in response to requests.

    • Success: If nlmsg['header']['error'] is None, the request was successful. Receiving an NLMSG_ERROR message where error == 0 is equivalent to a successful command (like $? == 0 in bash).
    • Failure: If nlmsg['header']['error'] is not None, the parser will raise an exception.
  5. Use synchronous APIs with the .asyncore property

    master

    Synchronous API classes (like IPRoute or CoreSocket) are implemented as wrappers around the asynchronous core for backward compatibility. These classes use composition rather than inheritance.

    To access the underlying asynchronous functionality from a synchronous object, use the .asyncore property.

    from pyroute2 import IPRoute
    
    # Using the synchronous API
    with IPRoute() as ipr:
        # Access the underlying asynchronous core
        async_core = ipr.asyncore
        # Now you can access AsyncCoreSocket components
        queue = async_core.msg_queue
  6. Understand the pyroute2 licensing options

    master

    Since version 0.3.6, the pyroute2 package is dual-licensed. When writing derived code or including the library in a distribution, you are free to choose between the following two licenses:

    • GPL-2.0-or-later
    • Apache-2.0

    The Apache v2 license was specifically included to ensure compatibility with the OpenStack project.

  7. Manage network interfaces with pyroute2.ndb

    master
    The pyroute2.ndb.objects.interface module provides high-level object-oriented interfaces for managing network interfaces. This module is part of the NetDevKit (ndb) layer, which offers a more intuitive, object-oriented way to interact with network resources compared to the low-level Netlink API.
  8. How NetlinkRequest manages queries and responses

    master

    The NetlinkRequest class is used by AsyncNetlinkSocket to manage the lifecycle of a Netlink query. It performs the following tasks:

    1. Message Preparation: Calculates required message flags, allocates a sequence number, completes the query message, and encodes it.
    2. Proxy Support: Before sending, it checks if a proxy is registered via NetlinkRequest.proxy(). If the proxy returns True, the request stops processing; otherwise, it proceeds using the underlying socket.
    3. Response Collection: NetlinkRequest.response() collects all response packets matching its specific sequence number. It returns an async iterator over the arrived response messages, allowing you to process the stream of responses.

    Because Netlink is asynchronous and can receive broadcast messages (with sequence_number == 0) or interleaved responses from multiple requests, NetlinkRequest buffers messages to ensure you only receive the relevant responses for your specific query.

    # Example of how response() behaves conceptually
    # It returns an async iterator over messages with the matching sequence number
    async for msg in request.response():
        process(msg)
  9. Use the Plan9 9p2000 protocol implementation

    master

    The pyroute2 library provides a basic asynchronous implementation of the Plan9 9p2000 protocol. You can interact with this protocol using either a server-side socket or a client-side socket.

    To use these components, import them from their respective modules:

    • Plan9ServerSocket for implementing a 9p2000 server.
    • Plan9ClientSocket for implementing a 9p2000 client.
    import asyncio
    from pyroute2.plan9.server import Plan9ServerSocket
    from pyroute2.plan9.client import Plan9ClientSocket
  10. Automatic socket setup for netlink events

    master
    When using pyroute2 event sockets, you do not need to manually call bind() or discovery(). The event socket objects perform these operations automatically upon initialization/usage, simplifying the setup process for listening to broadcasted messages.
  11. How pyroute2 sockets and APIs work

    master

    The pyroute2 framework is built around socket objects that provide shortcuts to establish high-level connections (such as Netlink or 9p) and extra methods to run queries and protocols.

    The library core is based on asyncio. It provides two versions of its API:

    1. Asynchronous API: Native asyncio-based sockets (e.g., AsyncIPRoute, AsyncGenericNetlinkSocket).
    2. Synchronous API: A legacy synchronous API that acts as a wrapper around the asynchronous code. This ensures a single codebase for both styles.

    Note: While most features are available in both, not all synchronous sockets have an asynchronous counterpart yet.

  12. Understand RTNL object states and transitions

    master

    RTNL objects in NDB can exist in several states:

    • invalid: The object does not exist in the system.
    • system: The object exists both in the system and in NDB.
    • setns: The existing object should be moved to another network namespace.
    • remove: The existing object must be deleted from the system.

    State transitions are recorded in the object's state.events list, providing timestamps that can be correlated with NDB logs and RTNL event logs.

    from pyroute2 import NDB
    ndb = NDB()
    # Create an interface and commit the change
    c = ndb.interfaces.create(ifname='t0', kind='dummy').commit()
    
    # Inspect the state transition history
    print(c.state.events)
    # Example output: [(1557752212.6703758, 'invalid'), (1557752212.6821117, 'system')]