├── .flake8
├── .github
├── FUNDING.yml
├── dependabot.yml
└── workflows
│ ├── codeql.yaml
│ ├── depsreview.yaml
│ ├── full.yml
│ ├── pull_request.yml
│ └── push.yml
├── .gitignore
├── .mypy-check-paths
├── .pre-commit-config.yaml
├── CHANGELOG.rst
├── LICENSE
├── LICENSE.Apache-2.0
├── LICENSE.GPL-2.0-or-later
├── MANIFEST.in
├── Makefile
├── README.contribute.rst
├── README.license.rst
├── README.minimal.rst
├── README.report.rst
├── README.rst
├── VERSION
├── docs
├── Makefile
├── README.md
├── _static
│ ├── .empty
│ ├── classic.css
│ ├── custom.css
│ └── fixup.js
├── _templates
│ ├── .empty
│ └── layout.html
├── aafigure.map
├── arch.rst
├── asyncio.rst
├── conf.py
├── debug.rst
├── deprecated.rst
├── dhcp-server-detector.rst
├── event.rst
├── fixtures.rst
├── index.rst
├── iproute.rst
├── iproute_intro.rst
├── iproute_linux.rst
├── iproute_netns.rst
├── iproute_platforms.rst.disabled
├── iproute_responses.rst
├── iproute_tc.rst.disabled
├── ipset.rst
├── mpls.rst
├── ndb.rst
├── ndb_addresses.rst
├── ndb_auth.rst
├── ndb_debug.rst
├── ndb_init.rst
├── ndb_interfaces.rst
├── ndb_objects.rst
├── ndb_probes.rst
├── ndb_reports.rst
├── ndb_routes.rst
├── ndb_schema.rst
├── ndb_sources.rst
├── ndb_toc.rst
├── ndb_transactions.rst
├── ndb_views.rst
├── netlink.rst
├── netns.rst
├── nlsocket.rst.disabled
├── parser.rst
├── plan9.rst
├── pyroute2-cli.rst
├── pyroute2-dhcp-client.rst
├── remote.rst.disabled
├── threading.rst
├── usage.rst
├── wireguard.rst
└── wiset.rst
├── examples
├── README.md
├── devlink
│ ├── devlink_list.py
│ ├── devlink_monitor.py
│ └── devlink_port_list.py
├── ethtool
│ ├── ethtool-ioctl_get_infos.py
│ ├── ethtool-netlink_get_infos.py
│ └── ethtool_get_infos.py
├── generic
│ ├── Makefile
│ ├── netl.c
│ └── netl.py
├── ipq.py
├── iproute
│ ├── ip_monitor.py
│ └── socketcan.py
├── ipset.py
├── kobject_uevent.py
├── ndb
│ ├── create_bond.py
│ ├── create_interface.py
│ ├── create_vlan.py
│ ├── keystone_auth.py
│ └── radius_auth.py
├── nftables.py
├── nftables_sets.py
├── policy
│ └── policy.py
├── processes
│ ├── pmonitor.py
│ └── taskstats.py
├── pyroute2-cli
│ ├── comments
│ ├── create_bridge
│ ├── create_dummy
│ └── dump_lo
└── wifi
│ ├── nl80211_interface_type.py
│ ├── nl80211_interfaces.py
│ ├── nl80211_monitor.py
│ ├── nl80211_scan_dump.py
│ └── nl80211_set_type.py
├── noxfile.py
├── pyproject.toml
├── pyroute2
├── __init__.py
├── arp.py
├── bsd
│ ├── README
│ ├── __init__.py
│ ├── pf_route
│ │ ├── __init__.py
│ │ ├── freebsd.py
│ │ └── openbsd.py
│ ├── rtmsocket
│ │ ├── __init__.py
│ │ ├── freebsd.py
│ │ └── openbsd.py
│ └── util.py
├── cli
│ ├── __init__.py
│ ├── auth
│ │ ├── __init__.py
│ │ ├── auth_keystone.py
│ │ └── auth_radius.py
│ ├── console.py
│ ├── parser.py
│ ├── server.py
│ └── session.py
├── common.py
├── compat.py
├── config
│ ├── __init__.py
│ ├── asyncio.py
│ ├── eventlet.py
│ ├── log.py
│ └── test_platform.py
├── conntrack.py
├── decoder
│ ├── __init__.py
│ ├── args.py
│ ├── loader.py
│ └── main.py
├── devlink.py
├── dhcp
│ ├── __init__.py
│ ├── cli.py
│ ├── client.py
│ ├── dhcp4msg.py
│ ├── dhcp4socket.py
│ ├── enums
│ │ ├── __init__.py
│ │ ├── bootp.py
│ │ └── dhcp.py
│ ├── fsm.py
│ ├── hooks.py
│ ├── iface_status.py
│ ├── leases.py
│ ├── messages.py
│ ├── server_detector.py
│ ├── timers.py
│ └── xids.py
├── ethtool
│ ├── __init__.py
│ ├── common.py
│ ├── ethtool.py
│ └── ioctl.py
├── ext
│ ├── __init__.py
│ ├── bpf.py
│ ├── icmp.py
│ └── rawsocket.py
├── fixtures
│ ├── __init__.py
│ ├── doctest.py
│ ├── iproute.py
│ └── plan9.py
├── inotify
│ ├── __init__.py
│ ├── inotify_fd.py
│ └── inotify_msg.py
├── ipdb
│ └── __init__.py
├── iproute
│ ├── __init__.py
│ ├── bsd.py
│ ├── darwin.py
│ ├── ipmock.py
│ ├── linux.py
│ ├── parsers.py
│ └── windows.py
├── ipset.py
├── ipvs.py
├── iwutil.py
├── minimal.py
├── ndb
│ ├── __init__.py
│ ├── auth_manager.py
│ ├── cli.py
│ ├── cluster.py
│ ├── compat.py
│ ├── events.py
│ ├── main.py
│ ├── messages.py
│ ├── objects
│ │ ├── __init__.py
│ │ ├── address.py
│ │ ├── interface.py
│ │ ├── neighbour.py
│ │ ├── netns.py
│ │ ├── probe.py
│ │ ├── route.py
│ │ └── rule.py
│ ├── query.py
│ ├── report.py
│ ├── schema.py
│ ├── source.py
│ ├── task_manager.py
│ ├── transaction.py
│ ├── transport.py
│ └── view.py
├── netlink
│ ├── __init__.py
│ ├── buffer.py
│ ├── connector
│ │ ├── __init__.py
│ │ └── cn_proc.py
│ ├── core.py
│ ├── coredata.py
│ ├── devlink
│ │ └── __init__.py
│ ├── diag
│ │ ├── __init__.py
│ │ └── ss2.py
│ ├── event
│ │ ├── __init__.py
│ │ ├── acpi_event.py
│ │ ├── dquot.py
│ │ └── thermal.py
│ ├── exceptions.py
│ ├── generic
│ │ ├── __init__.py
│ │ ├── ethtool.py
│ │ ├── ipvs.py
│ │ ├── l2tp.py
│ │ ├── mptcp.py
│ │ └── wireguard.py
│ ├── ipq
│ │ └── __init__.py
│ ├── marshal.py
│ ├── nfnetlink
│ │ ├── __init__.py
│ │ ├── ipset.py
│ │ ├── nfctsocket.py
│ │ └── nftsocket.py
│ ├── nl80211
│ │ └── __init__.py
│ ├── nlsocket.py
│ ├── rtnl
│ │ ├── __init__.py
│ │ ├── errmsg.py
│ │ ├── fibmsg.py
│ │ ├── ifaddrmsg.py
│ │ ├── ifinfmsg
│ │ │ ├── __init__.py
│ │ │ ├── plugins
│ │ │ │ ├── __init__.py
│ │ │ │ ├── bond.py
│ │ │ │ ├── can.py
│ │ │ │ ├── geneve.py
│ │ │ │ ├── gtp.py
│ │ │ │ ├── ipoib.py
│ │ │ │ ├── ipvlan.py
│ │ │ │ ├── team.py
│ │ │ │ ├── tun.py
│ │ │ │ ├── tuntap.py
│ │ │ │ ├── vlan.py
│ │ │ │ ├── vrf.py
│ │ │ │ ├── vti.py
│ │ │ │ ├── vti6.py
│ │ │ │ ├── vxlan.py
│ │ │ │ └── xfrm.py
│ │ │ └── tuntap.py
│ │ ├── ifstatsmsg.py
│ │ ├── iprsocket.py
│ │ ├── iw_event.py
│ │ ├── marshal.py
│ │ ├── ndmsg.py
│ │ ├── ndtmsg.py
│ │ ├── nsidmsg.py
│ │ ├── nsinfmsg.py
│ │ ├── p2pmsg.py
│ │ ├── probe_msg.py
│ │ ├── rtgenmsg.py
│ │ ├── rtmsg.py
│ │ └── tcmsg
│ │ │ ├── README.md
│ │ │ ├── __init__.py
│ │ │ ├── act_bpf.py
│ │ │ ├── act_connmark.py
│ │ │ ├── act_gact.py
│ │ │ ├── act_mirred.py
│ │ │ ├── act_police.py
│ │ │ ├── act_skbedit.py
│ │ │ ├── act_vlan.py
│ │ │ ├── cls_basic.py
│ │ │ ├── cls_flow.py
│ │ │ ├── cls_fw.py
│ │ │ ├── cls_matchall.py
│ │ │ ├── cls_u32.py
│ │ │ ├── common.py
│ │ │ ├── common_act.py
│ │ │ ├── common_ematch.py
│ │ │ ├── em_cmp.py
│ │ │ ├── em_ipset.py
│ │ │ ├── em_meta.py
│ │ │ ├── sched_bpf.py
│ │ │ ├── sched_cake.py
│ │ │ ├── sched_choke.py
│ │ │ ├── sched_clsact.py
│ │ │ ├── sched_codel.py
│ │ │ ├── sched_drr.py
│ │ │ ├── sched_fq_codel.py
│ │ │ ├── sched_hfsc.py
│ │ │ ├── sched_htb.py
│ │ │ ├── sched_ingress.py
│ │ │ ├── sched_netem.py
│ │ │ ├── sched_pfifo.py
│ │ │ ├── sched_pfifo_fast.py
│ │ │ ├── sched_plug.py
│ │ │ ├── sched_sfq.py
│ │ │ ├── sched_tbf.py
│ │ │ └── sched_template.py
│ ├── taskstats
│ │ └── __init__.py
│ └── uevent
│ │ └── __init__.py
├── netns
│ ├── __init__.py
│ └── manager.py
├── nftables
│ ├── __init__.py
│ ├── expressions.py
│ ├── main.py
│ ├── parser
│ │ ├── __init__.py
│ │ ├── expr.py
│ │ └── parser.py
│ └── rule.py
├── nslink
│ ├── __init__.py
│ └── nspopen.py
├── plan9
│ ├── __init__.py
│ ├── client.py
│ ├── filesystem.py
│ ├── ipc.py
│ ├── plan9socket.py
│ └── server.py
├── process.py
├── protocols
│ └── __init__.py
├── requests
│ ├── __init__.py
│ ├── address.py
│ ├── bridge.py
│ ├── common.py
│ ├── link.py
│ ├── main.py
│ ├── neighbour.py
│ ├── netns.py
│ ├── probe.py
│ ├── route.py
│ ├── rule.py
│ └── tc.py
├── statsd.py
└── wiset.py
├── requirements.dev.txt
├── requirements.docs.txt
├── requirements.repo.txt
├── setup.cfg
├── setup.minimal.cfg
├── setup.py
├── tests
├── mocklib
│ ├── dateutil
│ │ ├── __init__.py
│ │ └── parser.py
│ ├── keystoneauth1
│ │ ├── __init__.py
│ │ ├── identity
│ │ │ ├── __init__.py
│ │ │ └── v3.py
│ │ └── session
│ │ │ └── __init__.py
│ ├── keystoneclient
│ │ ├── __init__.py
│ │ └── v3
│ │ │ ├── __init__.py
│ │ │ ├── client.py
│ │ │ └── tokens.py
│ └── pyrad
│ │ ├── __init__.py
│ │ ├── client.py
│ │ ├── dictionary.py
│ │ └── packet.py
├── net_tools.py
├── test_ci
│ ├── conftest.py
│ └── test_fixtures.py
├── test_core
│ ├── conftest.py
│ ├── test_check_tid.py
│ ├── test_event_loop.py
│ ├── test_ipr
│ │ ├── test_addr_async.py
│ │ ├── test_addr_sync.py
│ │ ├── test_ensure_async.py
│ │ ├── test_ensure_sync.py
│ │ ├── test_link_async.py
│ │ ├── test_link_sync.py
│ │ ├── test_route_async.py
│ │ ├── test_route_dump_async.py
│ │ ├── test_route_dump_sync.py
│ │ ├── test_route_sync.py
│ │ ├── test_rule_async.py
│ │ ├── test_rule_sync.py
│ │ ├── test_tc_async.py
│ │ └── test_tc_sync.py
│ ├── test_nftables
│ │ ├── test_expressions.py
│ │ └── test_nftsocket.py
│ ├── test_plan9
│ │ └── test_basic.py
│ ├── test_socket_create.py
│ └── test_statsd.py
├── test_decoder
│ ├── nl0.json
│ ├── nl0.pcap
│ └── test_pcap.py
├── test_integration
│ ├── conftest.py
│ ├── test_kuryr.py
│ ├── test_lnst.py
│ ├── test_octavia.py
│ ├── test_os_vif.py
│ └── test_ovn_bgp_agent.py
├── test_limits
│ ├── conftest.py
│ ├── test_nl.py
│ └── test_stress.py
├── test_linux
│ ├── conftest.py
│ ├── fixtures
│ │ ├── dhcp_servers
│ │ │ ├── __init__.py
│ │ │ ├── dnsmasq.py
│ │ │ ├── mock.py
│ │ │ └── udhcpd.py
│ │ ├── interfaces.py
│ │ └── pcap_files.py
│ ├── pr2test
│ │ ├── __init__.py
│ │ ├── context_manager.py
│ │ ├── custom_link_kind
│ │ │ ├── __init__.py
│ │ │ └── foo.py
│ │ ├── marks.py
│ │ └── tools.py
│ ├── test_api
│ │ └── __init__.py
│ ├── test_connector
│ │ └── test_cn_proc.py
│ ├── test_conntrack.py
│ ├── test_devlink.py
│ ├── test_dhcp
│ │ ├── captures
│ │ │ ├── test_parser
│ │ │ │ ├── test_android_reboot_request.pcap
│ │ │ │ ├── test_android_tethering_renew.pcap
│ │ │ │ ├── test_decode_simple_lease_process.pcap
│ │ │ │ ├── test_huawei_discover_option_148.pcap
│ │ │ │ ├── test_invalid_client_id_option.pcap
│ │ │ │ ├── test_invalid_router_option.pcap
│ │ │ │ ├── test_netatmo_discover_request.pcap
│ │ │ │ ├── test_truncated_packet.pcap
│ │ │ │ ├── test_washing_machine_request.pcap
│ │ │ │ └── test_wii_discover.pcap
│ │ │ └── test_unit
│ │ │ │ ├── test_ack_invalid_request_state.pcap
│ │ │ │ ├── test_get_and_renew_lease.pcap
│ │ │ │ ├── test_init_reboot_nak.pcap
│ │ │ │ ├── test_offer_wrong_xid.pcap
│ │ │ │ ├── test_requesting_timeout.pcap
│ │ │ │ ├── test_truncated_packet.pcap
│ │ │ │ ├── test_unexpected_dhcp_message.pcap
│ │ │ │ └── test_unknown_message.pcap
│ │ ├── conftest.py
│ │ ├── test_cli.py
│ │ ├── test_encode.py
│ │ ├── test_hooks.py
│ │ ├── test_integration.py
│ │ ├── test_parser.py
│ │ ├── test_server_detector.py
│ │ └── test_unit.py
│ ├── test_diag.py
│ ├── test_dquot
│ │ ├── dquot.img.gz
│ │ └── test_dquot.py
│ ├── test_ethtool.py
│ ├── test_generic
│ │ ├── __init__.py
│ │ ├── test_basic.py
│ │ ├── test_l2tp.py
│ │ ├── test_mptcp.py
│ │ └── test_taskstats.py
│ ├── test_integration
│ │ └── test_serialize.py
│ ├── test_ipr
│ │ ├── __init__.py
│ │ ├── test_addr.py
│ │ ├── test_basic.py
│ │ ├── test_callbacks.py
│ │ ├── test_compile.py
│ │ ├── test_config.py
│ │ ├── test_fdb.py
│ │ ├── test_ipbatch.py
│ │ ├── test_link.py
│ │ ├── test_link_create.py
│ │ ├── test_link_custom_kind.py
│ │ ├── test_match.py
│ │ ├── test_neigh.py
│ │ ├── test_netns.py
│ │ ├── test_ntables.py
│ │ ├── test_probe.py
│ │ ├── test_route.py
│ │ ├── test_rule.py
│ │ ├── test_stress.py
│ │ ├── test_vlan.py
│ │ └── test_vlan_filter.py
│ ├── test_ipset.py
│ ├── test_ipvs.py
│ ├── test_iwutil.py
│ ├── test_ndb
│ │ ├── __init__.py
│ │ ├── test_address.py
│ │ ├── test_altnames.py
│ │ ├── test_backup.py
│ │ ├── test_chaotic.py
│ │ ├── test_db.py
│ │ ├── test_ensure.py
│ │ ├── test_examples.py
│ │ ├── test_fdb.py
│ │ ├── test_init.py
│ │ ├── test_interface_create.py
│ │ ├── test_interface_set.py
│ │ ├── test_mpls.py
│ │ ├── test_neighbour.py
│ │ ├── test_netns.py
│ │ ├── test_probe.py
│ │ ├── test_reports.py
│ │ ├── test_rollback.py
│ │ ├── test_routes.py
│ │ ├── test_rules.py
│ │ ├── test_sources.py
│ │ ├── test_syntax.py
│ │ ├── test_transaction.py
│ │ └── test_views.py
│ ├── test_netns
│ │ └── test_nspopen.py
│ ├── test_nlmsg
│ │ └── test_nlmsg.py
│ ├── test_tc
│ │ ├── __init__.py
│ │ ├── test_actions.py
│ │ ├── test_basic.py
│ │ ├── test_bpf.py
│ │ ├── test_classful.py
│ │ ├── test_htb.py
│ │ └── test_ingress.py
│ ├── test_wireguard
│ │ ├── __init__.py
│ │ └── test_peer.py
│ └── test_wiset.py
├── test_minimal
│ └── test_iproute.py
├── test_neutron
│ └── test_ip_lib.py
├── test_openbsd
│ ├── conftest.py
│ └── test_ipr
│ │ └── test_basic.py
├── test_process
│ ├── test_basic.py
│ └── test_catastrophe.py
├── test_repo
│ ├── test_minimal.py
│ ├── test_noxfile.py
│ └── test_version.py
├── test_unit
│ ├── test_addr_pool.py
│ ├── test_buffer.py
│ ├── test_common.py
│ ├── test_config.py
│ ├── test_entry_points
│ │ └── test_basic.py
│ ├── test_iproute_match
│ │ ├── links.dump
│ │ └── test_match.py
│ ├── test_nlmsg
│ │ ├── addrmsg_ipv4.dump
│ │ ├── gre_01.dump
│ │ ├── iw_info_rsp.dump
│ │ ├── iw_scan_rsp.dump
│ │ ├── test_attr.py
│ │ ├── test_map_adapter.py
│ │ ├── test_marshal.py
│ │ ├── uevent_kernel_backlight.dump
│ │ └── uevent_udevd_backlight.dump
│ └── test_requests
│ │ ├── common.py
│ │ ├── test_address.py
│ │ ├── test_link.py
│ │ ├── test_neighbour.py
│ │ └── test_route.py
├── test_windows
│ └── test_ipr.py
└── utils.py
└── util
├── aafigure_mapper.py
├── aafigure_mapper.sh
├── find_python.sh
├── imports_dict.awk
└── update_version.py
/.flake8:
--------------------------------------------------------------------------------
1 | [flake8]
2 |
3 | ignore = E203,E722,W503
4 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: svinota
2 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "github-actions"
4 | directory: "/"
5 | schedule:
6 | interval: "weekly"
7 |
--------------------------------------------------------------------------------
/.github/workflows/codeql.yaml:
--------------------------------------------------------------------------------
1 | name: "Code Scanning - Action"
2 |
3 | on:
4 | pull_request:
5 | push:
6 |
7 | jobs:
8 | CodeQL-Build:
9 | # CodeQL runs on ubuntu-latest, windows-latest, and macos-latest
10 | runs-on: ubuntu-latest
11 |
12 | permissions:
13 | # required for all workflows
14 | security-events: write
15 |
16 | steps:
17 | - name: Checkout repository
18 | uses: actions/checkout@v4
19 |
20 | # Initializes the CodeQL tools for scanning.
21 | - name: Initialize CodeQL
22 | uses: github/codeql-action/init@v3
23 | # Override language selection by uncommenting this and choosing your languages
24 | # with:
25 | # languages: go, javascript, csharp, python, cpp, java
26 |
27 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
28 | # If this step fails, then you should remove it and run the build manually (see below).
29 | - name: Autobuild
30 | uses: github/codeql-action/autobuild@v3
31 |
32 | # ℹ️ Command-line programs to run using the OS shell.
33 | # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
34 |
35 | # ✏️ If the Autobuild fails above, remove it and uncomment the following
36 | # three lines and modify them (or add more) to build your code if your
37 | # project uses a compiled language
38 |
39 | #- run: |
40 | # make bootstrap
41 | # make release
42 |
43 | - name: Perform CodeQL Analysis
44 | uses: github/codeql-action/analyze@v3
45 |
--------------------------------------------------------------------------------
/.github/workflows/depsreview.yaml:
--------------------------------------------------------------------------------
1 | name: 'Dependency Review'
2 | on: [pull_request]
3 |
4 | permissions:
5 | contents: read
6 |
7 | jobs:
8 | dependency-review:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: 'Checkout Repository'
12 | uses: actions/checkout@v4
13 | - name: 'Dependency Review'
14 | uses: actions/dependency-review-action@v4
15 |
--------------------------------------------------------------------------------
/.github/workflows/push.yml:
--------------------------------------------------------------------------------
1 | name: Linter
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 | workflow_dispatch:
7 |
8 | permissions:
9 | contents: read
10 |
11 | jobs:
12 | build:
13 | runs-on: Fedora
14 | strategy:
15 | matrix:
16 | python: [python3.9, python3.14]
17 | steps:
18 | - run: sudo chown -R $USER:$USER $GITHUB_WORKSPACE
19 | - uses: actions/checkout@v4
20 | - run: make nox session=linter-${{ matrix.python }}
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | .eggs/
3 | *.swp
4 | *.pyc
5 | *~
6 | pyroute2/config/version.py
7 | build/
8 | dist/
9 | MANIFEST
10 | docs/html
11 | docs/man
12 | docs/doctrees
13 | docs/_templates/private.layout.html
14 | docs-build.log
15 | lab/_build
16 | lab/*html
17 | lab/_static/conf.js
18 | *.egg-info
19 | benchmark.log
20 | venv
21 | .venv
22 | .nox*
23 | tests/*.db
24 | tests/*.json
25 |
--------------------------------------------------------------------------------
/.mypy-check-paths:
--------------------------------------------------------------------------------
1 | pyroute2/common.py
2 | pyroute2/fixtures
3 | pyroute2/netlink/core.py
4 | pyroute2/netlink/coredata.py
5 | pyroute2/netlink/nlsocket.py
6 | pyroute2/netlink/uevent/__init__.py
7 | pyroute2/netlink/rtnl/iprsocket.py
8 | pyroute2/netlink/rtnl/ifinfmsg/tuntap.py
9 | pyroute2/netns/
10 | pyroute2/plan9/client.py
11 | pyroute2/process.py
12 | pyroute2/statsd.py
13 |
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | files: '^(noxfile.py|pyroute2|pr2modules|util|examlpes/ndb|docs/conf.py|examples/pyroute2-cli|tests)'
2 | repos:
3 | - repo: https://github.com/pre-commit/pre-commit-hooks
4 | rev: v4.5.0
5 | hooks:
6 | - id: trailing-whitespace
7 | - id: end-of-file-fixer
8 | - repo: https://github.com/pycqa/isort
9 | rev: 5.13.2
10 | hooks:
11 | - id: isort
12 | name: isort (python)
13 | args: ['-m', '3', '--tc', '-w', '79', '--profile', 'black']
14 | - repo: https://github.com/psf/black
15 | rev: 24.1.1
16 | hooks:
17 | - id: black
18 | args: ['-C', '-S', '-l', '79']
19 | - repo: https://github.com/PyCQA/flake8
20 | rev: 7.0.0
21 | hooks:
22 | - id: flake8
23 | files: \.py$
24 | args: ['--config', '.flake8']
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GPL-2.0-or-later OR Apache-2.0
2 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include VERSION
2 | include README.rst
3 | include README.contribute.rst
4 | include README.minimal.rst
5 | include README.report.rst
6 | include README.license.rst
7 | include LICENSE*
8 | include CHANGELOG.rst
9 | graft docs/html
10 | graft tests/test_unit
11 | graft examples
12 |
--------------------------------------------------------------------------------
/README.license.rst:
--------------------------------------------------------------------------------
1 | Pyroute2 package is dual licensed since 0.3.6, emerging two licenses:
2 |
3 | * GPL-2.0-or-later
4 | * Apache-2.0
5 |
6 | It means, that being writing some derived code, or including the
7 | library into distribution, you are free to choose the license from the
8 | list above.
9 |
10 | Apache v2 license was included to make the code compatible with the
11 | OpenStack project.
12 |
--------------------------------------------------------------------------------
/README.minimal.rst:
--------------------------------------------------------------------------------
1 | pyroute2.minimal
2 | ================
3 |
4 | PyRoute2 is a pure Python **netlink** library.
5 |
6 | This module provides minimal subset of pyroute2 modules. Only netlink parser,
7 | basic netns management and some netlink protocols implementations.
8 |
9 | links
10 | =====
11 |
12 | * Home:
13 | * PyPI:
14 | * Usage:
15 |
--------------------------------------------------------------------------------
/README.report.rst:
--------------------------------------------------------------------------------
1 | Report a bug
2 | ============
3 |
4 | In the case you have issues, please report them to the project
5 | bug tracker: https://github.com/svinota/pyroute2/issues
6 |
7 | It is important to provide all the required information
8 | with your report:
9 |
10 | * Linux kernel version
11 | * Python version
12 | * Specific environment, if used -- gevent, eventlet etc.
13 |
--------------------------------------------------------------------------------
/VERSION:
--------------------------------------------------------------------------------
1 | 0.9.2
2 |
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | Documentation
2 | -------------
3 |
4 | That's the project documentation source. In order to build
5 | html docs, one should install sphinx and run `make docs`
6 | in the project's root directory.
7 |
8 | Actual built docs are available at http://docs.pyroute2.org/
9 |
--------------------------------------------------------------------------------
/docs/_static/.empty:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/docs/_static/.empty
--------------------------------------------------------------------------------
/docs/_static/classic.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/docs/_static/classic.css
--------------------------------------------------------------------------------
/docs/_templates/.empty:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/docs/_templates/.empty
--------------------------------------------------------------------------------
/docs/_templates/layout.html:
--------------------------------------------------------------------------------
1 | {% extends '!layout.html' %}
2 |
3 | {%- macro c_relbar() %}
4 |
22 | {%- endmacro %}
23 |
24 | {% block relbar1 %}
25 | {{ c_relbar() }}
26 | {% endblock %}
27 |
--------------------------------------------------------------------------------
/docs/aafigure.map:
--------------------------------------------------------------------------------
1 | source|../ndb_sources.html
2 | SQL database|../ndb_schema.html
3 | SQLite|../ndb_schema.html
4 | PostgreSQL|../ndb_schema.html
5 | NDB object:|../ndb_objects.html
6 | interface|../ndb_objects.html
7 | address|../ndb_objects.html
8 | route|../ndb_objects.html
9 | netlink events|../netlink.html
10 | inotify events|../netlink.html
11 | NDB() instance|../ndb.html
12 | View()|../ndb_objects.html
13 | .dump()|../ndb_objects.html
14 | .summary()|../ndb_objects.html
15 | RecordSet()|../ndb_reports.html
16 | filter()|../ndb_reports.html
17 | select()|../ndb_reports.html
18 | transform()|../ndb_reports.html
19 | join()|../ndb_reports.html
20 | Record()|../ndb_reports.html
21 | .create()|../ndb_objects.html
22 | .__getitem__()|../ndb_objects.html
23 | Interface()|../ndb_interfaces.html
24 | Address()|../ndb_addresses.html
25 | Route()|../ndb_routes.html
26 | Neighbour()|../ndb.html
27 | Rule()|../ndb.html
28 |
--------------------------------------------------------------------------------
/docs/conf.py:
--------------------------------------------------------------------------------
1 | import pyroute2
2 |
3 | extensions = [
4 | 'sphinx.ext.autodoc',
5 | 'sphinx.ext.doctest',
6 | 'sphinx.ext.inheritance_diagram',
7 | 'aafigure.sphinxext',
8 | 'code_include.extension',
9 | ]
10 |
11 | aafig_format = {'html': 'svg', 'man': None, '': None}
12 |
13 | inheritance_graph_attrs = {'rankdir': 'LR', 'ratio': 'auto'}
14 | source_suffix = '.rst'
15 | master_doc = 'index'
16 | project = u'pyroute2'
17 | copyright = u'pyroute2 team'
18 |
19 | release = pyroute2.__version__
20 |
21 | exclude_patterns = ['_build']
22 | pygments_style = 'sphinx'
23 | autodoc_member_order = 'bysource'
24 |
25 | html_theme = 'default'
26 | html_static_path = ['_static']
27 | html_js_files = ['fixup.js']
28 | html_css_files = ['custom.css']
29 | htmlhelp_basename = 'pyroute2doc'
30 | templates_path = ['_templates']
31 |
32 |
33 | man_pages = [
34 | (
35 | 'pyroute2-cli',
36 | 'pyroute2-cli',
37 | 'pyroute2 command line interface',
38 | ['Peter Saveliev'],
39 | 1,
40 | ),
41 | (
42 | 'pyroute2-dhcp-client',
43 | 'pyroute2-dhcp-client',
44 | 'pyroute2 dhcp client',
45 | ['Étienne Noss', 'Peter Saveliev'],
46 | 1,
47 | ),
48 | (
49 | 'dhcp-server-detector',
50 | 'dhcp-server-detector',
51 | 'dhcp server detector',
52 | ['Étienne Noss'],
53 | 1,
54 | ),
55 | ]
56 |
--------------------------------------------------------------------------------
/docs/debug.rst:
--------------------------------------------------------------------------------
1 | .. debug:
2 |
3 | Netlink debugging howto
4 | -----------------------
5 |
6 | pyroute2-decoder
7 | ================
8 |
9 | .. automodule:: pyroute2.decoder.main
10 | :members:
11 |
12 | filter functions
13 | ================
14 | .. automodule:: pyroute2.decoder.loader
15 | :members: MatchOps
16 |
--------------------------------------------------------------------------------
/docs/deprecated.rst:
--------------------------------------------------------------------------------
1 | .. _deprecated:
2 |
3 | .. automodule:: pyroute2.ipdb
4 |
--------------------------------------------------------------------------------
/docs/event.rst:
--------------------------------------------------------------------------------
1 | .. _event:
2 |
3 | Generic netlink events protocols
4 | ================================
5 |
6 | The only available method for the event sockets is `get()` -- it returns
7 | an iterator over broadcasted messages, following the generic pyroute2 API.
8 | Even though the event protocols provide one message per `recv()`.
9 |
10 | No manual `bind()` or `discovery()` required -- the event sockets run
11 | these methods authomatically.
12 |
13 | Please keep in mind that you have to consume all the incoming messages
14 | in time, otherwise a buffer overflow happens on the socket and the only
15 | way to fix that is to `close()` the failed socket and to open a new one.
16 |
17 | ACPI events
18 | -----------
19 |
20 | .. automodule:: pyroute2.netlink.event.acpi_event
21 |
22 | Disk quota events
23 | -----------------
24 |
25 | .. automodule:: pyroute2.netlink.event.dquot
26 |
--------------------------------------------------------------------------------
/docs/fixtures.rst:
--------------------------------------------------------------------------------
1 | .. _fixtures:
2 |
3 | .. automodule:: pyroute2.fixtures
4 | :members:
5 |
--------------------------------------------------------------------------------
/docs/index.rst:
--------------------------------------------------------------------------------
1 | .. pyroute2 documentation master file
2 |
3 | Pyroute2 netlink library
4 | ========================
5 |
6 | General information
7 | -------------------
8 |
9 | .. toctree::
10 | :maxdepth: 2
11 |
12 | general
13 | changelog
14 | report
15 |
16 | Usage
17 | -----
18 |
19 | .. toctree::
20 | :maxdepth: 2
21 |
22 | usage
23 | asyncio
24 | threading
25 | iproute
26 | ndb
27 | fixtures
28 | plan9
29 | wiset
30 | ipset
31 | netns
32 | wireguard
33 | event
34 |
35 | Howtos
36 | ------
37 |
38 | .. toctree::
39 | :maxdepth: 2
40 |
41 | mpls
42 | debug
43 |
44 | Man pages
45 | ---------
46 |
47 | .. toctree::
48 | :maxdepth: 1
49 |
50 | pyroute2-cli
51 | pyroute2-dhcp-client
52 | dhcp-server-detector
53 |
54 | Development
55 | -----------
56 |
57 | .. toctree::
58 | :maxdepth: 2
59 |
60 | devcontribute
61 | arch
62 | parser
63 | netlink
64 |
65 | Deprecated
66 | ----------
67 |
68 | .. toctree::
69 | :maxdepth: 1
70 |
71 | deprecated
72 |
73 | Indices and tables
74 | ==================
75 |
76 | * :ref:`genindex`
77 | * :ref:`modindex`
78 | * :ref:`search`
79 |
80 |
--------------------------------------------------------------------------------
/docs/iproute.rst:
--------------------------------------------------------------------------------
1 | .. _iproute:
2 |
3 | IPRoute and related modules
4 | ===========================
5 |
6 | .. toctree::
7 | :maxdepth: 2
8 |
9 | iproute_intro
10 | iproute_netns
11 | iproute_responses
12 | iproute_linux
13 |
14 | ..
15 | excluded chapters:
16 | iproute_platforms
17 | iproute_tc
18 |
--------------------------------------------------------------------------------
/docs/iproute_linux.rst:
--------------------------------------------------------------------------------
1 | .. _iproute_linux:
2 |
3 | .. testsetup:: *
4 |
5 | from pyroute2 import config, IPRoute
6 | config.mock_netlink = True
7 | ipr = IPRoute()
8 |
9 | .. testcleanup:: *
10 |
11 | ipr.close()
12 |
13 |
14 | Linux systems
15 | -------------
16 |
17 | .. automodule:: pyroute2.iproute.linux
18 |
19 | .. autoclass:: pyroute2.iproute.linux.RTNL_API
20 | :members:
21 |
--------------------------------------------------------------------------------
/docs/iproute_platforms.rst.disabled:
--------------------------------------------------------------------------------
1 | .. _iproute_platforms:
2 |
3 | Non-RTNL platforms
4 | ------------------
5 |
6 | `pyroute2` offers experimental support for platforms that do not
7 | provide Netlink/RTNL, including BSD systems.
8 |
9 | BSD systems
10 | ~~~~~~~~~~~
11 |
12 | .. automodule:: pyroute2.iproute.bsd
13 |
14 | Windows systems
15 | ~~~~~~~~~~~~~~~
16 |
17 | .. automodule:: pyroute2.iproute.windows
18 |
19 | .. autoclass:: pyroute2.iproute.windows.IPRoute
20 | :members:
21 |
--------------------------------------------------------------------------------
/docs/iproute_tc.rst.disabled:
--------------------------------------------------------------------------------
1 | .. _iproute_tc:
2 |
3 | Queueing disciplines
4 | --------------------
5 |
6 | .. automodule:: pyroute2.netlink.rtnl.tcmsg.sched_drr
7 | :members:
8 |
9 | .. automodule:: pyroute2.netlink.rtnl.tcmsg.sched_choke
10 | :members:
11 |
12 | .. automodule:: pyroute2.netlink.rtnl.tcmsg.sched_clsact
13 | :members:
14 |
15 | .. automodule:: pyroute2.netlink.rtnl.tcmsg.sched_hfsc
16 | :members:
17 |
18 | .. automodule:: pyroute2.netlink.rtnl.tcmsg.sched_htb
19 | :members:
20 |
21 | Filters
22 | -------
23 |
24 | .. automodule:: pyroute2.netlink.rtnl.tcmsg.cls_u32
25 |
--------------------------------------------------------------------------------
/docs/ipset.rst:
--------------------------------------------------------------------------------
1 | .. ipset:
2 |
3 | IPSet module
4 | ==============
5 |
6 | .. automodule:: pyroute2.ipset
7 | :members:
8 |
--------------------------------------------------------------------------------
/docs/ndb.rst:
--------------------------------------------------------------------------------
1 | .. _ndb:
2 |
3 | NDB module intro
4 | ================
5 |
6 | .. automodule:: pyroute2.ndb.main
7 |
8 | NDB reference
9 | =============
10 |
11 | .. include:: ndb_toc.rst
12 |
--------------------------------------------------------------------------------
/docs/ndb_addresses.rst:
--------------------------------------------------------------------------------
1 | .. ndbaddresses:
2 |
3 | IP addresses management
4 | =======================
5 |
6 | .. automodule:: pyroute2.ndb.objects.address
7 |
--------------------------------------------------------------------------------
/docs/ndb_auth.rst:
--------------------------------------------------------------------------------
1 | .. _ndbauth:
2 |
3 | Authorization plugins
4 | =====================
5 |
6 | .. automodule:: pyroute2.ndb.auth_manager
7 |
8 | Usecase: OpenStack Keystone auth
9 | --------------------------------
10 |
11 | Say we have a public service that provides access to NDB instance via
12 | HTTP, and authenticates users via Keystone. Then the auth flow could be:
13 |
14 | 1. Accept a connection from a client
15 | 2. Create custom auth manager object A
16 | 3. A.__init__() validates X-Auth-Token against Keystone (Authentication)
17 | 4. A.check() checks that X-Auth-Token is not expired (Authorization)
18 | 5. The auth result is being logged (Accounting)
19 |
20 | An example AuthManager with OpenStack APIv3 support you may find in the
21 | `/examples/ndb/` directory.
22 |
23 | .. literalinclude:: ../examples/ndb/keystone_auth.py
24 | :language: python
25 | :caption: keystone_auth.py
26 | :name: keystone_auth
27 |
28 | Usecase: RADIUS auth
29 | --------------------
30 |
31 | .. literalinclude:: ../examples/ndb/radius_auth.py
32 | :language: python
33 | :caption: radius_auth.py
34 | :name: radius_auth
35 |
--------------------------------------------------------------------------------
/docs/ndb_interfaces.rst:
--------------------------------------------------------------------------------
1 | .. _ndbinterfaces:
2 |
3 | Network interfaces
4 | ==================
5 |
6 | .. automodule:: pyroute2.ndb.objects.interface
7 |
--------------------------------------------------------------------------------
/docs/ndb_objects.rst:
--------------------------------------------------------------------------------
1 | .. ndbobjects:
2 |
3 | RTNL objects
4 | ============
5 |
6 | .. automodule:: pyroute2.ndb.objects
7 |
8 | .. autoclass:: pyroute2.ndb.objects.RTNL_Object()
9 |
10 | .. autoproperty:: table
11 | .. autoproperty:: etable
12 | .. autoproperty:: key
13 | .. automethod:: apply
14 | .. automethod:: commit
15 | .. automethod:: complete_key
16 | .. automethod:: create(**spec)
17 | .. automethod:: exists
18 | .. automethod:: load_sql
19 | .. automethod:: load_value
20 | .. automethod:: set(key, value)
21 | .. automethod:: show(fmt)
22 | .. automethod:: snapshot
23 | .. automethod:: rollback
24 |
--------------------------------------------------------------------------------
/docs/ndb_probes.rst:
--------------------------------------------------------------------------------
1 | .. ndbprobes:
2 |
3 | Network probes
4 | ==============
5 |
6 | .. automodule:: pyroute2.ndb.objects.probe
7 |
--------------------------------------------------------------------------------
/docs/ndb_reports.rst:
--------------------------------------------------------------------------------
1 | .. _ndbreports:
2 |
3 | Record list filters
4 | ===================
5 |
6 | .. automodule:: pyroute2.ndb.report
7 | :members:
8 |
--------------------------------------------------------------------------------
/docs/ndb_routes.rst:
--------------------------------------------------------------------------------
1 | .. _ndbroutes:
2 |
3 | Routes management
4 | =================
5 |
6 | .. automodule:: pyroute2.ndb.objects.route
7 |
--------------------------------------------------------------------------------
/docs/ndb_schema.rst:
--------------------------------------------------------------------------------
1 | .. _ndbschema:
2 |
3 | Database
4 | ========
5 |
6 | .. automodule:: pyroute2.ndb.schema
7 |
--------------------------------------------------------------------------------
/docs/ndb_sources.rst:
--------------------------------------------------------------------------------
1 | .. _ndbsources:
2 |
3 | RTNL sources
4 | ============
5 |
6 | .. automodule:: pyroute2.ndb.source
7 |
--------------------------------------------------------------------------------
/docs/ndb_toc.rst:
--------------------------------------------------------------------------------
1 | .. _ndb_toc:
2 |
3 | .. toctree::
4 | :maxdepth: 2
5 |
6 | ndb_init
7 | ndb_objects
8 | ndb_views
9 | ndb_transactions
10 | ndb_reports
11 | ndb_interfaces
12 | ndb_addresses
13 | ndb_routes
14 | ndb_probes
15 | ndb_schema
16 | ndb_sources
17 | ndb_debug
18 | ndb_auth
19 |
--------------------------------------------------------------------------------
/docs/ndb_transactions.rst:
--------------------------------------------------------------------------------
1 |
2 | .. ndbtransactions:
3 |
4 | Transactions
5 | ============
6 |
7 | .. automodule:: pyroute2.ndb.transaction
8 | :members:
9 |
--------------------------------------------------------------------------------
/docs/ndb_views.rst:
--------------------------------------------------------------------------------
1 | .. ndbviews:
2 |
3 | Views
4 | =====
5 |
6 | .. automodule:: pyroute2.ndb.view
7 |
8 | .. autoclass:: pyroute2.ndb.view.View()
9 | :members:
10 |
--------------------------------------------------------------------------------
/docs/netlink.rst:
--------------------------------------------------------------------------------
1 | .. netlink:
2 |
3 | .. automodule:: pyroute2.netlink
4 |
--------------------------------------------------------------------------------
/docs/netns.rst:
--------------------------------------------------------------------------------
1 | .. _netns:
2 |
3 | NetNS management
4 | ================
5 |
6 | .. automodule:: pyroute2.netns
7 | :members: create,
8 | remove,
9 | attach,
10 | setns,
11 | pushns,
12 | popns,
13 | dropns,
14 | listnetns,
15 | ns_pids,
16 | pid_to_ns
17 |
18 | .. automodule:: pyroute2.nslink.nspopen
19 | :members:
20 |
--------------------------------------------------------------------------------
/docs/nlsocket.rst.disabled:
--------------------------------------------------------------------------------
1 | .. nlsocket:
2 |
3 | .. automodule:: pyroute2.netlink.nlsocket
4 | :members:
5 |
--------------------------------------------------------------------------------
/docs/plan9.rst:
--------------------------------------------------------------------------------
1 | .. _plan9:
2 |
3 | .. testsetup::
4 |
5 | import asyncio
6 |
7 | from pyroute2.plan9.server import Plan9ServerSocket
8 | from pyroute2.plan9.client import Plan9ClientSocket
9 |
10 |
11 | Plan9 9p2000 protocol
12 | =====================
13 |
14 | The library provides basic asynchronous 9p2000 implementation.
15 |
16 | .. autoclass:: pyroute2.plan9.server.Plan9ServerSocket
17 | :members:
18 |
19 | .. autoclass:: pyroute2.plan9.client.Plan9ClientSocket
20 | :members:
21 |
--------------------------------------------------------------------------------
/docs/wireguard.rst:
--------------------------------------------------------------------------------
1 | .. _wireguard:
2 |
3 | WireGuard module
4 | ================
5 |
6 | .. automodule:: pyroute2.netlink.generic.wireguard
7 |
--------------------------------------------------------------------------------
/docs/wiset.rst:
--------------------------------------------------------------------------------
1 | .. wiset:
2 |
3 | WiSet module
4 | ============
5 |
6 | .. automodule:: pyroute2.wiset
7 | :members:
8 |
--------------------------------------------------------------------------------
/examples/README.md:
--------------------------------------------------------------------------------
1 | Examples
2 | ========
3 |
--------------------------------------------------------------------------------
/examples/devlink/devlink_list.py:
--------------------------------------------------------------------------------
1 | from pyroute2 import DL
2 |
3 | dl = DL()
4 | for q in dl.get_dump():
5 | print(
6 | '%s\t%s'
7 | % (
8 | q.get_attr('DEVLINK_ATTR_BUS_NAME'),
9 | q.get_attr('DEVLINK_ATTR_DEV_NAME'),
10 | )
11 | )
12 | dl.close()
13 |
--------------------------------------------------------------------------------
/examples/devlink/devlink_monitor.py:
--------------------------------------------------------------------------------
1 | from pyroute2.devlink import DL
2 |
3 |
4 | dl = DL(groups=~0)
5 | print(dl.get())
6 | dl.close()
7 |
--------------------------------------------------------------------------------
/examples/devlink/devlink_port_list.py:
--------------------------------------------------------------------------------
1 | from pyroute2 import DL
2 |
3 | dl = DL()
4 | for q in dl.get_port_dump():
5 | print(
6 | '%s\t%s\t%u'
7 | % (
8 | q.get_attr('DEVLINK_ATTR_BUS_NAME'),
9 | q.get_attr('DEVLINK_ATTR_DEV_NAME'),
10 | q.get_attr('DEVLINK_ATTR_PORT_INDEX'),
11 | )
12 | )
13 | dl.close()
14 |
--------------------------------------------------------------------------------
/examples/ethtool/ethtool-ioctl_get_infos.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from pyroute2.ethtool.ioctl import IoctlEthtool
3 | from pyroute2.ethtool.ioctl import NotSupportedError
4 |
5 | if len(sys.argv) != 2:
6 | raise Exception("USAGE: {0} IFNAME".format(sys.argv[0]))
7 |
8 |
9 | dev = IoctlEthtool(sys.argv[1])
10 | print("=== Device cmd: ===")
11 | try:
12 | for name, value in dev.get_cmd().items():
13 | print("\t{}: {}".format(name, value))
14 | except NotSupportedError:
15 | print("Not supported by driver.\n")
16 | print("")
17 |
18 | print("=== Device feature: ===")
19 | for name, value, not_fixed, _, _ in dev.get_features():
20 | value = "on" if value else "off"
21 | if not not_fixed:
22 | # I love double negations
23 | value += " [fixed]"
24 | print("\t{}: {}".format(name, value))
25 |
26 | print("\n=== Device coalesce: ===")
27 | for name, value in dev.get_coalesce().items():
28 | print("\t{}: {}".format(name, value))
29 |
30 | print("\n=== Device statistics: ===")
31 | for name, value in dev.get_statistics():
32 | print("\t{}: {}".format(name, value))
33 |
--------------------------------------------------------------------------------
/examples/ethtool/ethtool-netlink_get_infos.py:
--------------------------------------------------------------------------------
1 | import pprint
2 | import sys
3 |
4 | from pyroute2.netlink.generic.ethtool import NlEthtool
5 |
6 | if len(sys.argv) != 2:
7 | raise Exception("USAGE: {0} IFNAME".format(sys.argv[0]))
8 |
9 |
10 | IFNAME = sys.argv[1]
11 | eth = NlEthtool()
12 |
13 | print("kernel ok?:", eth.is_nlethtool_in_kernel())
14 | pprint.pprint(eth.get_linkmode(IFNAME))
15 | print("")
16 | pprint.pprint(eth.get_linkinfo(IFNAME))
17 | print("")
18 | pprint.pprint(eth.get_stringset(IFNAME))
19 | print("")
20 | pprint.pprint(eth.get_linkstate(IFNAME))
21 | print("")
22 | pprint.pprint(eth.get_wol(IFNAME))
23 |
--------------------------------------------------------------------------------
/examples/ethtool/ethtool_get_infos.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from pyroute2.ethtool import Ethtool
3 |
4 | if len(sys.argv) != 2:
5 | raise Exception("USAGE: {0} IFNAME".format(sys.argv[0]))
6 | ethtool = Ethtool()
7 | ifname = sys.argv[1]
8 |
9 | print(ethtool.get_link_mode(ifname))
10 | print(ethtool.get_link_info(ifname))
11 | print(ethtool.get_strings_set(ifname))
12 | print(ethtool.get_wol(ifname))
13 | print(ethtool.get_features(ifname))
14 | print(ethtool.get_coalesce(ifname))
15 |
--------------------------------------------------------------------------------
/examples/generic/Makefile:
--------------------------------------------------------------------------------
1 | obj-m += netl.o
2 |
3 | all:
4 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
5 |
6 | clean:
7 | make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
8 |
9 |
--------------------------------------------------------------------------------
/examples/generic/netl.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | import traceback
4 | from pyroute2.netlink import NLM_F_REQUEST
5 | from pyroute2.netlink import genlmsg
6 | from pyroute2.netlink.generic import GenericNetlinkSocket
7 |
8 |
9 | RLINK_CMD_UNSPEC = 0
10 | RLINK_CMD_REQ = 1
11 |
12 |
13 | class rcmd(genlmsg):
14 | '''
15 | Message class that will be used to communicate
16 | with the kernel module
17 | '''
18 |
19 | nla_map = (
20 | ('RLINK_ATTR_UNSPEC', 'none'),
21 | ('RLINK_ATTR_DATA', 'asciiz'),
22 | ('RLINK_ATTR_LEN', 'uint32'),
23 | )
24 |
25 |
26 | class Rlink(GenericNetlinkSocket):
27 | def send_data(self, data):
28 | msg = rcmd()
29 | msg['cmd'] = RLINK_CMD_REQ
30 | msg['version'] = 1
31 | msg['attrs'] = [('RLINK_ATTR_DATA', data)]
32 | ret = self.nlm_request(msg, self.prid, msg_flags=NLM_F_REQUEST)[0]
33 | return ret.get_attr('RLINK_ATTR_LEN')
34 |
35 |
36 | if __name__ == '__main__':
37 | try:
38 | # create protocol instance
39 | rlink = Rlink()
40 | rlink.bind('EXMPL_GENL', rcmd)
41 | # request a method
42 | print(rlink.send_data('x' * 65000))
43 | except:
44 | # if there was an error, log it to the console
45 | traceback.print_exc()
46 | finally:
47 | # finally -- release the instance
48 | rlink.close()
49 |
--------------------------------------------------------------------------------
/examples/ipq.py:
--------------------------------------------------------------------------------
1 | from pyroute2.common import hexdump
2 | from pyroute2 import IPQSocket
3 | from pyroute2.netlink.ipq import NF_ACCEPT
4 | from dpkt.ip import IP
5 |
6 | ip = IPQSocket()
7 | ip.bind()
8 | try:
9 | while True:
10 | msg = ip.get()[0]
11 | print("\n")
12 | print(hexdump(msg.raw))
13 | print(repr(IP(msg['payload'])))
14 | ip.verdict(msg['packet_id'], NF_ACCEPT)
15 | except:
16 | pass
17 | finally:
18 | ip.release()
19 |
--------------------------------------------------------------------------------
/examples/iproute/ip_monitor.py:
--------------------------------------------------------------------------------
1 | '''
2 | Simplest example to monitor Netlink events with a Python script.
3 | '''
4 |
5 | from pyroute2 import IPRSocket
6 | from pprint import pprint
7 |
8 | ip = IPRSocket()
9 | ip.bind()
10 | pprint(ip.get())
11 | ip.close()
12 |
--------------------------------------------------------------------------------
/examples/iproute/socketcan.py:
--------------------------------------------------------------------------------
1 | '''
2 | Simplest example to set CAN bitrate.
3 | '''
4 |
5 | from pyroute2 import IPRoute
6 |
7 | with IPRoute() as ip_route:
8 | # loolkup can0 interface
9 | idx = ip_route.link_lookup(ifname='can0')[0]
10 | link = ip_route.link('get', index=idx)
11 |
12 | # bring can0 interface down. CAN settings can be set only
13 | # if the interface is down
14 | if 'state' in link[0] and link[0]['state'] == 'up':
15 | ip_route.link('set', index=idx, state='down')
16 |
17 | # set CAN birate
18 | ip_route.link('set', index=idx, kind='can', can_bittiming={'bitrate': 250000 })
19 |
20 | # bring can0 interface up
21 | ip_route.link('set', index=idx, state='up')
22 |
--------------------------------------------------------------------------------
/examples/ipset.py:
--------------------------------------------------------------------------------
1 | import socket
2 | from pyroute2.ipset import IPSet, PortRange, PortEntry
3 |
4 | ipset = IPSet()
5 | ipset.create("foo", stype="hash:ip")
6 | ipset.add("foo", "198.51.100.1", etype="ip")
7 | ipset.add("foo", "198.51.100.2", etype="ip")
8 | print(ipset.test("foo", "198.51.100.1")) # True
9 | print(ipset.test("foo", "198.51.100.10")) # False
10 | msg_list = ipset.list("foo")
11 | for msg in msg_list:
12 | for attr_data in msg.get_attr('IPSET_ATTR_ADT').get_attrs(
13 | 'IPSET_ATTR_DATA'
14 | ):
15 | for attr_ip_from in attr_data.get_attrs('IPSET_ATTR_IP_FROM'):
16 | for ipv4 in attr_ip_from.get_attrs('IPSET_ATTR_IPADDR_IPV4'):
17 | print("- " + ipv4)
18 | ipset.destroy("foo")
19 | ipset.close()
20 |
21 |
22 | ipset = IPSet()
23 | ipset.create("bar", stype="bitmap:port", bitmap_ports_range=(1000, 2000))
24 | ipset.add("bar", 1001, etype="port")
25 | ipset.add("bar", PortRange(1500, 2000), etype="port")
26 | print(ipset.test("bar", 1600, etype="port")) # True
27 | print(ipset.test("bar", 2600, etype="port")) # False
28 | ipset.destroy("bar")
29 | ipset.close()
30 |
31 |
32 | ipset = IPSet()
33 | protocol_tcp = socket.getprotobyname("tcp")
34 | ipset.create("foobar", stype="hash:net,port")
35 | port_entry_http = PortEntry(80, protocol=protocol_tcp)
36 | ipset.add("foobar", ("198.51.100.0/24", port_entry_http), etype="net,port")
37 | print(
38 | ipset.test("foobar", ("198.51.100.1", port_entry_http), etype="ip,port")
39 | ) # True
40 | port_entry_https = PortEntry(443, protocol=protocol_tcp)
41 | print(
42 | ipset.test("foobar", ("198.51.100.1", port_entry_https), etype="ip,port")
43 | ) # False
44 | ipset.destroy("foobar")
45 | ipset.close()
46 |
--------------------------------------------------------------------------------
/examples/kobject_uevent.py:
--------------------------------------------------------------------------------
1 | from pprint import pprint
2 | from pyroute2 import UeventSocket
3 |
4 | kus = UeventSocket()
5 | kus.bind()
6 | while True:
7 | pprint(kus.get())
8 |
--------------------------------------------------------------------------------
/examples/ndb/create_bond.py:
--------------------------------------------------------------------------------
1 | from pyroute2 import NDB
2 | from pyroute2.common import uifname
3 |
4 | # create unique interface names
5 | p0 = uifname()
6 | p1 = uifname()
7 | bond = uifname()
8 |
9 | with NDB() as ndb:
10 |
11 |
12 | # The same scheme works for bridge interfaces too: you
13 | # can create a bridge interface and assign ports to it
14 | # just as below.
15 | ndb.interfaces.create(kind='dummy', ifname=p0).commit()
16 | ndb.interfaces.create(kind='dummy', ifname=p1).commit()
17 |
18 | with ndb.interfaces.create(kind='bond', ifname=bond) as i:
19 | # assign two interfaces
20 | i.add_port(p0)
21 | i.add_port(p0)
22 | # make an example more scary: add IPs
23 | i.add_ip('10.251.0.1/24')
24 | i.add_ip('10.251.0.2/24')
25 |
26 | for i in (p0, p1, bond):
27 | ndb.interfaces[i].remove().commit()
28 |
--------------------------------------------------------------------------------
/examples/ndb/create_interface.py:
--------------------------------------------------------------------------------
1 | from pyroute2 import NDB
2 | from pyroute2.common import uifname
3 |
4 |
5 | with NDB() as ndb:
6 |
7 | # dummy, bridge and bond interfaces are created in the
8 | # same way
9 | #
10 | # uifname() function is used here only to generate a
11 | # unique name of the interface for the regression testing,
12 | # you can pick up any name
13 | #
14 | ifname = uifname()
15 | (
16 | ndb.interfaces.create(kind='dummy', ifname=ifname, state='up')
17 | .set('state', 'up')
18 | .set('address', '00:11:22:33:44:55')
19 | .commit()
20 | )
21 | print(ndb.interfaces[ifname].show('json'))
22 | (
23 | ndb.interfaces[ifname]
24 | .remove()
25 | .commit()
26 | )
27 |
--------------------------------------------------------------------------------
/examples/ndb/create_vlan.py:
--------------------------------------------------------------------------------
1 | from pyroute2 import NDB
2 | from pyroute2.common import uifname
3 |
4 | # unique interface names
5 | vlan_host = uifname()
6 | vlan_interface = uifname()
7 |
8 | with NDB() as ndb:
9 |
10 |
11 | (
12 | ndb.interfaces.create(ifname=vlan_host, kind='dummy')
13 | .set('state', 'up')
14 | .commit()
15 | )
16 | (
17 | ndb.interfaces.create(
18 | ifname=vlan_interface,
19 | kind='vlan',
20 | link=ndb.interfaces[vlan_host],
21 | vlan_id=101
22 | )
23 | .set('mtu', 1400)
24 | .set('state', 'up')
25 | .add_ip('10.251.0.1/24')
26 | .add_ip('10.251.0.2/24')
27 | .commit()
28 | )
29 |
30 | for i in (vlan_interface, vlan_host):
31 | ndb.interfaces[i].remove().commit()
32 |
--------------------------------------------------------------------------------
/examples/nftables.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | from pyroute2.nftables.main import NFTables
4 |
5 |
6 | # nfgen_family 0 == inet
7 | def show_nftables(family: int = 0) -> None:
8 | nft = NFTables(nfgen_family=family)
9 | tables = nft.get_tables()
10 | chains = nft.get_chains()
11 | rules = nft.get_rules()
12 |
13 | print("Tables:")
14 | print(tables)
15 | print("\nChains:")
16 | print(chains)
17 | print("\nRules:")
18 | for rule in rules:
19 | print(rule, type(rule))
20 |
21 |
22 | show_nftables(0)
23 |
--------------------------------------------------------------------------------
/examples/nftables_sets.py:
--------------------------------------------------------------------------------
1 | import time
2 |
3 | from pyroute2.netlink.nfnetlink.nftsocket import NFPROTO_IPV4
4 | from pyroute2.nftables.main import NFTables
5 | from pyroute2.nftables.main import NFTSetElem
6 |
7 |
8 | def test_ipv4_addr_set():
9 | with NFTables(nfgen_family=NFPROTO_IPV4) as nft:
10 | nft.table("add", name="filter")
11 | my_set = nft.sets("add", table="filter", name="test0", key_type="ipv4_addr",
12 | comment="my test set", timeout=0)
13 |
14 | # With str
15 | nft.set_elems(
16 | "add",
17 | table="filter",
18 | set="test0",
19 | elements={"10.2.3.4", "10.4.3.2"},
20 | )
21 |
22 | # With NFTSet & NFTSetElem classes
23 | nft.set_elems(
24 | "add",
25 | set=my_set,
26 | elements={NFTSetElem(value="9.9.9.9", timeout=1000)},
27 | )
28 |
29 | try:
30 | assert {e.value for e in nft.set_elems("get", table="filter", set="test0")} == {
31 | "10.2.3.4",
32 | "10.4.3.2",
33 | "9.9.9.9",
34 | }
35 | assert nft.sets("get", table="filter", name="test0").comment == b"my test set"
36 |
37 | time.sleep(1.2)
38 | # timeout for elem 9.9.9.9 (1000ms)
39 | assert {e.value for e in nft.set_elems("get", table="filter", set="test0")} == {
40 | "10.2.3.4",
41 | "10.4.3.2",
42 | }
43 | finally:
44 | nft.sets("del", table="filter", name="test0")
45 | nft.table("del", name="filter")
46 |
47 |
48 | def main():
49 | test_ipv4_addr_set()
50 |
51 |
52 | if __name__ == "__main__":
53 | main()
54 |
--------------------------------------------------------------------------------
/examples/policy/policy.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 |
3 | import traceback
4 | from pprint import pprint
5 | from pyroute2.netlink.generic import GenericNetlinkSocket
6 |
7 | if __name__ == '__main__':
8 | try:
9 | # create protocol instance
10 | genl = GenericNetlinkSocket(ext_ack=True)
11 |
12 | # extract policy
13 | msg = genl.policy('nlctrl')
14 |
15 | # dump policy information
16 | pprint(msg)
17 | except:
18 | # if there was an error, log it to the console
19 | traceback.print_exc()
20 | finally:
21 | # finally -- release the instance
22 | genl.close()
23 |
--------------------------------------------------------------------------------
/examples/processes/pmonitor.py:
--------------------------------------------------------------------------------
1 | '''
2 | Monitor process exit
3 | '''
4 | from pyroute2 import TaskStats
5 | from pyroute2.common import hexdump
6 |
7 | pmask = ''
8 |
9 | with open('/proc/cpuinfo', 'r') as f:
10 | for line in f.readlines():
11 | if line.startswith('processor'):
12 | pmask += ',' + line.split()[2]
13 | pmask = pmask[1:]
14 | ts = TaskStats()
15 | ts.register_mask(pmask)
16 | msg = ts.get()[0]
17 | print(hexdump(msg.raw))
18 | print(msg)
19 |
20 | ts.deregister_mask(pmask)
21 | ts.release()
22 |
--------------------------------------------------------------------------------
/examples/processes/taskstats.py:
--------------------------------------------------------------------------------
1 | '''
2 | Simple taskstats sample.
3 | '''
4 | import os
5 | from pyroute2 import TaskStats
6 |
7 | pid = os.getpid()
8 | ts = TaskStats()
9 | # bind is required in the case of generic netlink
10 | ts.bind()
11 | ret = ts.get_pid_stat(int(pid))[0]
12 | # parsed structure
13 | print(ret)
14 | ts.close()
15 |
--------------------------------------------------------------------------------
/examples/pyroute2-cli/comments:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env pyroute2-cli
2 | #
3 | ! Test mixed comments, both ! and #
4 | #
5 | interfaces # ... tail comments
6 | !
7 | # ... indented comments
8 | !
9 | create {ifname test01, kind dummy, address 00:11:22:33:44:55}
10 | commit
11 | !
12 | test01
13 | #
14 | show
15 | !
16 | remove
17 | commit
18 |
--------------------------------------------------------------------------------
/examples/pyroute2-cli/create_dummy:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env pyroute2-cli
2 | #
3 | #
4 | interfaces
5 | # create a dummy interface
6 | #
7 | # there the very minimal spec consists of ifname,
8 | # other properties may be set later
9 | #
10 | create {ifname test01}
11 | #
12 | # set properties
13 | kind dummy
14 | address 00:11:22:33:44:55
15 | commit
16 | #
17 | # create addresses ...
18 | ipaddr
19 | create {address 192.168.15.67, prefixlen 24}
20 | commit
21 | create {address 192.168.15.68, prefixlen 24}
22 | commit
23 | #
24 | # and remove one of them
25 | 192.168.15.68/24
26 | remove
27 | commit
28 | #
29 | # remove the interface
30 | remove
31 | commit
32 |
--------------------------------------------------------------------------------
/examples/pyroute2-cli/dump_lo:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env pyroute2-cli
2 | !
3 | ! Just dump the loopback interface.
4 | !
5 | interfaces lo show
6 |
--------------------------------------------------------------------------------
/examples/wifi/nl80211_interface_type.py:
--------------------------------------------------------------------------------
1 | import errno
2 | from pyroute2 import IW
3 | from pyroute2 import IPRoute
4 | from pyroute2.netlink.exceptions import NetlinkError
5 |
6 | # interface name to check
7 | ifname = 'lo'
8 |
9 | ip = IPRoute()
10 | iw = IW()
11 | index = ip.link_lookup(ifname=ifname)[0]
12 | try:
13 | iw.get_interface_by_ifindex(index)
14 | print("wireless interface")
15 | except NetlinkError as e:
16 | if e.code == errno.ENODEV: # 19 'No such device'
17 | print("not a wireless interface")
18 | finally:
19 | iw.close()
20 | ip.close()
21 |
--------------------------------------------------------------------------------
/examples/wifi/nl80211_interfaces.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # -*- coding: utf-8 -*-
3 | #
4 | from pyroute2.iwutil import IW
5 |
6 | iw = IW()
7 | for q in iw.get_interfaces_dump():
8 | phyname = 'phy%i' % int(q.get_attr('NL80211_ATTR_WIPHY'))
9 | print(
10 | '%s\t%s\t%s\t%s'
11 | % (
12 | q.get_attr('NL80211_ATTR_IFINDEX'),
13 | phyname,
14 | q.get_attr('NL80211_ATTR_IFNAME'),
15 | q.get_attr('NL80211_ATTR_MAC'),
16 | )
17 | )
18 | iw.close()
19 |
--------------------------------------------------------------------------------
/examples/wifi/nl80211_monitor.py:
--------------------------------------------------------------------------------
1 | from pyroute2 import IW
2 |
3 |
4 | # register IW to get all the messages
5 | iw = IW(groups=0xFFF)
6 | print(iw.get())
7 | iw.close()
8 |
--------------------------------------------------------------------------------
/examples/wifi/nl80211_set_type.py:
--------------------------------------------------------------------------------
1 | import errno
2 | from pyroute2 import IW
3 | from pyroute2 import IPRoute
4 | from pyroute2.netlink.exceptions import NetlinkError
5 | from pyroute2.netlink.nl80211 import IFTYPE_NAMES
6 |
7 | # interface name to check
8 | ifname = 'wlx2'
9 | iftype = 'monitor'
10 |
11 | iw = IW()
12 | ip = IPRoute()
13 | index = ip.link_lookup(ifname=ifname)[0]
14 | try:
15 | print(f"Original type: '{iw.get_interface_type(index)}'")
16 | iw.set_interface_type(index, iftype)
17 | print(f"New state: '{iw.get_interface_type(index)}'")
18 | except NetlinkError as e:
19 | print(f"Exception : {e}")
20 | finally:
21 | iw.close()
22 | ip.close()
23 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [build-system]
2 | requires = ["setuptools", "wheel"]
3 | build-backend = "setuptools.build_meta"
4 |
5 | [[tool.mypy.overrides]]
6 | module = ["pytest.*", "pytest_asyncio.*"]
7 | ignore_missing_imports = true
8 |
--------------------------------------------------------------------------------
/pyroute2/bsd/README:
--------------------------------------------------------------------------------
1 | BSD platform support
2 | ====================
3 |
4 | BSD systems have PF_ROUTE -- a protocol similar to Netlink, but
5 | with very limited functionality. Still it is possible to use it
6 | in almost the same way one uses Netlink. Almost.
7 |
8 | This module is in the very early development stage. Ye warned.
9 |
10 | Example::
11 |
12 | from pyroute2.bsd.rtmsocket import RTMSocket
13 |
14 | rs = RTMSocket()
15 | while True:
16 | print(rs.get())
17 |
--------------------------------------------------------------------------------
/pyroute2/bsd/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/pyroute2/bsd/__init__.py
--------------------------------------------------------------------------------
/pyroute2/bsd/rtmsocket/freebsd.py:
--------------------------------------------------------------------------------
1 | from pyroute2.bsd.pf_route import (
2 | if_announcemsg,
3 | if_msg,
4 | ifa_msg,
5 | ifma_msg,
6 | rt_msg,
7 | )
8 |
9 | RTM_ADD = 0x1 # Add Route
10 | RTM_DELETE = 0x2 # Delete Route
11 | RTM_CHANGE = 0x3 # Change Metrics or flags
12 | RTM_GET = 0x4 # Report Metrics
13 | RTM_LOSING = 0x5 # Kernel Suspects Partitioning
14 | RTM_REDIRECT = 0x6 # Told to use different route
15 | RTM_MISS = 0x7 # Lookup failed on this address
16 | RTM_LOCK = 0x8 # Fix specified metrics
17 | RTM_RESOLVE = 0xB # Req to resolve dst to LL addr
18 | RTM_NEWADDR = 0xC # Address being added to iface
19 | RTM_DELADDR = 0xD # Address being removed from iface
20 | RTM_IFINFO = 0xE # Iface going up/down etc
21 | RTM_NEWMADDR = 0xF # Mcast group membership being added to if
22 | RTM_DELMADDR = 0x10 # Mcast group membership being deleted
23 | RTM_IFANNOUNCE = 0x11 # Iface arrival/departure
24 | RTM_IEEE80211 = 0x12 # IEEE80211 wireless event
25 |
26 |
27 | class RTMSocketBase(object):
28 | msg_map = {
29 | RTM_ADD: rt_msg,
30 | RTM_DELETE: rt_msg,
31 | RTM_CHANGE: rt_msg,
32 | RTM_GET: rt_msg,
33 | RTM_LOSING: rt_msg,
34 | RTM_REDIRECT: rt_msg,
35 | RTM_MISS: rt_msg,
36 | RTM_LOCK: rt_msg,
37 | RTM_RESOLVE: rt_msg,
38 | RTM_NEWADDR: ifa_msg,
39 | RTM_DELADDR: ifa_msg,
40 | RTM_IFINFO: if_msg,
41 | RTM_NEWMADDR: ifma_msg,
42 | RTM_DELMADDR: ifma_msg,
43 | RTM_IFANNOUNCE: if_announcemsg,
44 | RTM_IEEE80211: if_announcemsg,
45 | }
46 |
--------------------------------------------------------------------------------
/pyroute2/bsd/rtmsocket/openbsd.py:
--------------------------------------------------------------------------------
1 | from pyroute2.bsd.pf_route import (
2 | bsdmsg,
3 | if_announcemsg,
4 | if_msg,
5 | ifa_msg,
6 | rt_msg,
7 | )
8 |
9 | RTM_ADD = 0x1 # Add Route
10 | RTM_DELETE = 0x2 # Delete Route
11 | RTM_CHANGE = 0x3 # Change Metrics or flags
12 | RTM_GET = 0x4 # Report Metrics
13 | RTM_LOSING = 0x5 # Kernel Suspects Partitioning
14 | RTM_REDIRECT = 0x6 # Told to use different route
15 | RTM_MISS = 0x7 # Lookup failed on this address
16 | RTM_LOCK = 0x8 # Fix specified metrics
17 | RTM_RESOLVE = 0xB # Req to resolve dst to LL addr
18 | RTM_NEWADDR = 0xC # Address being added to iface
19 | RTM_DELADDR = 0xD # Address being removed from iface
20 | RTM_IFINFO = 0xE # Iface going up/down etc
21 | RTM_IFANNOUNCE = 0xF # Iface arrival/departure
22 | RTM_DESYNC = 0x10 # route socket buffer overflow
23 | RTM_INVALIDATE = 0x10 # Invalidate cache of L2 route
24 | RTM_BFD = 0x12 # bidirectional forwarding detection
25 | RTM_PROPOSAL = 0x13 # proposal for netconfigd
26 |
27 |
28 | class RTMSocketBase(object):
29 | msg_map = {
30 | RTM_ADD: rt_msg,
31 | RTM_DELETE: rt_msg,
32 | RTM_CHANGE: rt_msg,
33 | RTM_GET: rt_msg,
34 | RTM_LOSING: rt_msg,
35 | RTM_REDIRECT: rt_msg,
36 | RTM_MISS: rt_msg,
37 | RTM_LOCK: rt_msg,
38 | RTM_RESOLVE: rt_msg,
39 | RTM_NEWADDR: ifa_msg,
40 | RTM_DELADDR: ifa_msg,
41 | RTM_IFINFO: if_msg,
42 | RTM_IFANNOUNCE: if_announcemsg,
43 | RTM_DESYNC: bsdmsg,
44 | RTM_INVALIDATE: bsdmsg,
45 | RTM_BFD: bsdmsg,
46 | RTM_PROPOSAL: bsdmsg,
47 | }
48 |
--------------------------------------------------------------------------------
/pyroute2/cli/auth/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/pyroute2/cli/auth/__init__.py
--------------------------------------------------------------------------------
/pyroute2/cli/auth/auth_keystone.py:
--------------------------------------------------------------------------------
1 | import os
2 | import time
3 |
4 | from dateutil.parser import parse as isodate
5 | from keystoneauth1 import session
6 | from keystoneauth1.identity import v3
7 | from keystoneclient.v3 import client as ksclient
8 | from keystoneclient.v3.tokens import TokenManager
9 |
10 |
11 | class OSAuthManager(object):
12 | def __init__(self, headers):
13 | # create a Keystone password object
14 | auth = v3.Password(
15 | auth_url=os.environ.get('OS_AUTH_URL'),
16 | username=os.environ.get('OS_USERNAME'),
17 | password=os.environ.get('OS_PASSWORD'),
18 | user_domain_name=(os.environ.get('OS_USER_DOMAIN_NAME')),
19 | project_id=os.environ.get('OS_PROJECT_ID'),
20 | )
21 | # create a session object
22 | sess = session.Session(auth=auth)
23 | # create a token manager
24 | tmanager = TokenManager(ksclient.Client(session=sess))
25 | # validate the token
26 | keystone_response = tmanager.validate(headers['X-Auth-Token'])
27 | # init attrs
28 | self.expire = isodate(keystone_response['expires_at']).timestamp()
29 |
30 | def check(self, obj, tag):
31 | if time.time() > self.expire:
32 | raise PermissionError('keystone token has been expired')
33 | return True
34 |
--------------------------------------------------------------------------------
/pyroute2/cli/auth/auth_radius.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | import pyrad.packet
4 | from pyrad.client import Client
5 | from pyrad.dictionary import Dictionary
6 |
7 |
8 | class RadiusAuthManager(object):
9 | def __init__(self, headers):
10 | user = headers['X-Auth-User']
11 | password = headers['X-Auth-Password']
12 |
13 | client = Client(
14 | server=os.environ.get('RADIUS_SERVER'),
15 | secret=os.environ.get('RADIUS_SECRET').encode('ascii'),
16 | dict=Dictionary('dictionary'),
17 | )
18 |
19 | req = client.CreateAuthPacket(
20 | code=pyrad.packet.AccessRequest, User_Name=user
21 | )
22 |
23 | req['User-Password'] = req.PwCrypt(password)
24 | reply = client.SendPacket(req)
25 | self.auth = reply.code
26 |
27 | def check(self, obj, tag):
28 | return self.auth == pyrad.packet.AccessAccept
29 |
--------------------------------------------------------------------------------
/pyroute2/compat.py:
--------------------------------------------------------------------------------
1 | '''Compatibility with older but supported Python versions'''
2 |
3 | try:
4 | from enum import StrEnum # noqa: F401
5 | except ImportError:
6 | from enum import Enum
7 |
8 | class StrEnum(str, Enum):
9 | '''Same as enum, but members are also strings.'''
10 |
11 |
12 | try:
13 | from socket import ETHERTYPE_IP
14 | except ImportError:
15 | # ETHERTYPE_* are new in python 3.12
16 | ETHERTYPE_IP = 0x800
17 |
18 |
19 | __all__ = ('StrEnum', 'ETHERTYPE_IP')
20 |
--------------------------------------------------------------------------------
/pyroute2/config/eventlet.py:
--------------------------------------------------------------------------------
1 | import logging
2 |
3 | from pyroute2.config.asyncio import asyncio_config
4 |
5 | log = logging.getLogger(__name__)
6 | log.warning("Please use pyroute2.config.asyncio.asyncio_config")
7 | log.warning("The eventlet module will be dropped soon ")
8 |
9 | eventlet_config = asyncio_config
10 |
--------------------------------------------------------------------------------
/pyroute2/config/log.py:
--------------------------------------------------------------------------------
1 | import logging
2 |
3 | ##
4 | # Create the main logger
5 | #
6 | # Do NOT touch the root logger -- not to break basicConfig() etc
7 | #
8 | log = logging.getLogger('pyroute2')
9 | log.setLevel(0)
10 | log.addHandler(logging.NullHandler())
11 |
12 |
13 | def debug(*argv, **kwarg):
14 | return log.debug(*argv, **kwarg)
15 |
16 |
17 | def info(*argv, **kwarg):
18 | return log.info(*argv, **kwarg)
19 |
20 |
21 | def warning(*argv, **kwarg):
22 | return log.warning(*argv, **kwarg)
23 |
24 |
25 | def error(*argv, **kwarg):
26 | return log.error(*argv, **kwarg)
27 |
28 |
29 | def critical(*argv, **kwarg):
30 | return log.critical(*argv, **kwarg)
31 |
--------------------------------------------------------------------------------
/pyroute2/decoder/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/pyroute2/decoder/__init__.py
--------------------------------------------------------------------------------
/pyroute2/decoder/args.py:
--------------------------------------------------------------------------------
1 | import argparse
2 |
3 |
4 | def parse_args():
5 | argument_parser = argparse.ArgumentParser()
6 | argument_parser.add_argument(
7 | '-c', '--cls', help='message class to use for decoding the data'
8 | )
9 | argument_parser.add_argument('-d', '--data', help='data dump file')
10 | argument_parser.add_argument(
11 | '-f', '--format', default='hex', help='data file format: hex, pcap'
12 | )
13 | argument_parser.add_argument(
14 | '-m', '--match', help='match protocol family (only for pcap data)'
15 | )
16 | argument_parser.add_argument(
17 | '-o',
18 | '--offset',
19 | help='message offset in the data',
20 | default=0,
21 | type=int,
22 | )
23 | argument_parser.add_argument(
24 | '-k', '--key', help='key format (see struct)', default='H'
25 | )
26 | return argument_parser.parse_args()
27 |
--------------------------------------------------------------------------------
/pyroute2/dhcp/enums/__init__.py:
--------------------------------------------------------------------------------
1 | from . import bootp, dhcp # noqa: F401
2 |
--------------------------------------------------------------------------------
/pyroute2/dhcp/enums/bootp.py:
--------------------------------------------------------------------------------
1 | from enum import IntEnum, IntFlag
2 |
3 |
4 | class MessageType(IntEnum):
5 | BOOTREQUEST = 1 # Client to server
6 | BOOTREPLY = 2 # Server to client
7 |
8 |
9 | class HardwareType(IntEnum):
10 | ETHERNET = 1 # Ethernet (10Mb)
11 | EXPERIMENTAL_ETHERNET = 2
12 | AMATEUR_RADIO = 3
13 | TOKEN_RING = 4
14 | FDDI = 8
15 | ATM = 19
16 | WIRELESS_IEEE_802_11 = 20
17 |
18 |
19 | class Flag(IntFlag):
20 | UNICAST = 0x0000 # Unicast response requested
21 | BROADCAST = 0x8000 # Broadcast response requested
22 |
--------------------------------------------------------------------------------
/pyroute2/ethtool/__init__.py:
--------------------------------------------------------------------------------
1 | from .ethtool import Ethtool
2 |
3 | __all__ = [Ethtool]
4 |
--------------------------------------------------------------------------------
/pyroute2/ext/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/pyroute2/ext/__init__.py
--------------------------------------------------------------------------------
/pyroute2/ext/icmp.py:
--------------------------------------------------------------------------------
1 | from pyroute2.protocols import msg
2 |
3 |
4 | class icmpmsg(msg):
5 | fields = [('type', 'uint8'), ('code', 'uint8'), ('csum', 'be32')]
6 |
7 |
8 | class icmp_router_adv(icmpmsg):
9 | fields = icmpmsg.fields + [
10 | ('addrs_num', 'uint8'),
11 | ('alen', 'uint8'),
12 | ('lifetime', 'be32'),
13 | ('addrs', 'routers'),
14 | ]
15 |
--------------------------------------------------------------------------------
/pyroute2/fixtures/doctest.py:
--------------------------------------------------------------------------------
1 | '''
2 | This module only prepares the environment for doctests
3 | in `pyroute2.fixtures`.
4 | '''
5 |
6 | from unittest.mock import MagicMock
7 |
8 | from pyroute2 import config
9 | from pyroute2.iproute.linux import AsyncIPRoute, IPRoute
10 | from pyroute2.netlink.rtnl.ifinfmsg import ifinfmsg
11 |
12 | # config setup
13 | config.mock_netlink = True
14 | config.mock_netns = True
15 |
16 | # mock modules
17 | subprocess = MagicMock()
18 | pytest = MagicMock()
19 |
20 | # mock fixtures
21 | nsname = MagicMock()
22 | test_link_ifinfmsg = ifinfmsg()
23 | async_ipr = AsyncIPRoute()
24 | sync_ipr = IPRoute()
25 |
--------------------------------------------------------------------------------
/pyroute2/fixtures/plan9.py:
--------------------------------------------------------------------------------
1 | import time
2 | from collections.abc import AsyncGenerator
3 | from socket import socketpair
4 |
5 | import pytest_asyncio
6 |
7 | from pyroute2.plan9.client import Plan9ClientSocket
8 | from pyroute2.plan9.server import Plan9ServerSocket
9 |
10 |
11 | def test_time():
12 | return time.time_ns()
13 |
14 |
15 | class AsyncPlan9Context:
16 |
17 | server = None
18 | client = None
19 | shutdown_response = None
20 | sample_data = b'Pi6raTaXuzohdu7n'
21 |
22 | def __init__(self):
23 | self.server_sock, self.client_sock = socketpair()
24 | self.server = Plan9ServerSocket(use_socket=self.server_sock)
25 | self.client = Plan9ClientSocket(use_socket=self.client_sock)
26 | self._task = None
27 | with self.server.filesystem.create('test_file') as i:
28 | i.data.write(self.sample_data)
29 | with self.server.filesystem.create('test_time') as i:
30 | i.metadata.call_on_read = True
31 | i.register_function(test_time, loader=lambda x: {})
32 |
33 | async def ensure_session(self):
34 | self._task = await self.server.async_run()
35 | await self.client.start_session()
36 |
37 | def close(self):
38 | self._task.cancel()
39 | self.client.close()
40 | self.server.close()
41 |
42 |
43 | @pytest_asyncio.fixture
44 | async def async_p9_context() -> AsyncGenerator[AsyncPlan9Context]:
45 | ctx = AsyncPlan9Context()
46 | await ctx.ensure_session()
47 | yield ctx
48 | ctx.close()
49 |
--------------------------------------------------------------------------------
/pyroute2/inotify/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/pyroute2/inotify/__init__.py
--------------------------------------------------------------------------------
/pyroute2/inotify/inotify_msg.py:
--------------------------------------------------------------------------------
1 | import struct
2 |
3 | from pyroute2.netlink import nlmsg_base, nlmsg_decoder_generic
4 |
5 |
6 | class inotify_msg(nlmsg_base, nlmsg_decoder_generic):
7 | fields = (
8 | ('wd', 'i'),
9 | ('mask', 'I'),
10 | ('cookie', 'I'),
11 | ('name_length', 'I'),
12 | )
13 |
14 | def decode(self):
15 | super(inotify_msg, self).decode()
16 | (name,) = struct.unpack_from(
17 | '%is' % self['name_length'], self.data, self.offset + 16
18 | )
19 | self['name'] = name.decode('utf-8').strip('\0')
20 | self.length = self['name_length'] + 16
21 |
--------------------------------------------------------------------------------
/pyroute2/iproute/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import sys
3 |
4 | from pyroute2 import config
5 | from pyroute2.iproute.linux import RTNL_API, IPBatch
6 |
7 | # compatibility fix -- LNST:
8 | from pyroute2.netlink.rtnl import (
9 | RTM_DELADDR,
10 | RTM_DELLINK,
11 | RTM_GETADDR,
12 | RTM_GETLINK,
13 | RTM_NEWADDR,
14 | RTM_NEWLINK,
15 | )
16 |
17 | AsyncIPRoute = None
18 | if sys.platform.startswith('win'):
19 | from pyroute2.iproute.windows import (
20 | ChaoticIPRoute,
21 | IPRoute,
22 | NetNS,
23 | RawIPRoute,
24 | )
25 | elif sys.platform.startswith('darwin'):
26 | from pyroute2.iproute.darwin import (
27 | ChaoticIPRoute,
28 | IPRoute,
29 | NetNS,
30 | RawIPRoute,
31 | )
32 | elif config.uname[0][-3:] == 'BSD':
33 | from pyroute2.iproute.bsd import ChaoticIPRoute, IPRoute, NetNS, RawIPRoute
34 | else:
35 | from pyroute2.iproute.linux import (
36 | AsyncIPRoute,
37 | ChaoticIPRoute,
38 | IPRoute,
39 | NetNS,
40 | RawIPRoute,
41 | )
42 |
43 | classes = [
44 | AsyncIPRoute,
45 | RTNL_API,
46 | IPBatch,
47 | IPRoute,
48 | RawIPRoute,
49 | ChaoticIPRoute,
50 | NetNS,
51 | ]
52 |
53 | constants = [
54 | RTM_GETLINK,
55 | RTM_NEWLINK,
56 | RTM_DELLINK,
57 | RTM_GETADDR,
58 | RTM_NEWADDR,
59 | RTM_DELADDR,
60 | ]
61 |
--------------------------------------------------------------------------------
/pyroute2/ndb/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/pyroute2/ndb/__init__.py
--------------------------------------------------------------------------------
/pyroute2/ndb/cluster.py:
--------------------------------------------------------------------------------
1 | import json
2 | import socket
3 |
4 | from pyroute2.common import basestring
5 |
6 | from .main import NDB
7 | from .transport import Messenger, Transport
8 |
9 |
10 | def init(config):
11 | if isinstance(config, basestring):
12 | config = json.loads(config)
13 | else:
14 | config = json.load(config)
15 | hostname = config['local'].get('hostname', socket.gethostname())
16 | messenger = Messenger(
17 | config['local']['id'],
18 | Transport(config['local']['address'], config['local']['port']),
19 | )
20 |
21 | for target in config['local'].get('targets', []):
22 | messenger.targets.add(target)
23 |
24 | if not messenger.targets:
25 | messenger.targets.add(hostname)
26 |
27 | for peer in config.get('peers', []):
28 | messenger.add_peer(*peer)
29 |
30 | sources = config['local'].get('sources')
31 | if sources is None:
32 | sources = [{'target': hostname, 'kind': 'local'}]
33 |
34 | return NDB(
35 | log=config.get('log', 'debug'),
36 | sources=sources,
37 | localhost=sources[0]['target'],
38 | messenger=messenger,
39 | )
40 |
--------------------------------------------------------------------------------
/pyroute2/ndb/messages.py:
--------------------------------------------------------------------------------
1 | class cmsg(dict):
2 | def __init__(self, target, payload=None):
3 | self['header'] = {'target': target}
4 | self.payload = payload
5 |
6 |
7 | class cmsg_event(cmsg):
8 | pass
9 |
10 |
11 | class cmsg_failed(cmsg):
12 | pass
13 |
14 |
15 | class cmsg_sstart(cmsg):
16 | pass
17 |
--------------------------------------------------------------------------------
/pyroute2/netlink/connector/__init__.py:
--------------------------------------------------------------------------------
1 | from pyroute2.netlink import NETLINK_CONNECTOR, nlmsg
2 | from pyroute2.netlink.nlsocket import NetlinkSocket
3 |
4 |
5 | class cn_msg(nlmsg):
6 | fields = (
7 | ('idx', 'I'),
8 | ('val', 'I'),
9 | ('seq', 'I'),
10 | ('ack', 'I'),
11 | ('len', 'H'),
12 | ('flags', 'H'),
13 | )
14 |
15 |
16 | class ConnectorSocket(NetlinkSocket):
17 | def __init__(self, fileno=None):
18 | super().__init__(NETLINK_CONNECTOR)
19 |
--------------------------------------------------------------------------------
/pyroute2/netlink/coredata.py:
--------------------------------------------------------------------------------
1 | import os
2 | from dataclasses import asdict, dataclass
3 | from typing import Optional, Type, Union
4 |
5 | from pyroute2 import config
6 | from pyroute2.requests.main import RequestFilter, RequestProcessor
7 |
8 |
9 | @dataclass
10 | class CoreConfig:
11 | target: str = 'localhost'
12 | flags: int = os.O_CREAT
13 | groups: int = 0
14 | rcvsize: int = 16384
15 | netns: Optional[str] = None
16 | tag_field: str = ''
17 | address: Optional[tuple[str, int]] = None
18 | telemetry: Optional[tuple[str, int]] = None
19 | use_socket: bool = False
20 | use_event_loop: bool = False
21 | use_libc: bool = False
22 |
23 |
24 | class CoreSocketSpec:
25 | defaults: dict[str, Union[bool, int, str, None, tuple[str, ...]]] = {
26 | 'closed': False,
27 | 'compiled': None,
28 | 'uname': config.uname,
29 | }
30 | status_filters: list[Type[RequestFilter]] = []
31 |
32 | def __init__(self, config: CoreConfig):
33 | self.config = config
34 | self.status = RequestProcessor()
35 | for flt in self.status_filters:
36 | self.status.add_filter(flt())
37 | self.status.update(self.defaults)
38 | self.status.update(asdict(self.config))
39 |
40 | def __setitem__(self, key, value):
41 | setattr(self.config, key, value)
42 | self.status.update(asdict(self.config))
43 |
44 | def __getitem__(self, key):
45 | return getattr(self.config, key)
46 |
47 | def serializable(self):
48 | return not any(
49 | (
50 | self.config.use_socket,
51 | self.config.use_event_loop,
52 | self.config.use_libc,
53 | )
54 | )
55 |
--------------------------------------------------------------------------------
/pyroute2/netlink/event/__init__.py:
--------------------------------------------------------------------------------
1 | from pyroute2.config import kernel
2 | from pyroute2.netlink.generic import GenericNetlinkSocket
3 |
4 |
5 | class EventSocket(GenericNetlinkSocket):
6 | marshal_class = None
7 | genl_family = None
8 |
9 | def __init__(self, *args, **kwargs):
10 | GenericNetlinkSocket.__init__(self, *args, **kwargs)
11 | self.set_marshal(self.marshal_class())
12 | if kernel[0] <= 2:
13 | self.bind(groups=0xFFFFFF)
14 | else:
15 | self.bind()
16 | for group in self.mcast_groups:
17 | self.add_membership(group)
18 |
19 | def bind(self, groups=0, **kwarg):
20 | GenericNetlinkSocket.bind(
21 | self,
22 | self.genl_family,
23 | self.marshal_class.msg_map[0],
24 | groups,
25 | None,
26 | **kwarg
27 | )
28 |
--------------------------------------------------------------------------------
/pyroute2/netlink/exceptions.py:
--------------------------------------------------------------------------------
1 | import os
2 | import time
3 |
4 |
5 | class NetlinkError(Exception):
6 | '''
7 | Base netlink error
8 | '''
9 |
10 | def __init__(self, code, msg=None):
11 | msg = msg or os.strerror(code)
12 | super(NetlinkError, self).__init__(code, msg)
13 | self.code = code
14 | self.extra_code = 0
15 |
16 |
17 | class NetlinkDecodeError(Exception):
18 | '''
19 | Base decoding error class.
20 |
21 | Incapsulates underlying error for the following analysis
22 | '''
23 |
24 | def __init__(self, exception):
25 | self.exception = exception
26 |
27 |
28 | class NetlinkHeaderDecodeError(NetlinkDecodeError):
29 | '''
30 | The error occured while decoding a header
31 | '''
32 |
33 | pass
34 |
35 |
36 | class NetlinkDataDecodeError(NetlinkDecodeError):
37 | '''
38 | The error occured while decoding the message fields
39 | '''
40 |
41 | pass
42 |
43 |
44 | class NetlinkNLADecodeError(NetlinkDecodeError):
45 | '''
46 | The error occured while decoding NLA chain
47 | '''
48 |
49 | pass
50 |
51 |
52 | class IPSetError(NetlinkError):
53 | '''
54 | Netlink error with IPSet special error codes.
55 |
56 | Messages are imported from errcode.c
57 | '''
58 |
59 | pass
60 |
61 |
62 | class NetlinkDumpInterrupted(NetlinkError):
63 | '''
64 | Raised when NLM_F_DUMP_INTR is set in the flags.
65 | '''
66 |
67 | def __init__(self, code=-1, msg='dump interrupted'):
68 | super(NetlinkDumpInterrupted, self).__init__(code, msg)
69 |
70 |
71 | class SkipInode(Exception):
72 | def __init__(self, code=0, msg=None):
73 | super(SkipInode, self).__init__(code, msg)
74 | self.code = code
75 |
76 |
77 | class ChaoticException(Exception):
78 | def __init__(self):
79 | chaotic_id = str(time.time())
80 | super(ChaoticException, self).__init__(chaotic_id)
81 | self.chaotic_id = chaotic_id
82 |
--------------------------------------------------------------------------------
/pyroute2/netlink/nfnetlink/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | Nfnetlink
3 | =========
4 |
5 | The support of nfnetlink families is now at the
6 | very beginning. So there is no public exports
7 | yet, but you can review the code. Work is in
8 | progress, stay tuned.
9 |
10 | nf-queue
11 | ++++++++
12 |
13 | Netfilter protocol for NFQUEUE iptables target.
14 | '''
15 |
16 | from pyroute2.netlink import nlmsg
17 |
18 | NFNL_SUBSYS_NONE = 0
19 | NFNL_SUBSYS_CTNETLINK = 1
20 | NFNL_SUBSYS_CTNETLINK_EXP = 2
21 | NFNL_SUBSYS_QUEUE = 3
22 | NFNL_SUBSYS_ULOG = 4
23 | NFNL_SUBSYS_OSF = 5
24 | NFNL_SUBSYS_IPSET = 6
25 | NFNL_SUBSYS_ACCT = 7
26 | NFNL_SUBSYS_CTNETLINK_TIMEOUT = 8
27 | NFNL_SUBSYS_CTHELPER = 9
28 | NFNL_SUBSYS_NFTABLES = 10
29 | NFNL_SUBSYS_NFT_COMPAT = 11
30 | NFNL_SUBSYS_COUNT = 12
31 |
32 | # multicast group ids (for use with {add,drop}_membership)
33 | NFNLGRP_NONE = 0
34 | NFNLGRP_CONNTRACK_NEW = 1
35 | NFNLGRP_CONNTRACK_UPDATE = 2
36 | NFNLGRP_CONNTRACK_DESTROY = 3
37 | NFNLGRP_CONNTRACK_EXP_NEW = 4
38 | NFNLGRP_CONNTRACK_EXP_UPDATE = 5
39 | NFNLGRP_CONNTRACK_EXP_DESTROY = 6
40 | NFNLGRP_NFTABLES = 7
41 | NFNLGRP_ACCT_QUOTA = 8
42 | NFNLGRP_NFTRACE = 9
43 |
44 |
45 | class nfgen_msg(nlmsg):
46 | fields = (('nfgen_family', 'B'), ('version', 'B'), ('res_id', '!H'))
47 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/errmsg.py:
--------------------------------------------------------------------------------
1 | from pyroute2.netlink import nlmsg
2 |
3 |
4 | class errmsg(nlmsg):
5 | '''
6 | Custom message type
7 |
8 | Error ersatz-message
9 | '''
10 |
11 | fields = (('code', 'i'),)
12 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/ifinfmsg/plugins/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/pyroute2/netlink/rtnl/ifinfmsg/plugins/__init__.py
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/ifinfmsg/plugins/bond.py:
--------------------------------------------------------------------------------
1 | from pyroute2.netlink import nla
2 |
3 |
4 | class bond(nla):
5 | prefix = 'IFLA_'
6 | nla_map = (
7 | ('IFLA_BOND_UNSPEC', 'none'),
8 | ('IFLA_BOND_MODE', 'uint8'),
9 | ('IFLA_BOND_ACTIVE_SLAVE', 'uint32'),
10 | ('IFLA_BOND_MIIMON', 'uint32'),
11 | ('IFLA_BOND_UPDELAY', 'uint32'),
12 | ('IFLA_BOND_DOWNDELAY', 'uint32'),
13 | ('IFLA_BOND_USE_CARRIER', 'uint8'),
14 | ('IFLA_BOND_ARP_INTERVAL', 'uint32'),
15 | ('IFLA_BOND_ARP_IP_TARGET', '*ipaddr'),
16 | ('IFLA_BOND_ARP_VALIDATE', 'uint32'),
17 | ('IFLA_BOND_ARP_ALL_TARGETS', 'uint32'),
18 | ('IFLA_BOND_PRIMARY', 'uint32'),
19 | ('IFLA_BOND_PRIMARY_RESELECT', 'uint8'),
20 | ('IFLA_BOND_FAIL_OVER_MAC', 'uint8'),
21 | ('IFLA_BOND_XMIT_HASH_POLICY', 'uint8'),
22 | ('IFLA_BOND_RESEND_IGMP', 'uint32'),
23 | ('IFLA_BOND_NUM_PEER_NOTIF', 'uint8'),
24 | ('IFLA_BOND_ALL_SLAVES_ACTIVE', 'uint8'),
25 | ('IFLA_BOND_MIN_LINKS', 'uint32'),
26 | ('IFLA_BOND_LP_INTERVAL', 'uint32'),
27 | ('IFLA_BOND_PACKETS_PER_SLAVE', 'uint32'),
28 | ('IFLA_BOND_AD_LACP_RATE', 'uint8'),
29 | ('IFLA_BOND_AD_SELECT', 'uint8'),
30 | ('IFLA_BOND_AD_INFO', 'ad_info'),
31 | ('IFLA_BOND_AD_ACTOR_SYS_PRIO', 'uint16'),
32 | ('IFLA_BOND_AD_USER_PORT_KEY', 'uint16'),
33 | ('IFLA_BOND_AD_ACTOR_SYSTEM', 'hex'),
34 | ('IFLA_BOND_TLB_DYNAMIC_LB', 'uint8'),
35 | )
36 |
37 | class ad_info(nla):
38 | nla_map = (
39 | ('IFLA_BOND_AD_INFO_UNSPEC', 'none'),
40 | ('IFLA_BOND_AD_INFO_AGGREGATOR', 'uint16'),
41 | ('IFLA_BOND_AD_INFO_NUM_PORTS', 'uint16'),
42 | ('IFLA_BOND_AD_INFO_ACTOR_KEY', 'uint16'),
43 | ('IFLA_BOND_AD_INFO_PARTNER_KEY', 'uint16'),
44 | ('IFLA_BOND_AD_INFO_PARTNER_MAC', 'l2addr'),
45 | )
46 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/ifinfmsg/plugins/geneve.py:
--------------------------------------------------------------------------------
1 | from pyroute2.netlink import nla, nlmsg_atoms
2 |
3 |
4 | class geneve(nla):
5 | nla_map = (
6 | ('IFLA_GENEVE_UNSPEC', 'none'),
7 | ('IFLA_GENEVE_ID', 'uint32'),
8 | ('IFLA_GENEVE_REMOTE', 'ip4addr'),
9 | ('IFLA_GENEVE_TTL', 'uint8'),
10 | ('IFLA_GENEVE_TOS', 'uint8'),
11 | ('IFLA_GENEVE_PORT', 'be16'),
12 | ('IFLA_GENEVE_COLLECT_METADATA', 'flag'),
13 | ('IFLA_GENEVE_REMOTE6', 'ip6addr'),
14 | ('IFLA_GENEVE_UDP_CSUM', 'uint8'),
15 | ('IFLA_GENEVE_UDP_ZERO_CSUM6_TX', 'uint8'),
16 | ('IFLA_GENEVE_UDP_ZERO_CSUM6_RX', 'uint8'),
17 | ('IFLA_GENEVE_LABEL', 'be32'),
18 | ('IFLA_GENEVE_TTL_INHERIT', 'uint8'),
19 | ('IFLA_GENEVE_DF', 'df'),
20 | )
21 |
22 | class df(nlmsg_atoms.uint16):
23 | value_map = {0: 'unset', 1: 'set', 2: 'inherit'}
24 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/ifinfmsg/plugins/gtp.py:
--------------------------------------------------------------------------------
1 | from pyroute2.netlink import nla
2 |
3 |
4 | class gtp(nla):
5 | nla_map = (
6 | ('IFLA_GTP_UNSPEC', 'none'),
7 | ('IFLA_GTP_FD0', 'uint32'),
8 | ('IFLA_GTP_FD1', 'uint32'),
9 | ('IFLA_GTP_PDP_HASHSIZE', 'uint32'),
10 | )
11 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/ifinfmsg/plugins/ipoib.py:
--------------------------------------------------------------------------------
1 | from pyroute2.netlink import nla, nlmsg_atoms
2 |
3 |
4 | class ipoib(nla):
5 | prefix = 'IFLA_IPOIB_'
6 |
7 | nla_map = (
8 | ('IFLA_IPOIB_UNSPEC', 'none'),
9 | ('IFLA_IPOIB_PKEY', 'uint16'),
10 | ('IFLA_IPOIB_MODE', 'mode'),
11 | ('IFLA_IPOIB_UMCAST', 'uint16'),
12 | )
13 |
14 | class mode(nlmsg_atoms.uint16):
15 | value_map = {0: 'datagram', 1: 'connected'}
16 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/ifinfmsg/plugins/ipvlan.py:
--------------------------------------------------------------------------------
1 | from pyroute2.netlink import nla
2 |
3 |
4 | class ipvlan(nla):
5 | prefix = 'IFLA_'
6 | nla_map = (('IFLA_IPVLAN_UNSPEC', 'none'), ('IFLA_IPVLAN_MODE', 'uint16'))
7 |
8 | modes = {
9 | 0: 'IPVLAN_MODE_L2',
10 | 1: 'IPVLAN_MODE_L3',
11 | 'IPVLAN_MODE_L2': 0,
12 | 'IPVLAN_MODE_L3': 1,
13 | }
14 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/ifinfmsg/plugins/team.py:
--------------------------------------------------------------------------------
1 | from pyroute2.netlink import nla
2 |
3 |
4 | class team(nla):
5 | prefix = 'IFLA_'
6 |
7 | nla_map = (('IFLA_TEAM_UNSPEC', 'none'), ('IFLA_TEAM_CONFIG', 'asciiz'))
8 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/ifinfmsg/plugins/tun.py:
--------------------------------------------------------------------------------
1 | from pyroute2.netlink import nla
2 |
3 |
4 | class tun(nla):
5 | prefix = 'IFLA_'
6 | nla_map = (
7 | ('IFLA_TUN_UNSPEC', 'none'),
8 | ('IFLA_TUN_OWNER', 'uint32'),
9 | ('IFLA_TUN_GROUP', 'uint32'),
10 | ('IFLA_TUN_TYPE', 'uint8'),
11 | ('IFLA_TUN_PI', 'uint8'),
12 | ('IFLA_TUN_VNET_HDR', 'uint8'),
13 | ('IFLA_TUN_PERSIST', 'uint8'),
14 | ('IFLA_TUN_MULTI_QUEUE', 'uint8'),
15 | ('IFLA_TUN_NUM_QUEUES', 'uint32'),
16 | ('IFLA_TUN_NUM_DISABLED_QUEUES', 'uint32'),
17 | )
18 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/ifinfmsg/plugins/tuntap.py:
--------------------------------------------------------------------------------
1 | from pyroute2.netlink import nla
2 |
3 |
4 | class tuntap(nla):
5 | '''
6 | Fake data type
7 | '''
8 |
9 | prefix = 'IFTUN_'
10 | nla_map = (
11 | ('IFTUN_UNSPEC', 'none'),
12 | ('IFTUN_MODE', 'asciiz'),
13 | ('IFTUN_UID', 'uint32'),
14 | ('IFTUN_GID', 'uint32'),
15 | ('IFTUN_IFR', 'flags'),
16 | )
17 |
18 | class flags(nla):
19 | fields = (
20 | ('no_pi', 'B'),
21 | ('one_queue', 'B'),
22 | ('vnet_hdr', 'B'),
23 | ('tun_excl', 'B'),
24 | ('multi_queue', 'B'),
25 | ('persist', 'B'),
26 | ('nofilter', 'B'),
27 | )
28 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/ifinfmsg/plugins/vlan.py:
--------------------------------------------------------------------------------
1 | from pyroute2.netlink import nla
2 |
3 | flags = {'reorder_hdr': 0x1, 'gvrp': 0x2, 'loose_binding': 0x4, 'mvrp': 0x8}
4 |
5 |
6 | class vlan(nla):
7 | prefix = 'IFLA_'
8 |
9 | nla_map = (
10 | ('IFLA_VLAN_UNSPEC', 'none'),
11 | ('IFLA_VLAN_ID', 'uint16'),
12 | ('IFLA_VLAN_FLAGS', 'vlan_flags'),
13 | ('IFLA_VLAN_EGRESS_QOS', 'qos'),
14 | ('IFLA_VLAN_INGRESS_QOS', 'qos'),
15 | ('IFLA_VLAN_PROTOCOL', 'be16'),
16 | )
17 |
18 | class vlan_flags(nla):
19 | fields = (('flags', 'I'), ('mask', 'I'))
20 |
21 | class qos(nla):
22 | prefix = 'IFLA_'
23 |
24 | nla_map = (
25 | ('IFLA_VLAN_QOS_UNSPEC', 'none'),
26 | ('IFLA_VLAN_QOS_MAPPING', 'qos_mapping'),
27 | )
28 |
29 | class qos_mapping(nla):
30 | fields = (('from', 'I'), ('to', 'I'))
31 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/ifinfmsg/plugins/vrf.py:
--------------------------------------------------------------------------------
1 | from pyroute2.netlink import nla
2 |
3 |
4 | class vrf(nla):
5 | prefix = 'IFLA_'
6 | nla_map = (('IFLA_VRF_UNSPEC', 'none'), ('IFLA_VRF_TABLE', 'uint32'))
7 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/ifinfmsg/plugins/vti.py:
--------------------------------------------------------------------------------
1 | from pyroute2.netlink import nla
2 |
3 |
4 | class vti(nla):
5 | prefix = 'IFLA_'
6 | nla_map = (
7 | ('IFLA_VTI_UNSPEC', 'none'),
8 | ('IFLA_VTI_LINK', 'uint32'),
9 | ('IFLA_VTI_IKEY', 'be32'),
10 | ('IFLA_VTI_OKEY', 'be32'),
11 | ('IFLA_VTI_LOCAL', 'ip4addr'),
12 | ('IFLA_VTI_REMOTE', 'ip4addr'),
13 | )
14 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/ifinfmsg/plugins/vti6.py:
--------------------------------------------------------------------------------
1 | from pyroute2.netlink import nla
2 |
3 |
4 | class vti6(nla):
5 | prefix = 'IFLA_'
6 | nla_map = (
7 | ('IFLA_VTI_UNSPEC', 'none'),
8 | ('IFLA_VTI_LINK', 'uint32'),
9 | ('IFLA_VTI_IKEY', 'be32'),
10 | ('IFLA_VTI_OKEY', 'be32'),
11 | ('IFLA_VTI_LOCAL', 'ip6addr'),
12 | ('IFLA_VTI_REMOTE', 'ip6addr'),
13 | ('IFLA_VTI_FWMARK', 'uint32'),
14 | )
15 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/ifinfmsg/plugins/vxlan.py:
--------------------------------------------------------------------------------
1 | from pyroute2.netlink import nla
2 |
3 |
4 | class vxlan(nla):
5 | prefix = 'IFLA_'
6 | nla_map = (
7 | ('IFLA_VXLAN_UNSPEC', 'none'),
8 | ('IFLA_VXLAN_ID', 'uint32'),
9 | ('IFLA_VXLAN_GROUP', 'ip4addr'),
10 | ('IFLA_VXLAN_LINK', 'uint32'),
11 | ('IFLA_VXLAN_LOCAL', 'ip4addr'),
12 | ('IFLA_VXLAN_TTL', 'uint8'),
13 | ('IFLA_VXLAN_TOS', 'uint8'),
14 | ('IFLA_VXLAN_LEARNING', 'uint8'),
15 | ('IFLA_VXLAN_AGEING', 'uint32'),
16 | ('IFLA_VXLAN_LIMIT', 'uint32'),
17 | ('IFLA_VXLAN_PORT_RANGE', 'port_range'),
18 | ('IFLA_VXLAN_PROXY', 'uint8'),
19 | ('IFLA_VXLAN_RSC', 'uint8'),
20 | ('IFLA_VXLAN_L2MISS', 'uint8'),
21 | ('IFLA_VXLAN_L3MISS', 'uint8'),
22 | ('IFLA_VXLAN_PORT', 'be16'),
23 | ('IFLA_VXLAN_GROUP6', 'ip6addr'),
24 | ('IFLA_VXLAN_LOCAL6', 'ip6addr'),
25 | ('IFLA_VXLAN_UDP_CSUM', 'uint8'),
26 | ('IFLA_VXLAN_UDP_ZERO_CSUM6_TX', 'uint8'),
27 | ('IFLA_VXLAN_UDP_ZERO_CSUM6_RX', 'uint8'),
28 | ('IFLA_VXLAN_REMCSUM_TX', 'uint8'),
29 | ('IFLA_VXLAN_REMCSUM_RX', 'uint8'),
30 | ('IFLA_VXLAN_GBP', 'flag'),
31 | ('IFLA_VXLAN_REMCSUM_NOPARTIAL', 'flag'),
32 | ('IFLA_VXLAN_COLLECT_METADATA', 'uint8'),
33 | ('IFLA_VXLAN_LABEL', 'uint32'),
34 | ('IFLA_VXLAN_GPE', 'flag'),
35 | ('IFLA_VXLAN_TTL_INHERIT', 'flag'),
36 | ('IFLA_VXLAN_DF', 'uint8'),
37 | )
38 |
39 | class port_range(nla):
40 | fields = (('low', '>H'), ('high', '>H'))
41 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/ifinfmsg/plugins/xfrm.py:
--------------------------------------------------------------------------------
1 | from pyroute2.netlink import nla
2 |
3 |
4 | class xfrm(nla):
5 | nla_map = (
6 | ('IFLA_XFRM_UNSPEC', 'none'),
7 | ('IFLA_XFRM_LINK', 'uint32'),
8 | ('IFLA_XFRM_IF_ID', 'uint32'),
9 | )
10 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/nsidmsg.py:
--------------------------------------------------------------------------------
1 | from pyroute2.netlink.rtnl.rtgenmsg import rtgenmsg
2 |
3 |
4 | class nsidmsg(rtgenmsg):
5 | nla_map = (
6 | ('NETNSA_NONE', 'none'),
7 | ('NETNSA_NSID', 'uint32'),
8 | ('NETNSA_PID', 'uint32'),
9 | ('NETNSA_FD', 'uint32'),
10 | ('NETNSA_TARGET_NSID', 'uint32'),
11 | ('NETNSA_CURRENT_NSID', 'uint32'),
12 | )
13 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/nsinfmsg.py:
--------------------------------------------------------------------------------
1 | from pyroute2.netlink import nlmsg, nlmsg_atoms
2 |
3 |
4 | class nsinfmsg(nlmsg):
5 | '''
6 | Fake message type to represent network namespace information.
7 |
8 | This is a prototype, the NLA layout is subject to change without
9 | notification.
10 | '''
11 |
12 | __slots__ = ()
13 | prefix = 'NSINFO_'
14 |
15 | fields = (('inode', 'I'), ('netnsid', 'I'))
16 |
17 | nla_map = (
18 | ('NSINFO_UNSPEC', 'none'),
19 | ('NSINFO_PATH', 'string'),
20 | ('NSINFO_PEER', 'peer'),
21 | )
22 |
23 | class peer(nlmsg_atoms.string):
24 | sql_type = None
25 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/p2pmsg.py:
--------------------------------------------------------------------------------
1 | from pyroute2.netlink import nlmsg
2 |
3 |
4 | class p2pmsg(nlmsg):
5 | '''
6 | Fake message type to represent peer to peer connections,
7 | be it GRE or PPP
8 | '''
9 |
10 | __slots__ = ()
11 | prefix = 'P2P_'
12 |
13 | fields = (('index', 'I'), ('family', 'I'))
14 |
15 | nla_map = (
16 | ('P2P_UNSPEC', 'none'),
17 | ('P2P_LOCAL', 'target'),
18 | ('P2P_REMOTE', 'target'),
19 | )
20 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/rtgenmsg.py:
--------------------------------------------------------------------------------
1 | from pyroute2.netlink import nlmsg
2 |
3 |
4 | class rtgenmsg(nlmsg):
5 | fields = (('rtgen_family', 'B'), ('__pad', '3x'))
6 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/tcmsg/README.md:
--------------------------------------------------------------------------------
1 | See the API description in `sched_template.py`
2 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/tcmsg/act_bpf.py:
--------------------------------------------------------------------------------
1 | from pyroute2.netlink import nla
2 | from pyroute2.netlink.rtnl.tcmsg.common import tc_actions
3 |
4 |
5 | def fix_request(request):
6 | if 'rate' in request:
7 | del request['rate']
8 |
9 |
10 | class options(nla):
11 | nla_map = (
12 | ('TCA_ACT_BPF_UNSPEC', 'none'),
13 | ('TCA_ACT_BPF_TM,', 'none'),
14 | ('TCA_ACT_BPF_PARMS', 'tca_act_bpf_parms'),
15 | ('TCA_ACT_BPF_OPS_LEN', 'uint16'),
16 | ('TCA_ACT_BPF_OPS', 'hex'),
17 | ('TCA_ACT_BPF_FD', 'uint32'),
18 | ('TCA_ACT_BPF_NAME', 'asciiz'),
19 | )
20 |
21 | class tca_act_bpf_parms(nla):
22 | fields = (
23 | ('index', 'I'),
24 | ('capab', 'I'),
25 | ('action', 'i'),
26 | ('refcnt', 'i'),
27 | ('bindcnt', 'i'),
28 | )
29 |
30 |
31 | def get_parameters(kwarg):
32 | ret = {'attrs': []}
33 | if 'fd' in kwarg:
34 | ret['attrs'].append(['TCA_ACT_BPF_FD', kwarg['fd']])
35 | if 'name' in kwarg:
36 | ret['attrs'].append(['TCA_ACT_BPF_NAME', kwarg['name']])
37 | a = tc_actions[kwarg.get('action', 'drop')]
38 | ret['attrs'].append(['TCA_ACT_BPF_PARMS', {'action': a}])
39 | return ret
40 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/tcmsg/act_connmark.py:
--------------------------------------------------------------------------------
1 | from pyroute2.netlink import NLA_F_NESTED, nla
2 | from pyroute2.netlink.rtnl.tcmsg.common import tc_actions
3 |
4 | """
5 | connmark - netfilter connmark retriever action
6 | see tc-connmark(8)
7 |
8 | This filter restores the connection mark into the packet mark.
9 | Connection marks are typically handled by the CONNMARK iptables module.
10 | See iptables-extensions(8).
11 |
12 | There is no mandatory parameter, but you can specify the action, which defaults
13 | to 'pipe', and the conntrack zone (see the manual).
14 | """
15 |
16 |
17 | class options(nla):
18 | nla_flags = NLA_F_NESTED
19 | nla_map = (
20 | ('TCA_CONNMARK_UNSPEC', 'none'),
21 | ('TCA_CONNMARK_PARMS', 'tca_connmark_parms'),
22 | ('TCA_CONNMARK_TM', 'none'),
23 | )
24 |
25 | class tca_connmark_parms(nla):
26 | fields = (
27 | ('index', 'I'),
28 | ('capab', 'I'),
29 | ('action', 'i'),
30 | ('refcnt', 'i'),
31 | ('bindcnt', 'i'),
32 | ('zone', 'H'),
33 | ('__padding', 'H'), # XXX is there a better way to do this ?
34 | )
35 |
36 |
37 | def get_parameters(kwarg):
38 | ret = {'attrs': []}
39 |
40 | parms = {
41 | 'action': tc_actions[kwarg.get('action', 'pipe')],
42 | 'zone': kwarg.get('zone', 0),
43 | }
44 |
45 | ret['attrs'].append(['TCA_CONNMARK_PARMS', parms])
46 | return ret
47 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/tcmsg/act_gact.py:
--------------------------------------------------------------------------------
1 | from pyroute2.netlink import NLA_F_NESTED, nla
2 | from pyroute2.netlink.rtnl.tcmsg.common import tc_actions
3 |
4 |
5 | class options(nla):
6 | nla_flags = NLA_F_NESTED
7 | nla_map = (
8 | ('TCA_GACT_UNSPEC', 'none'),
9 | ('TCA_GACT_TM', 'none'),
10 | ('TCA_GACT_PARMS', 'tca_gact_parms'),
11 | ('TCA_GACT_PROB', 'none'),
12 | )
13 |
14 | class tca_gact_parms(nla):
15 | fields = (
16 | ('index', 'I'),
17 | ('capab', 'I'),
18 | ('action', 'i'),
19 | ('refcnt', 'i'),
20 | ('bindcnt', 'i'),
21 | )
22 |
23 |
24 | def get_parameters(kwarg):
25 | ret = {'attrs': []}
26 | a = tc_actions[kwarg.get('action', 'drop')]
27 | ret['attrs'].append(['TCA_GACT_PARMS', {'action': a}])
28 | return ret
29 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/tcmsg/act_mirred.py:
--------------------------------------------------------------------------------
1 | from pyroute2.netlink import NLA_F_NESTED, nla
2 | from pyroute2.netlink.rtnl.tcmsg.common import tc_actions
3 |
4 | """
5 | Mirred - mirror/redirect action
6 | see tc-mirred(8)
7 |
8 | Use like any other action, with the following parameters available:
9 | - direction (mandatory): ingress or egress
10 | - action (mandatory): mirror or redirect
11 | - ifindex (mandatory): destination interface for mirrored or redirected packets
12 | - index: explicit index for this action
13 | """
14 |
15 | # see tc_mirred.h
16 | MIRRED_EACTIONS = {
17 | ("egress", "redirect"): 1, # redirect packet to egress
18 | ("egress", "mirror"): 2, # mirror packet to egress
19 | ("ingress", "redirect"): 3, # redirect packet to ingress
20 | ("ingress", "mirror"): 4, # mirror packet to ingress
21 | }
22 |
23 |
24 | class options(nla):
25 | nla_flags = NLA_F_NESTED
26 | nla_map = (
27 | ('TCA_MIRRED_UNSPEC', 'none'),
28 | ('TCA_MIRRED_TM', 'none'),
29 | ('TCA_MIRRED_PARMS', 'tca_mirred_parms'),
30 | )
31 |
32 | class tca_mirred_parms(nla):
33 | fields = (
34 | ('index', 'I'),
35 | ('capab', 'I'),
36 | ('action', 'i'),
37 | ('refcnt', 'i'),
38 | ('bindcnt', 'i'),
39 | ('eaction', 'i'),
40 | ('ifindex', 'I'),
41 | )
42 |
43 |
44 | def get_parameters(kwarg):
45 | ret = {'attrs': []}
46 | # direction, action and ifindex are mandatory
47 | parms = {
48 | 'eaction': MIRRED_EACTIONS[(kwarg['direction'], kwarg['action'])],
49 | 'ifindex': kwarg['ifindex'],
50 | }
51 |
52 | if 'index' in kwarg:
53 | parms['index'] = int(kwarg['index'])
54 |
55 | # From m_mirred.c
56 | if kwarg['action'] == 'redirect':
57 | parms['action'] = tc_actions['stolen']
58 | else: # mirror
59 | parms['action'] = tc_actions['pipe']
60 |
61 | ret['attrs'].append(['TCA_MIRRED_PARMS', parms])
62 | return ret
63 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/tcmsg/act_vlan.py:
--------------------------------------------------------------------------------
1 | from socket import htons
2 |
3 | from pyroute2.netlink import nla
4 | from pyroute2.netlink.rtnl.tcmsg.common import tc_actions
5 |
6 | v_actions = {'pop': 1, 'push': 2, 'modify': 3}
7 |
8 |
9 | class options(nla):
10 | nla_map = (
11 | ('TCA_VLAN_UNSPEC', 'none'),
12 | ('TCA_VLAN_TM', 'none'),
13 | ('TCA_VLAN_PARMS', 'tca_vlan_parms'),
14 | ('TCA_VLAN_PUSH_VLAN_ID', 'uint16'),
15 | ('TCA_VLAN_PUSH_VLAN_PROTOCOL', 'uint16'),
16 | ('TCA_VLAN_PAD', 'none'),
17 | ('TCA_VLAN_PUSH_VLAN_PRIORITY', 'uint8'),
18 | )
19 |
20 | class tca_vlan_parms(nla):
21 | fields = (
22 | ('index', 'I'),
23 | ('capab', 'I'),
24 | ('action', 'i'),
25 | ('refcnt', 'i'),
26 | ('bindcnt', 'i'),
27 | ('v_action', 'i'),
28 | )
29 |
30 |
31 | def get_parameters(kwarg):
32 | ret = {'attrs': []}
33 | parms = {'v_action': v_actions[kwarg['v_action']]}
34 | parms['action'] = tc_actions[kwarg.get('action', 'pipe')]
35 | ret['attrs'].append(['TCA_VLAN_PARMS', parms])
36 | # Vlan id compulsory for "push" and "modify"
37 | if kwarg['v_action'] in ['push', 'modify']:
38 | ret['attrs'].append(['TCA_VLAN_PUSH_VLAN_ID', kwarg['id']])
39 | if 'priority' in kwarg:
40 | ret['attrs'].append(['TCA_VLAN_PUSH_VLAN_PRIORITY', kwarg['priority']])
41 | if kwarg.get('protocol', '802.1Q') == '802.1ad':
42 | ret['attrs'].append(['TCA_VLAN_PUSH_VLAN_PROTOCOL', htons(0x88A8)])
43 | else:
44 | ret['attrs'].append(['TCA_VLAN_PUSH_VLAN_PROTOCOL', htons(0x8100)])
45 | return ret
46 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/tcmsg/cls_fw.py:
--------------------------------------------------------------------------------
1 | from socket import htons
2 |
3 | from pyroute2 import protocols
4 | from pyroute2.netlink import nla
5 | from pyroute2.netlink.rtnl.tcmsg.act_police import (
6 | get_parameters as ap_parameters,
7 | )
8 | from pyroute2.netlink.rtnl.tcmsg.act_police import nla_plus_police
9 | from pyroute2.netlink.rtnl.tcmsg.common_act import get_tca_action, tca_act_prio
10 |
11 |
12 | def fix_request(request):
13 | if 'rate' in request:
14 | del request['rate']
15 | request['info'] = htons(
16 | request.get('protocol', protocols.ETH_P_ALL) & 0xFFFF
17 | ) | ((request.get('prio', 0) << 16) & 0xFFFF0000)
18 |
19 |
20 | def get_parameters(kwarg):
21 | ret = {'attrs': []}
22 | attrs_map = (
23 | ('classid', 'TCA_FW_CLASSID'),
24 | # ('police', 'TCA_FW_POLICE'),
25 | # Handled in ap_parameters
26 | ('indev', 'TCA_FW_INDEV'),
27 | ('mask', 'TCA_FW_MASK'),
28 | )
29 |
30 | if kwarg.get('rate'):
31 | ret['attrs'].append(['TCA_FW_POLICE', ap_parameters(kwarg)])
32 |
33 | if kwarg.get('action'):
34 | ret['attrs'].append(['TCA_FW_ACT', get_tca_action(kwarg)])
35 |
36 | for k, v in attrs_map:
37 | r = kwarg.get(k, None)
38 | if r is not None:
39 | ret['attrs'].append([v, r])
40 |
41 | return ret
42 |
43 |
44 | class options(nla, nla_plus_police):
45 | nla_map = (
46 | ('TCA_FW_UNSPEC', 'none'),
47 | ('TCA_FW_CLASSID', 'uint32'),
48 | ('TCA_FW_POLICE', 'police'), # TODO string?
49 | ('TCA_FW_INDEV', 'hex'), # TODO string
50 | ('TCA_FW_ACT', 'tca_act_prio'),
51 | ('TCA_FW_MASK', 'uint32'),
52 | )
53 |
54 | tca_act_prio = tca_act_prio
55 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/tcmsg/cls_matchall.py:
--------------------------------------------------------------------------------
1 | from socket import htons
2 |
3 | from pyroute2 import protocols
4 | from pyroute2.netlink import nla
5 | from pyroute2.netlink.rtnl.tcmsg.common_act import get_tca_action, tca_act_prio
6 |
7 |
8 | def fix_request(request):
9 | if 'rate' in request:
10 | del request['rate']
11 | request['info'] = htons(
12 | request.get('protocol', protocols.ETH_P_ALL) & 0xFFFF
13 | ) | ((request.get('prio', 0) << 16) & 0xFFFF0000)
14 |
15 |
16 | def get_parameters(kwarg):
17 | ret = {'attrs': []}
18 | attrs_map = (
19 | ('classid', 'TCA_MATCHALL_CLASSID'),
20 | ('flags', 'TCA_MATCHALL_FLAGS'),
21 | )
22 |
23 | if kwarg.get('action'):
24 | ret['attrs'].append(['TCA_MATCHALL_ACT', get_tca_action(kwarg)])
25 |
26 | for k, v in attrs_map:
27 | r = kwarg.get(k, None)
28 | if r is not None:
29 | ret['attrs'].append([v, r])
30 |
31 | return ret
32 |
33 |
34 | class options(nla):
35 | nla_map = (
36 | ('TCA_MATCHALL_UNSPEC', 'none'),
37 | ('TCA_MATCHALL_CLASSID', 'be32'),
38 | ('TCA_MATCHALL_ACT', 'tca_act_prio'),
39 | ('TCA_MATCHALL_FLAGS', 'be32'),
40 | )
41 |
42 | tca_act_prio = tca_act_prio
43 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/tcmsg/em_ipset.py:
--------------------------------------------------------------------------------
1 | from pyroute2.netlink import nlmsg_base, nlmsg_encoder_generic
2 |
3 | # see em_ipset.c
4 | IPSET_DIM = {
5 | 'IPSET_DIM_ZERO': 0,
6 | 'IPSET_DIM_ONE': 1,
7 | 'IPSET_DIM_TWO': 2,
8 | 'IPSET_DIM_THREE': 3,
9 | 'IPSET_DIM_MAX': 6,
10 | }
11 |
12 | TCF_IPSET_MODE_DST = 0
13 | TCF_IPSET_MODE_SRC = 2
14 |
15 |
16 | def get_parameters(kwarg):
17 | ret = {'attrs': []}
18 | attrs_map = (
19 | ('matchid', 'TCF_EM_MATCHID'),
20 | ('kind', 'TCF_EM_KIND'),
21 | ('flags', 'TCF_EM_FLAGS'),
22 | ('pad', 'TCF_EM_PAD'),
23 | )
24 |
25 | for k, v in attrs_map:
26 | r = kwarg.get(k, None)
27 | if r is not None:
28 | ret['attrs'].append([v, r])
29 |
30 | return ret
31 |
32 |
33 | class data(nlmsg_base, nlmsg_encoder_generic):
34 | fields = (
35 | ('ip_set_index', 'H'),
36 | ('ip_set_dim', 'B'),
37 | ('ip_set_flags', 'B'),
38 | )
39 |
40 | def encode(self):
41 | flags, dim = self._get_ip_set_parms()
42 |
43 | self['ip_set_index'] = self['index']
44 | self['ip_set_dim'] = dim
45 | self['ip_set_flags'] = flags
46 | nlmsg_base.encode(self)
47 |
48 | def _get_ip_set_parms(self):
49 | flags = 0
50 | dim = 0
51 | mode = self['mode']
52 |
53 | # Split to get dimension
54 | modes = mode.split(',')
55 | dim = len(modes)
56 | if dim > IPSET_DIM['IPSET_DIM_MAX']:
57 | raise ValueError(
58 | 'IPSet dimension could not be greater than {0}'.format(
59 | IPSET_DIM['IPSET_DIM_MAX']
60 | )
61 | )
62 |
63 | for i in range(0, dim):
64 | if modes[i] == 'dst':
65 | flags |= TCF_IPSET_MODE_DST << i
66 | elif modes[i] == 'src':
67 | flags |= TCF_IPSET_MODE_SRC << i
68 | else:
69 | raise ValueError('Unknown IP set mode "{0}"'.format(modes[i]))
70 |
71 | return (flags, dim)
72 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/tcmsg/sched_clsact.py:
--------------------------------------------------------------------------------
1 | '''
2 | clsact
3 | ++++++
4 |
5 | The clsact qdisc provides a mechanism to attach integrated
6 | filter-action classifiers to an interface, either at ingress or egress,
7 | or both. The use case shown here is using a bpf program (implemented
8 | elsewhere) to direct the packet processing. The example also uses the
9 | direct-action feature to specify what to do with each packet (pass,
10 | drop, redirect, etc.).
11 |
12 | BPF ingress/egress example using clsact qdisc::
13 |
14 | # open_bpf_fd is outside the scope of pyroute2
15 | #fd = open_bpf_fd()
16 | eth0 = ip.get_links(ifname="eth0")[0]
17 | ip.tc("add", "clsact", eth0)
18 | # add ingress clsact
19 | ip.tc("add-filter", "bpf", idx, ":1", fd=fd, name="myprog",
20 | parent="ffff:fff2", classid=1, direct_action=True)
21 | # add egress clsact
22 | ip.tc("add-filter", "bpf", idx, ":1", fd=fd, name="myprog",
23 | parent="ffff:fff3", classid=1, direct_action=True)
24 |
25 | '''
26 |
27 | from pyroute2.netlink.rtnl import TC_H_CLSACT
28 |
29 | parent = TC_H_CLSACT
30 |
31 |
32 | def fix_request(request):
33 | if 'rate' in request:
34 | del request['rate']
35 | request['handle'] = 0xFFFF0000
36 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/tcmsg/sched_codel.py:
--------------------------------------------------------------------------------
1 | import logging
2 |
3 | from pyroute2.netlink import nla
4 | from pyroute2.netlink.rtnl import TC_H_ROOT
5 | from pyroute2.netlink.rtnl.tcmsg.common import get_time
6 | from pyroute2.netlink.rtnl.tcmsg.common import stats2 as c_stats2
7 |
8 | log = logging.getLogger(__name__)
9 | parent = TC_H_ROOT
10 |
11 |
12 | def get_parameters(kwarg):
13 | #
14 | # ACHTUNG: experimental code
15 | #
16 | # Parameters naming scheme WILL be changed in next releases
17 | #
18 | ret = {'attrs': []}
19 | transform = {
20 | 'cdl_limit': lambda x: x,
21 | 'cdl_ecn': lambda x: x,
22 | 'cdl_target': get_time,
23 | 'cdl_ce_threshold': get_time,
24 | 'cdl_interval': get_time,
25 | }
26 | for key in transform:
27 | if key in kwarg:
28 | log.warning(
29 | 'codel parameters naming will be changed '
30 | 'in next releases (%s)' % key
31 | )
32 | ret['attrs'].append(
33 | ['TCA_CODEL_%s' % key[4:].upper(), transform[key](kwarg[key])]
34 | )
35 | return ret
36 |
37 |
38 | class options(nla):
39 | nla_map = (
40 | ('TCA_CODEL_UNSPEC', 'none'),
41 | ('TCA_CODEL_TARGET', 'uint32'),
42 | ('TCA_CODEL_LIMIT', 'uint32'),
43 | ('TCA_CODEL_INTERVAL', 'uint32'),
44 | ('TCA_CODEL_ECN', 'uint32'),
45 | ('TCA_CODEL_CE_THRESHOLD', 'uint32'),
46 | )
47 |
48 |
49 | class stats(nla):
50 | fields = (
51 | ('maxpacket', 'I'),
52 | ('count', 'I'),
53 | ('lastcount', 'I'),
54 | ('ldelay', 'I'),
55 | ('drop_next', 'I'),
56 | ('drop_overlimit', 'I'),
57 | ('ecn_mark', 'I'),
58 | ('dropping', 'I'),
59 | ('ce_mark', 'I'),
60 | )
61 |
62 |
63 | class stats2(c_stats2):
64 | class stats_app(stats):
65 | pass
66 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/tcmsg/sched_drr.py:
--------------------------------------------------------------------------------
1 | '''
2 | drr
3 | +++
4 |
5 | The qdisc doesn't accept any parameters, but the class
6 | accepts `quantum` parameter::
7 |
8 | ip.tc('add', 'drr', interface, '1:')
9 | ip.tc('add-class', 'drr', interface, '1:10', quantum=1600)
10 | ip.tc('add-class', 'drr', interface, '1:20', quantum=1600)
11 |
12 | '''
13 |
14 | from pyroute2.netlink import nla
15 | from pyroute2.netlink.rtnl import TC_H_ROOT
16 | from pyroute2.netlink.rtnl.tcmsg.common import stats2 as c_stats2
17 |
18 | parent = TC_H_ROOT
19 |
20 |
21 | def get_class_parameters(kwarg):
22 | return {'attrs': [['TCA_DRR_QUANTUM', kwarg.get('quantum', 0)]]}
23 |
24 |
25 | class options(nla):
26 | nla_map = (('TCA_DRR_UNSPEC', 'none'), ('TCA_DRR_QUANTUM', 'uint32'))
27 |
28 |
29 | class stats(nla):
30 | fields = (('deficit', 'I'),)
31 |
32 |
33 | class stats2(c_stats2):
34 | class stats_app(stats):
35 | pass
36 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/tcmsg/sched_ingress.py:
--------------------------------------------------------------------------------
1 | from pyroute2.netlink import nla
2 | from pyroute2.netlink.rtnl import TC_H_INGRESS
3 |
4 | parent = TC_H_INGRESS
5 |
6 |
7 | def fix_request(request):
8 | if 'rate' in request:
9 | del request['rate']
10 | request['handle'] = 0xFFFF0000
11 |
12 |
13 | class options(nla):
14 | fields = (('value', 'I'),)
15 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/tcmsg/sched_pfifo.py:
--------------------------------------------------------------------------------
1 | from pyroute2.netlink import nla
2 | from pyroute2.netlink.rtnl import TC_H_ROOT
3 |
4 | parent = TC_H_ROOT
5 |
6 |
7 | class options(nla):
8 | fields = (('limit', 'i'),)
9 |
10 |
11 | def get_parameters(kwarg):
12 | return kwarg
13 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/tcmsg/sched_pfifo_fast.py:
--------------------------------------------------------------------------------
1 | from pyroute2.netlink import nla
2 | from pyroute2.netlink.rtnl import TC_H_ROOT
3 |
4 | parent = TC_H_ROOT
5 |
6 |
7 | class options(nla):
8 | fields = (('bands', 'i'), ('priomap', '16B'))
9 |
10 |
11 | def get_parameters(kwarg):
12 | return kwarg
13 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/tcmsg/sched_plug.py:
--------------------------------------------------------------------------------
1 | from pyroute2.netlink import nla
2 | from pyroute2.netlink.rtnl import TC_H_ROOT
3 |
4 | parent = TC_H_ROOT
5 | actions = {
6 | 'TCQ_PLUG_BUFFER': 0,
7 | 'TCQ_PLUG_RELEASE_ONE': 1,
8 | 'TCQ_PLUG_RELEASE_INDEFINITE': 2,
9 | 'TCQ_PLUG_LIMIT': 3,
10 | }
11 |
12 |
13 | def get_parameters(kwarg):
14 | return {
15 | 'action': actions.get(kwarg.get('action', 0), 0),
16 | 'limit': kwarg.get('limit', 0),
17 | }
18 |
19 |
20 | class options(nla):
21 | fields = (('action', 'i'), ('limit', 'I'))
22 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/tcmsg/sched_tbf.py:
--------------------------------------------------------------------------------
1 | from pyroute2.netlink.rtnl import TC_H_ROOT
2 | from pyroute2.netlink.rtnl.tcmsg.common import (
3 | get_rate_parameters,
4 | nla_plus_rtab,
5 | )
6 |
7 | parent = TC_H_ROOT
8 |
9 |
10 | def fix_request(request):
11 | if 'rate' in request:
12 | del request['rate']
13 |
14 |
15 | def get_parameters(kwarg):
16 | parms = get_rate_parameters(kwarg)
17 | # fill parameters
18 | return {'attrs': [['TCA_TBF_PARMS', parms], ['TCA_TBF_RTAB', True]]}
19 |
20 |
21 | class options(nla_plus_rtab):
22 | nla_map = (
23 | ('TCA_TBF_UNSPEC', 'none'),
24 | ('TCA_TBF_PARMS', 'tbf_parms'),
25 | ('TCA_TBF_RTAB', 'rtab'),
26 | ('TCA_TBF_PTAB', 'ptab'),
27 | )
28 |
29 | class tbf_parms(nla_plus_rtab.parms):
30 | fields = (
31 | ('rate_cell_log', 'B'),
32 | ('rate___reserved', 'B'),
33 | ('rate_overhead', 'H'),
34 | ('rate_cell_align', 'h'),
35 | ('rate_mpu', 'H'),
36 | ('rate', 'I'),
37 | ('peak_cell_log', 'B'),
38 | ('peak___reserved', 'B'),
39 | ('peak_overhead', 'H'),
40 | ('peak_cell_align', 'h'),
41 | ('peak_mpu', 'H'),
42 | ('peak', 'I'),
43 | ('limit', 'I'),
44 | ('buffer', 'I'),
45 | ('mtu', 'I'),
46 | )
47 |
--------------------------------------------------------------------------------
/pyroute2/netlink/rtnl/tcmsg/sched_template.py:
--------------------------------------------------------------------------------
1 | '''
2 | Template sched file. All the tcmsg plugins should be
3 | registered in `__init__.py`, see the `plugins` dict.
4 |
5 | All the methods, variables and classes are optional,
6 | but the naming scheme is fixed.
7 | '''
8 |
9 | from pyroute2.netlink import nla
10 | from pyroute2.netlink.rtnl import TC_H_ROOT
11 | from pyroute2.netlink.rtnl.tcmsg import common
12 |
13 | # if you define the `parent` variable, it will be used
14 | # as the default parent value if no other value is
15 | # provided in the call options
16 | parent = TC_H_ROOT
17 |
18 |
19 | def fix_request(request):
20 | '''
21 | This method it called for all types -- classes,
22 | qdiscs and filters. Can be used to fix some request
23 | fields.
24 | '''
25 | pass
26 |
27 |
28 | def get_parameters(kwarg):
29 | '''
30 | Called for qdiscs and filters. Should return
31 | the structure to be embedded as the qdisc parameters
32 | (`TCA_OPTIONS`).
33 | '''
34 | return None
35 |
36 |
37 | def get_class_parameters(kwarg):
38 | '''
39 | The same as above, but called only for classes.
40 | '''
41 | return None
42 |
43 |
44 | class options(nla.hex):
45 | '''
46 | The `TCA_OPTIONS` struct, by default not decoded.
47 | '''
48 |
49 | pass
50 |
51 |
52 | class stats(nla.hex):
53 | '''
54 | The struct to decode `TCA_XSTATS`.
55 | '''
56 |
57 | pass
58 |
59 |
60 | class stats2(common.stats2):
61 | '''
62 | The struct to decode `TCA_STATS2`.
63 | '''
64 |
65 | pass
66 |
--------------------------------------------------------------------------------
/pyroute2/nftables/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/pyroute2/nftables/__init__.py
--------------------------------------------------------------------------------
/pyroute2/nftables/parser/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/pyroute2/nftables/parser/__init__.py
--------------------------------------------------------------------------------
/pyroute2/nslink/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/pyroute2/nslink/__init__.py
--------------------------------------------------------------------------------
/pyroute2/plan9/ipc.py:
--------------------------------------------------------------------------------
1 | import collections
2 | import multiprocessing
3 | from socket import socketpair
4 |
5 | from pyroute2.netlink.nlsocket import NetlinkSocket
6 | from pyroute2.plan9.client import Plan9ClientSocket
7 |
8 | IPCSocketPair = collections.namedtuple('IPCSocketPair', ('server', 'client'))
9 |
10 |
11 | class IPCSocket(NetlinkSocket):
12 |
13 | def setup_socket(self):
14 | # create socket pair
15 | sp = IPCSocketPair(*socketpair())
16 | # start the server
17 | self.socket = sp
18 | self.p9server = multiprocessing.Process(target=self.ipc_server)
19 | self.p9server.daemon = True
20 | self.p9server.start()
21 | # create and init the client
22 | self.p9client = Plan9ClientSocket(use_socket=sp.client)
23 | self.p9client.init()
24 | return sp
25 |
26 | def ipc_server(self):
27 | raise NotImplementedError()
28 |
29 | def recv(self, buffersize, flags=0):
30 | ret = self.p9client.call(
31 | fid=self.p9client.fid('call'),
32 | fname='recv',
33 | kwarg={'buffersize': buffersize, 'flags': flags},
34 | )
35 | return ret['data']
36 |
37 | def send(self, data, flags=0):
38 | return self.p9client.call(
39 | fid=self.p9client.fid('call'),
40 | fname='send',
41 | kwarg={'flags': flags},
42 | data=data,
43 | )
44 |
45 | def bind(self):
46 | return self.p9client.call(fid=self.p9client.fid('call'), fname='bind')
47 |
48 | def close(self):
49 | self.socket.client.close()
50 | self.socket.server.close()
51 | self.p9server.wait()
52 |
--------------------------------------------------------------------------------
/pyroute2/plan9/plan9socket.py:
--------------------------------------------------------------------------------
1 | from pyroute2.netlink.core import CoreSocket
2 | from pyroute2.plan9 import Marshal9P
3 |
4 |
5 | class Plan9Socket(CoreSocket):
6 | def __init__(self, use_socket=None):
7 | super().__init__(use_socket=use_socket)
8 | self.marshal = Marshal9P()
9 | self.spec['tag_field'] = 'tag'
10 |
--------------------------------------------------------------------------------
/pyroute2/requests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/pyroute2/requests/__init__.py
--------------------------------------------------------------------------------
/pyroute2/requests/neighbour.py:
--------------------------------------------------------------------------------
1 | from pyroute2.common import get_address_family
2 | from pyroute2.netlink.rtnl import ndmsg
3 |
4 | from .common import Index, IPRouteFilter
5 |
6 |
7 | class NeighbourFieldFilter(Index):
8 | def set_index(self, context, value):
9 | return {
10 | 'ifindex': super(NeighbourFieldFilter, self).set_index(
11 | context, value
12 | )['index']
13 | }
14 |
15 | def set_ifindex(self, context, value):
16 | return self.set_index(context, value)
17 |
18 | def _state(self, value):
19 | if isinstance(value, str):
20 | value = ndmsg.states_a2n(value)
21 | return {'state': value}
22 |
23 | def set_nud(self, context, value):
24 | return self._state(value)
25 |
26 | def set_state(self, context, value):
27 | return self._state(value)
28 |
29 | def set_dst(self, context, value):
30 | if value:
31 | return {'dst': value}
32 | else:
33 | return {}
34 |
35 |
36 | class NeighbourIPRouteFilter(IPRouteFilter):
37 |
38 | def finalize(self, context):
39 | if self.command not in ('dump', 'get'):
40 | if 'state' not in context:
41 | context['state'] = ndmsg.NUD_PERMANENT
42 | if 'dst' in context and 'family' not in context:
43 | context['family'] = get_address_family(context['dst'])
44 |
--------------------------------------------------------------------------------
/pyroute2/requests/netns.py:
--------------------------------------------------------------------------------
1 | from .common import NLAKeyTransform
2 |
3 |
4 | class NetNSFieldFilter(NLAKeyTransform):
5 | _nla_prefix = 'NSINFO_'
6 |
--------------------------------------------------------------------------------
/pyroute2/requests/probe.py:
--------------------------------------------------------------------------------
1 | from socket import AF_INET
2 |
3 | from .common import NLAKeyTransform
4 |
5 |
6 | class ProbeFieldFilter(NLAKeyTransform):
7 | _nla_prefix = 'PROBE_'
8 |
9 | def finalize(self, context):
10 | if 'family' not in context:
11 | context['family'] = AF_INET
12 | if 'proto' not in context:
13 | context['proto'] = 1
14 | if 'port' not in context:
15 | context['port'] = 0
16 | if 'dst_len' not in context:
17 | context['dst_len'] = 32
18 | if 'kind' not in context:
19 | context['kind'] = 'ping'
20 | if 'num' not in context:
21 | context['num'] = 1
22 | if 'timeout' not in context:
23 | context['timeout'] = 1
24 |
--------------------------------------------------------------------------------
/pyroute2/requests/rule.py:
--------------------------------------------------------------------------------
1 | import socket
2 |
3 | from pyroute2.netlink.rtnl.fibmsg import FR_ACT_NAMES, fibmsg
4 |
5 | from .common import Index, IPRouteFilter, IPTargets, NLAKeyTransform
6 |
7 | DEFAULT_FRA_PRIORITY = 32000
8 |
9 |
10 | class RuleFieldFilter(IPTargets, Index, NLAKeyTransform):
11 | _nla_prefix = fibmsg.prefix
12 |
13 |
14 | class RuleIPRouteFilter(IPRouteFilter):
15 |
16 | def get_table(self, context, mode):
17 | table = context.get('table', 0)
18 | if mode == 'field':
19 | return table if 0 <= table <= 255 else 252
20 | return table
21 |
22 | def set_action(self, context, value):
23 | if isinstance(value, str):
24 | return {
25 | 'action': FR_ACT_NAMES.get(
26 | value, FR_ACT_NAMES.get('FR_ACT_' + value.upper(), value)
27 | )
28 | }
29 | return {'action': value}
30 |
31 | def finalize(self, context):
32 | if self.command != 'dump':
33 | if 'family' not in context:
34 | context['family'] = socket.AF_INET
35 | if 'priority' not in context:
36 | context['priority'] = DEFAULT_FRA_PRIORITY
37 | if 'table' in context and 'action' not in context:
38 | context['action'] = 'to_tbl'
39 | for key in ('src_len', 'dst_len'):
40 | if (
41 | context.get(key, None) is None
42 | and context.get(key[:3], None) is not None
43 | ):
44 | context[key] = {socket.AF_INET6: 128, socket.AF_INET: 32}[
45 | context['family']
46 | ]
47 |
--------------------------------------------------------------------------------
/pyroute2/statsd.py:
--------------------------------------------------------------------------------
1 | import ctypes
2 | import os
3 | import socket
4 | from typing import Literal, Optional, Union
5 |
6 | from pyroute2 import netns
7 | from pyroute2.netlink.coredata import CoreConfig, CoreSocketSpec
8 |
9 | metric_type = Literal['c', 'g', 'ms']
10 |
11 |
12 | class StatsDClientSocket(socket.socket):
13 | '''StatsD client.'''
14 |
15 | def __init__(
16 | self,
17 | address: Optional[tuple[str, int]] = None,
18 | use_socket: Optional[socket.socket] = None,
19 | flags: int = os.O_CREAT,
20 | libc: Optional[ctypes.CDLL] = None,
21 | ):
22 | self.spec = CoreSocketSpec(
23 | CoreConfig(
24 | netns=None, address=address, use_socket=use_socket is not None
25 | )
26 | )
27 | self.status = self.spec.status
28 | self.buffer: str = ''
29 | if use_socket is not None:
30 | fd = use_socket.fileno()
31 | else:
32 | prime = netns.create_socket(
33 | self.spec['netns'], socket.AF_INET, socket.SOCK_DGRAM
34 | )
35 | fd = os.dup(prime.fileno())
36 | prime.close()
37 | super().__init__(fileno=fd)
38 |
39 | def __enter__(self):
40 | return self
41 |
42 | def __exit__(self, exc_type, exc_value, traceback):
43 | self.close()
44 |
45 | def commit(self):
46 | self.sendto(self.buffer.encode(), self.spec['address'])
47 | self.buffer = ''
48 |
49 | def put(
50 | self, name: str, value: Union[int, str], kind: metric_type
51 | ) -> None:
52 | self.buffer += f'{name}:{value}|{kind}\n'
53 |
54 | def incr(self, name: str, value: int = 1) -> None:
55 | self.put(name, value, 'c')
56 | self.commit()
57 |
58 | def gauge(self, name: str, value: int) -> None:
59 | self.put(name, value, 'g')
60 | self.commit()
61 |
62 | def timing(self, name: str, value: int) -> None:
63 | self.put(name, value, 'ms')
64 | self.commit()
65 |
--------------------------------------------------------------------------------
/requirements.dev.txt:
--------------------------------------------------------------------------------
1 | build
2 | twine
3 | flake8
4 | netaddr
5 | pytest
6 | pytest-asyncio==0.26.0
7 | pytest-timeout
8 | pre-commit
9 | findimports
10 |
--------------------------------------------------------------------------------
/requirements.docs.txt:
--------------------------------------------------------------------------------
1 | build
2 | twine
3 | aafigure
4 | sphinx==6.2.0
5 | sphinx-code-include
6 | pre-commit
7 | pytest
8 | pytest-asyncio==0.26.0
9 | docutils
10 |
--------------------------------------------------------------------------------
/requirements.repo.txt:
--------------------------------------------------------------------------------
1 | nox
2 | pytest
3 | pytest-cov
4 | pytest-html
5 | pytest-timeout
6 | setuptools
7 |
--------------------------------------------------------------------------------
/setup.cfg:
--------------------------------------------------------------------------------
1 | [metadata]
2 | name = pyroute2
3 | version = file: VERSION
4 | description = Python Netlink library
5 | long_description = file: README.rst
6 | author = Peter Saveliev
7 | author_email = peter@svinota.eu
8 | long_description_content_type = text/x-rst
9 | url = https://github.com/svinota/pyroute2
10 | license = GPL-2.0-or-later OR Apache-2.0
11 | classifiers =
12 | License :: OSI Approved :: GNU General Public License v2 or later (GPLv2+)
13 | License :: OSI Approved :: Apache Software License
14 | Programming Language :: Python
15 | Topic :: Software Development :: Libraries :: Python Modules
16 | Topic :: System :: Networking
17 | Topic :: System :: Systems Administration
18 | Operating System :: POSIX :: Linux
19 | Intended Audience :: Developers
20 | Intended Audience :: System Administrators
21 | Intended Audience :: Telecommunications Industry
22 | Programming Language :: Python :: 3
23 | Programming Language :: Python :: 3.9
24 | Programming Language :: Python :: 3.10
25 | Programming Language :: Python :: 3.11
26 | Programming Language :: Python :: 3.12
27 | Programming Language :: Python :: 3.13
28 | Programming Language :: Python :: 3.14
29 | Development Status :: 4 - Beta
30 |
31 | [options]
32 | install_requires =
33 | win_inet_pton ; platform_system == "Windows"
34 | packages_dir =
35 | =pyroute2
36 | packages = find:
37 |
38 | [options.entry_points]
39 | console_scripts =
40 | ss2 = pyroute2.netlink.diag.ss2:run [psutil]
41 | pyroute2-cli = pyroute2.ndb.cli:run
42 | pyroute2-decoder = pyroute2.decoder.main:run
43 | pyroute2-dhcp-client = pyroute2.dhcp.cli:run
44 | pyroute2-test-platform = pyroute2.config.test_platform:run
45 | dhcp-server-detector = pyroute2.dhcp.server_detector:run
46 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | from setuptools import setup
2 |
3 | setup()
4 |
--------------------------------------------------------------------------------
/tests/mocklib/dateutil/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/mocklib/dateutil/__init__.py
--------------------------------------------------------------------------------
/tests/mocklib/dateutil/parser.py:
--------------------------------------------------------------------------------
1 | from unittest import mock
2 |
3 |
4 | class parse(mock.Mock):
5 | def __init__(self, *argv, **kwarg):
6 | super().__init__(*argv, **kwarg)
7 | self.timestamp = mock.Mock(name='timestamp')
8 | self.timestamp.return_value = 3313938316
9 |
--------------------------------------------------------------------------------
/tests/mocklib/keystoneauth1/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/mocklib/keystoneauth1/__init__.py
--------------------------------------------------------------------------------
/tests/mocklib/keystoneauth1/identity/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/mocklib/keystoneauth1/identity/__init__.py
--------------------------------------------------------------------------------
/tests/mocklib/keystoneauth1/identity/v3.py:
--------------------------------------------------------------------------------
1 | from unittest import mock
2 |
3 | Password = mock.Mock()
4 |
--------------------------------------------------------------------------------
/tests/mocklib/keystoneauth1/session/__init__.py:
--------------------------------------------------------------------------------
1 | from unittest import mock
2 |
3 | Session = mock.Mock()
4 |
--------------------------------------------------------------------------------
/tests/mocklib/keystoneclient/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/mocklib/keystoneclient/__init__.py
--------------------------------------------------------------------------------
/tests/mocklib/keystoneclient/v3/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/mocklib/keystoneclient/v3/__init__.py
--------------------------------------------------------------------------------
/tests/mocklib/keystoneclient/v3/client.py:
--------------------------------------------------------------------------------
1 | from unittest import mock
2 |
3 | Client = mock.Mock()
4 |
--------------------------------------------------------------------------------
/tests/mocklib/keystoneclient/v3/tokens.py:
--------------------------------------------------------------------------------
1 | from unittest import mock
2 |
3 |
4 | class TokenManager:
5 | validate = mock.Mock(name='validate')
6 | validate.return_value = {'expires_at': '3022.07.04 00:00 CEST'}
7 |
8 | def __init__(self, *argv, **kwarg):
9 | pass
10 |
--------------------------------------------------------------------------------
/tests/mocklib/pyrad/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/mocklib/pyrad/__init__.py
--------------------------------------------------------------------------------
/tests/mocklib/pyrad/client.py:
--------------------------------------------------------------------------------
1 | import collections
2 | from unittest import mock
3 |
4 |
5 | class Client(mock.MagicMock):
6 | def __init__(self, *argv, **kwarg):
7 | super().__init__(*argv, **kwarg)
8 | self.SendPacket = mock.Mock(name='SendPacket')
9 | self.SendPacket.return_value = collections.namedtuple(
10 | 'reply', ['code']
11 | )(True)
12 |
--------------------------------------------------------------------------------
/tests/mocklib/pyrad/dictionary.py:
--------------------------------------------------------------------------------
1 | from unittest import mock
2 |
3 | Dictionary = mock.Mock()
4 |
--------------------------------------------------------------------------------
/tests/mocklib/pyrad/packet.py:
--------------------------------------------------------------------------------
1 | AccessRequest = True
2 | AccessAccept = True
3 |
--------------------------------------------------------------------------------
/tests/test_ci/conftest.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | from pyroute2 import config, netns
4 |
5 | config.mock_netlink = True
6 | config.mock_netns = True
7 | pytest_plugins = ["pyroute2.fixtures.iproute", "pyroute2.fixtures.plan9"]
8 | cleanup_netns_set = set()
9 |
10 |
11 | @pytest.fixture
12 | def netns_create_list():
13 | return set([x[0][0] for x in netns.create().call_args_list if x[0]])
14 |
15 |
16 | @pytest.fixture
17 | def netns_remove_list():
18 | return set([x[0][0] for x in netns.remove().call_args_list if x[0]])
19 |
20 |
21 | def check_fixture_spec_func(fixture, scope, name):
22 | spec = fixture._pytestfixturefunction
23 | return all((spec.name == name, spec.scope == scope))
24 |
25 |
26 | @pytest.fixture
27 | def check_fixture_spec():
28 | yield check_fixture_spec_func
29 |
30 |
31 | @pytest.fixture
32 | def cleanup_netns():
33 | global cleanup_netns_set
34 | yield cleanup_netns_set
35 |
--------------------------------------------------------------------------------
/tests/test_core/conftest.py:
--------------------------------------------------------------------------------
1 | import subprocess
2 | from collections import namedtuple
3 |
4 | import pytest
5 |
6 | from pyroute2.common import uifname
7 |
8 | NFTSetup = namedtuple('NFTSetup', ('table', 'chain'))
9 |
10 |
11 | @pytest.fixture
12 | def nft():
13 | table = uifname()
14 | chain = uifname()
15 | subprocess.call(f'nft add table {table}'.split())
16 | subprocess.call(
17 | f'nft add chain {table} {chain} '
18 | f'{{ type filter hook input priority 500 ; }}'.split()
19 | )
20 | subprocess.call(
21 | f'nft add chain {table} POSTROUTING '
22 | f'{{ type nat hook postrouting priority 100 ; }}'.split()
23 | )
24 | yield NFTSetup(table, chain)
25 | subprocess.call(f'nft delete table {table}'.split())
26 |
27 |
28 | pytest_plugins = ["pyroute2.fixtures.iproute", "pyroute2.fixtures.plan9"]
29 |
--------------------------------------------------------------------------------
/tests/test_core/test_check_tid.py:
--------------------------------------------------------------------------------
1 | import logging
2 | import threading
3 | import warnings
4 |
5 | import pytest
6 |
7 | from pyroute2 import IPRoute
8 |
9 |
10 | def catch_tid_error(ipr):
11 | try:
12 | ipr._check_tid(tag='0x8241', level=logging.ERROR)
13 | except RuntimeError as e:
14 | assert '#0x8241' in e.args[0]
15 | warnings.warn('#0x8242')
16 |
17 |
18 | @pytest.mark.parametrize(
19 | 'func,tag',
20 | (
21 | (lambda x: x.bind(), '#bind'),
22 | (lambda x: x._check_tid(tag='0x8240', level=logging.WARN), '#0x8240'),
23 | (catch_tid_error, '#0x8242'),
24 | ),
25 | )
26 | def test_calls(func, tag):
27 | with warnings.catch_warnings(record=True) as wrec:
28 | with IPRoute() as ipr:
29 | t = threading.Thread(target=func, args=[ipr])
30 | t.start()
31 | t.join()
32 | assert len(wrec) == 1
33 | assert tag in wrec[0].message.args[0]
34 |
--------------------------------------------------------------------------------
/tests/test_core/test_ipr/test_addr_async.py:
--------------------------------------------------------------------------------
1 | import re
2 |
3 | import pytest
4 | from net_tools import address_exists
5 |
6 | ip4v6 = re.compile('^[.:0-9a-f]*$')
7 |
8 |
9 | @pytest.mark.asyncio
10 | async def test_addr_dump(async_ipr):
11 | async for addr in await async_ipr.addr('dump'):
12 | index = addr.get('index')
13 | address = addr.get('address', '')
14 | prefixlen = addr.get('prefixlen')
15 | assert index > 0
16 | assert ip4v6.match(address)
17 | assert prefixlen > 0
18 |
19 |
20 | @pytest.mark.asyncio
21 | async def test_addr_add(async_ipr, test_link_ifname, test_link_index, nsname):
22 | await async_ipr.addr(
23 | 'add', index=test_link_index, address='192.168.145.150', prefixlen=24
24 | )
25 | assert address_exists('192.168.145.150', test_link_ifname, netns=nsname)
26 |
27 |
28 | @pytest.mark.parametrize(
29 | 'request_info,assert_info',
30 | (
31 | ({'preferred': 99}, {'preferred': 99}),
32 | ({'preferred_lft': 109}, {'preferred': 109}),
33 | ({'valid': 119, 'preferred': 100}, {'valid': 119}),
34 | ({'valid_lft': 129, 'preferred': 100}, {'valid': 129}),
35 | ),
36 | )
37 | @pytest.mark.asyncio
38 | async def test_addr_cacheinfo(
39 | async_ipr,
40 | test_link_ifname,
41 | test_link_index,
42 | nsname,
43 | request_info,
44 | assert_info,
45 | ):
46 | await async_ipr.addr(
47 | 'add',
48 | index=test_link_index,
49 | address='2001:db8::5678',
50 | mask=128,
51 | **request_info
52 | )
53 | assert address_exists('2001:db8::5678', netns=nsname, **assert_info)
54 |
--------------------------------------------------------------------------------
/tests/test_core/test_ipr/test_addr_sync.py:
--------------------------------------------------------------------------------
1 | import re
2 |
3 | import pytest
4 | from net_tools import address_exists
5 |
6 | ip4v6 = re.compile('^[.:0-9a-f]*$')
7 |
8 |
9 | def test_addr_dump(sync_ipr):
10 | for addr in sync_ipr.addr('dump'):
11 | index = addr.get('index')
12 | address = addr.get('address', '')
13 | prefixlen = addr.get('prefixlen')
14 | assert index > 0
15 | assert ip4v6.match(address)
16 | assert prefixlen > 0
17 |
18 |
19 | def test_addr_add(sync_ipr, test_link_ifname, test_link_index, nsname):
20 | sync_ipr.addr(
21 | 'add', index=test_link_index, address='192.168.145.150', prefixlen=24
22 | )
23 | assert address_exists('192.168.145.150', test_link_ifname, netns=nsname)
24 |
25 |
26 | @pytest.mark.parametrize(
27 | 'request_info,assert_info',
28 | (
29 | ({'preferred': 99}, {'preferred': 99}),
30 | ({'preferred_lft': 109}, {'preferred': 109}),
31 | ({'valid': 119, 'preferred': 100}, {'valid': 119}),
32 | ({'valid_lft': 129, 'preferred': 100}, {'valid': 129}),
33 | ),
34 | )
35 | def test_addr_cacheinfo(
36 | sync_ipr,
37 | test_link_ifname,
38 | test_link_index,
39 | nsname,
40 | request_info,
41 | assert_info,
42 | ):
43 | sync_ipr.addr(
44 | 'add',
45 | index=test_link_index,
46 | address='2001:db8::5678',
47 | mask=128,
48 | **request_info
49 | )
50 | assert address_exists('2001:db8::5678', netns=nsname, **assert_info)
51 |
--------------------------------------------------------------------------------
/tests/test_core/test_ipr/test_link_async.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from net_tools import interface_exists
3 |
4 |
5 | @pytest.mark.asyncio
6 | async def test_link_dump(async_ipr):
7 | async for link in await async_ipr.link('dump'):
8 | assert link.get('index') > 0
9 | assert 1 < len(link.get('ifname')) < 16
10 |
11 |
12 | @pytest.mark.asyncio
13 | async def test_link_add(async_ipr, tmp_link_ifname, nsname):
14 | await async_ipr.link(
15 | 'add', ifname=tmp_link_ifname, kind='dummy', state='up'
16 | )
17 | assert interface_exists(tmp_link_ifname, netns=nsname)
18 |
19 |
20 | @pytest.mark.asyncio
21 | async def test_link_get(async_ipr, test_link_ifname):
22 | (link,) = await async_ipr.link('get', ifname=test_link_ifname)
23 | assert link.get('state') == 'up'
24 | assert link.get('index') > 1
25 | assert link.get('ifname') == test_link_ifname
26 | assert link.get(('linkinfo', 'kind')) == 'dummy'
27 |
28 |
29 | @pytest.mark.asyncio
30 | async def test_link_del_by_index(
31 | async_ipr, test_link_ifname, test_link_index, nsname
32 | ):
33 | (link,) = await async_ipr.link('get', ifname=test_link_ifname)
34 | await async_ipr.link('del', index=test_link_index)
35 | assert not interface_exists(test_link_ifname, netns=nsname)
36 |
37 |
38 | @pytest.mark.asyncio
39 | async def test_link_del_by_name(async_ipr, test_link_ifname, nsname):
40 | await async_ipr.link('del', ifname=test_link_ifname)
41 | assert not interface_exists(test_link_ifname, netns=nsname)
42 |
--------------------------------------------------------------------------------
/tests/test_core/test_ipr/test_link_sync.py:
--------------------------------------------------------------------------------
1 | from net_tools import interface_exists
2 |
3 |
4 | def test_link_dump(sync_ipr):
5 | for link in sync_ipr.link('dump'):
6 | assert link.get('index') > 0
7 | assert 1 < len(link.get('ifname')) < 16
8 |
9 |
10 | def test_link_add(sync_ipr, tmp_link_ifname, nsname):
11 | sync_ipr.link('add', ifname=tmp_link_ifname, kind='dummy', state='up')
12 | assert interface_exists(tmp_link_ifname, netns=nsname)
13 |
14 |
15 | def test_link_get(sync_ipr, test_link_ifname):
16 | (link,) = sync_ipr.link('get', ifname=test_link_ifname)
17 | assert link.get('state') == 'up'
18 | assert link.get('index') > 1
19 | assert link.get('ifname') == test_link_ifname
20 | assert link.get(('linkinfo', 'kind')) == 'dummy'
21 |
22 |
23 | def test_link_del_by_index(
24 | sync_ipr, test_link_ifname, test_link_index, nsname
25 | ):
26 | (link,) = sync_ipr.link('get', ifname=test_link_ifname)
27 | sync_ipr.link('del', index=test_link_index)
28 | assert not interface_exists(test_link_ifname, netns=nsname)
29 |
30 |
31 | def test_link_del_by_name(sync_ipr, test_link_ifname, nsname):
32 | sync_ipr.link('del', ifname=test_link_ifname)
33 | assert not interface_exists(test_link_ifname, netns=nsname)
34 |
--------------------------------------------------------------------------------
/tests/test_core/test_ipr/test_route_async.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | from pyroute2 import AsyncIPRoute
4 |
5 |
6 | @pytest.mark.parametrize(
7 | "command,kwarg",
8 | [
9 | ("dump", {"table": 255}),
10 | ("show", {"table": 255}),
11 | ("dump", {"match": {"table": 255}}),
12 | ("show", {"match": {"table": 255}}),
13 | ],
14 | )
15 | @pytest.mark.asyncio
16 | async def test_route_filter(async_ipr, command, kwarg):
17 | assert set(
18 | [
19 | route.get('table')
20 | async for route in await async_ipr.route(command, **kwarg)
21 | ]
22 | ) == set([255])
23 |
24 |
25 | @pytest.mark.parametrize(
26 | "command,kwarg",
27 | [
28 | ("dump", {"table": 255, "family": 1}),
29 | ("show", {"table": 255, "family": 1}),
30 | ],
31 | )
32 | @pytest.mark.asyncio
33 | async def test_route_filter_strict(command, kwarg):
34 | async with AsyncIPRoute(strict_check=True) as ipr:
35 | assert set(
36 | [
37 | route.get('table')
38 | async for route in await ipr.route(command, **kwarg)
39 | ]
40 | ) == set([255])
41 |
--------------------------------------------------------------------------------
/tests/test_core/test_ipr/test_route_sync.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | from pyroute2 import IPRoute
4 |
5 |
6 | @pytest.mark.parametrize(
7 | "command,kwarg",
8 | [
9 | ("dump", {"table": 255}),
10 | ("show", {"table": 255}),
11 | ("dump", {"match": {"table": 255}}),
12 | ("show", {"match": {"table": 255}}),
13 | ],
14 | )
15 | def test_route_filter(sync_ipr, command, kwarg):
16 | assert set(
17 | [route.get('table') for route in sync_ipr.route(command, **kwarg)]
18 | ) == set([255])
19 |
20 |
21 | @pytest.mark.parametrize(
22 | "command,kwarg",
23 | [
24 | ("dump", {"table": 255, "family": 1}),
25 | ("show", {"table": 255, "family": 1}),
26 | ],
27 | )
28 | def test_route_filter_strict(command, kwarg):
29 | with IPRoute(strict_check=True) as ipr:
30 | assert set(
31 | [route.get('table') for route in ipr.route(command, **kwarg)]
32 | ) == set([255])
33 |
--------------------------------------------------------------------------------
/tests/test_core/test_ipr/test_rule_sync.py:
--------------------------------------------------------------------------------
1 | from socket import AF_INET, AF_INET6
2 |
3 | import pytest
4 | from net_tools import rule_exists
5 |
6 |
7 | @pytest.mark.parametrize(
8 | 'priority,spec',
9 | [
10 | (30313, {'table': 10}),
11 | (30314, {'table': 10, 'src': None}),
12 | (30315, {'table': 10, 'dst': None}),
13 | (30316, {'table': 10, 'dst': '127.0.0.0/24'}),
14 | (30317, {'table': 10, 'src': '127.0.0.0/24'}),
15 | ],
16 | )
17 | @pytest.mark.parametrize(
18 | 'sync_ipr', [{'ext_ack': True, 'strict_check': True}], indirect=True
19 | )
20 | def test_rule_strict_src(sync_ipr, priority, spec, nsname):
21 | sync_ipr.rule('add', priority=priority, **spec)
22 | assert rule_exists(priority=priority, netns=nsname)
23 |
24 |
25 | @pytest.mark.parametrize(
26 | 'priority,proto,spec',
27 | [
28 | (20100, AF_INET, {'table': 10}),
29 | (20101, AF_INET, {'table': 10, 'fwmark': 15}),
30 | (20102, AF_INET, {'table': 10, 'fwmark': 15, 'fwmask': 20}),
31 | (20103, AF_INET, {'table': 2048, 'FRA_FWMARK': 10, 'FRA_FWMASK': 12}),
32 | (20104, AF_INET, {'table': 2048, 'src': '127.0.1.0', 'src_len': 24}),
33 | (20105, AF_INET, {'table': 2048, 'dst': '127.0.1.0', 'dst_len': 24}),
34 | (20106, AF_INET6, {'table': 5192, 'src': 'fd00::', 'src_len': 8}),
35 | (20107, AF_INET6, {'table': 5192, 'dst': 'fd00::', 'dst_len': 8}),
36 | ],
37 | )
38 | def test_rule_add_del(sync_ipr, priority, proto, spec, nsname):
39 | sync_ipr.rule('add', priority=priority, **spec)
40 | assert rule_exists(priority=priority, proto=proto, netns=nsname)
41 | assert (
42 | len([x for x in sync_ipr.rule('dump', priority=priority, **spec)]) == 1
43 | )
44 | sync_ipr.rule('del', priority=priority, **spec)
45 | assert not rule_exists(
46 | priority=priority, proto=proto, netns=nsname, timeout=0.1
47 | )
48 |
--------------------------------------------------------------------------------
/tests/test_core/test_nftables/test_nftsocket.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | from pyroute2 import AsyncNFTSocket, NFTSocket
4 | from pyroute2.netlink.nfnetlink import nfgen_msg
5 | from pyroute2.netlink.nfnetlink.nftsocket import (
6 | NFT_MSG_GETCHAIN,
7 | NFT_MSG_GETTABLE,
8 | )
9 |
10 | list_objects = pytest.mark.parametrize(
11 | 'cmd,get_field',
12 | (
13 | (NFT_MSG_GETTABLE, lambda x: x.table),
14 | (NFT_MSG_GETCHAIN, lambda x: x.chain),
15 | ),
16 | ids=['table', 'chain'],
17 | )
18 |
19 |
20 | @list_objects
21 | def test_list_sync(nft, cmd, get_field):
22 | with NFTSocket() as sock:
23 | objects = [
24 | msg.get('name') for msg in sock.request_get(nfgen_msg(), cmd)
25 | ]
26 | assert get_field(nft) in objects
27 |
28 |
29 | @list_objects
30 | @pytest.mark.asyncio
31 | async def test_list_async(nft, cmd, get_field):
32 | async with AsyncNFTSocket() as sock:
33 | objects = [
34 | msg.get('name')
35 | async for msg in await sock.request_get(nfgen_msg(), cmd)
36 | ]
37 | assert get_field(nft) in objects
38 |
--------------------------------------------------------------------------------
/tests/test_core/test_plan9/test_basic.py:
--------------------------------------------------------------------------------
1 | import time
2 |
3 | import pytest
4 |
5 |
6 | @pytest.mark.asyncio
7 | async def test_server_data_read(async_p9_context):
8 | fid = await async_p9_context.client.fid('test_file')
9 | response = await async_p9_context.client.read(fid)
10 | assert response['data'] == async_p9_context.sample_data
11 |
12 |
13 | @pytest.mark.asyncio
14 | async def test_server_time_read(async_p9_context):
15 | ts = time.time_ns()
16 | fid = await async_p9_context.client.fid('test_time')
17 | responses = [await async_p9_context.client.read(fid) for _ in range(5)]
18 | times = {int(x['data'].decode('utf-8')) for x in responses}
19 | assert len(times) == 5
20 | assert min(times) > ts
21 | assert max(times) < time.time_ns()
22 |
23 |
24 | @pytest.mark.asyncio
25 | async def test_server_data_write(async_p9_context):
26 | new_sample = b'aevei3PhaeGeiseh'
27 | fid = await async_p9_context.client.fid('test_file')
28 | await async_p9_context.client.write(fid, new_sample)
29 | response = await async_p9_context.client.read(fid)
30 | assert response['data'] == new_sample
31 | assert new_sample != async_p9_context.sample_data
32 |
--------------------------------------------------------------------------------
/tests/test_core/test_socket_create.py:
--------------------------------------------------------------------------------
1 | import time
2 |
3 | import pytest
4 |
5 | from pyroute2 import AsyncIPRoute, config, netns
6 | from pyroute2.common import uifname
7 |
8 |
9 | def fake_create(*argv, **kwarg):
10 | time.sleep(600)
11 |
12 |
13 | @pytest.mark.asyncio
14 | async def test_netns_timeout(monkeypatch):
15 | monkeypatch.setattr(config, 'default_create_socket_timeout', 1)
16 | monkeypatch.setattr(config, 'default_communicate_timeout', 0.3)
17 | monkeypatch.setattr(netns, '_create_socket_child', fake_create)
18 |
19 | ipr = AsyncIPRoute(netns=uifname())
20 | ts_start = time.time()
21 | with pytest.raises(TimeoutError):
22 | await ipr.setup_endpoint()
23 | assert time.time() - ts_start < 2
24 |
--------------------------------------------------------------------------------
/tests/test_decoder/nl0.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/test_decoder/nl0.pcap
--------------------------------------------------------------------------------
/tests/test_decoder/test_pcap.py:
--------------------------------------------------------------------------------
1 | import json
2 | import subprocess
3 |
4 |
5 | def test_pcap_rtnl():
6 | decoder = subprocess.Popen(
7 | [
8 | "pyroute2-decoder",
9 | "-c",
10 | "pyroute2/netlink/rtnl/marshal.MarshalRtnl",
11 | "-d",
12 | "test_decoder/nl0.pcap",
13 | "-m",
14 | "ll_header{family=0}",
15 | ],
16 | stdout=subprocess.PIPE,
17 | )
18 | dump = json.loads(decoder.communicate()[0])
19 | decoder.wait()
20 | with open("test_decoder/nl0.json", 'r') as f:
21 | ref = json.load(f)
22 | assert len(ref) == len(dump)
23 | for i in range(len(ref)):
24 | assert ref[i]["pcap header"] == dump[i]["pcap header"]
25 | assert ref[i]["message class"] == dump[i]["message class"]
26 |
27 |
28 | def test_pcap_ipvs():
29 | decoder = subprocess.Popen(
30 | [
31 | "pyroute2-decoder",
32 | "-c",
33 | "pyroute2/netlink/generic/ipvs.ipvsmsg",
34 | "-d",
35 | "test_decoder/nl0.pcap",
36 | "-m",
37 | (
38 | "ll_header{family=16}"
39 | " AND data{fmt='H', offset=4, value=37}"
40 | " AND data{fmt='B', offset=16, value=1}"
41 | ),
42 | ],
43 | stdout=subprocess.PIPE,
44 | )
45 | dump = json.loads(decoder.communicate()[0])
46 | decoder.wait()
47 | assert len(dump) == 1
48 | assert dump[0]["data"]["cmd"] == 1
49 | assert dump[0]["data"]["header"]["type"] == 37
50 | assert dump[0]["link layer header"].find("family=16") > 0
51 | assert dump[0]["data"]["attrs"][0][0] == "IPVS_CMD_ATTR_SERVICE"
52 |
--------------------------------------------------------------------------------
/tests/test_integration/conftest.py:
--------------------------------------------------------------------------------
1 | pytest_plugins = ["pyroute2.fixtures.iproute"]
2 |
--------------------------------------------------------------------------------
/tests/test_integration/test_lnst.py:
--------------------------------------------------------------------------------
1 | import select
2 |
3 | import pytest
4 |
5 | from pyroute2 import IPRoute, IPRSocket
6 | from pyroute2.netlink import NLM_F_DUMP, NLM_F_REQUEST
7 | from pyroute2.netlink.rtnl import RTM_GETADDR, RTM_GETLINK
8 |
9 |
10 | @pytest.mark.parametrize(
11 | 'msg_type,dump_method,field,event',
12 | [
13 | (RTM_GETLINK, 'link', 'ifname', 'RTM_NEWLINK'),
14 | (RTM_GETADDR, 'addr', 'address', 'RTM_NEWADDR'),
15 | ],
16 | )
17 | def test_interface_manager_dump_link(
18 | nsname, msg_type, dump_method, field, event
19 | ):
20 | with IPRSocket(netns=nsname) as iprsock, IPRoute(netns=nsname) as ipr:
21 |
22 | # bring up loopback
23 | ipr.link('set', index=1, state='up')
24 | ipr.poll(ipr.addr, 'dump', address='127.0.0.1', timeout=1)
25 |
26 | # init dump:
27 | # InterfaceManager.request_netlink_dump()
28 | iprsock.put(None, msg_type, msg_flags=NLM_F_REQUEST | NLM_F_DUMP)
29 |
30 | # collect responses:
31 | # InterfaceManager.pull_netlink_messages_into_queue()
32 | ret = []
33 | while True:
34 | rl, wl, xl = select.select([iprsock], [], [], 0)
35 | if not len(rl):
36 | break
37 | ret.extend(iprsock.get())
38 |
39 | links = [x for x in getattr(ipr, dump_method)('dump')]
40 | ifnames_ipr = set([x.get(field) for x in links])
41 | ifnames_iprsock = set(
42 | [x.get(field) for x in ret if x.get('event') == event]
43 | )
44 | assert ifnames_iprsock == ifnames_ipr
45 |
--------------------------------------------------------------------------------
/tests/test_integration/test_os_vif.py:
--------------------------------------------------------------------------------
1 | from pyroute2.common import uifname
2 |
3 |
4 | def test_impl_lookup(sync_ipr, test_link_ifname):
5 | assert len(sync_ipr.link_lookup(ifname=test_link_ifname)) == 1
6 |
7 |
8 | def test_impl_add_bridge(sync_ipr):
9 | brname = uifname()
10 | args = {
11 | 'ifname': brname,
12 | 'kind': 'bridge',
13 | 'IFLA_BR_FORWARD_DELAY': 0,
14 | 'IFLA_BR_STP_STATE': 0,
15 | 'IFLA_BR_MCAST_SNOOPING': 0,
16 | 'IFLA_BR_AGEING_TIME': 1500,
17 | }
18 | sync_ipr.link('add', **args)
19 | link = [
20 | x
21 | for x in sync_ipr.poll(sync_ipr.link, 'dump', ifname=brname, timeout=5)
22 | ][0]
23 | assert link.get(('linkinfo', 'data', 'br_forward_delay')) == 0
24 | assert link.get(('linkinfo', 'data', 'br_stp_state')) == 0
25 | assert link.get(('linkinfo', 'data', 'br_mcast_snooping')) == 0
26 | assert link.get(('linkinfo', 'data', 'br_ageing_time')) == 1500
27 |
28 |
29 | def test_impl_add_vlan(sync_ipr, test_link_index):
30 | vname = uifname()
31 | args = {
32 | 'ifname': vname,
33 | 'kind': 'vlan',
34 | 'vlan_id': 1001,
35 | 'link': test_link_index,
36 | }
37 | sync_ipr.link('add', **args)
38 | link = [
39 | x
40 | for x in sync_ipr.poll(sync_ipr.link, 'dump', ifname=vname, timeout=5)
41 | ][0]
42 | assert link.get(('linkinfo', 'data', 'vlan_id')) == 1001
43 |
--------------------------------------------------------------------------------
/tests/test_integration/test_ovn_bgp_agent.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | from pyroute2 import iproute
4 | from pyroute2.common import uifname
5 |
6 |
7 | @pytest.mark.parametrize(
8 | 'method,argv',
9 | (('get_rules', []), ('route', ['show']), ('brport', ['show'])),
10 | )
11 | def test_iproute_call(method, argv):
12 | with iproute.IPRoute() as ip:
13 | iter(getattr(ip, method)(*argv))
14 |
15 |
16 | @pytest.mark.parametrize(
17 | 'param,value', (('neigh_suppress', True), ('learning', False))
18 | )
19 | def test_brport_set(
20 | sync_ipr, ndb, test_link_index, test_link_ifname, param, value
21 | ):
22 | brname = uifname()
23 | ndb.interfaces.create(ifname=brname, kind='bridge').add_port(
24 | test_link_ifname
25 | ).commit()
26 | kwarg = {param: value}
27 | sync_ipr.brport('set', index=test_link_index, **kwarg)
28 | sync_ipr.poll(
29 | sync_ipr.brport, 'dump', index=test_link_index, timeout=5, **kwarg
30 | )
31 |
--------------------------------------------------------------------------------
/tests/test_limits/conftest.py:
--------------------------------------------------------------------------------
1 | pytest_plugins = ["pyroute2.fixtures.iproute"]
2 |
--------------------------------------------------------------------------------
/tests/test_linux/pr2test/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/test_linux/pr2test/__init__.py
--------------------------------------------------------------------------------
/tests/test_linux/pr2test/custom_link_kind/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/test_linux/pr2test/custom_link_kind/__init__.py
--------------------------------------------------------------------------------
/tests/test_linux/pr2test/custom_link_kind/foo.py:
--------------------------------------------------------------------------------
1 | from pyroute2.netlink import nla
2 |
3 | register_kind = 'vlan'
4 |
5 |
6 | class vlan(nla):
7 | prefix = 'IFLA_'
8 |
9 | nla_map = (
10 | ('IFLA_FOO_UNSPEC', 'none'),
11 | ('IFLA_FOO_ID', 'uint16'),
12 | ('IFLA_FOO_FLAGS', 'vlan_flags'),
13 | ('IFLA_FOO_EGRESS_QOS', 'qos'),
14 | ('IFLA_FOO_INGRESS_QOS', 'qos'),
15 | ('IFLA_FOO_PROTOCOL', 'be16'),
16 | )
17 |
18 | class vlan_flags(nla):
19 | fields = (('flags', 'I'), ('mask', 'I'))
20 |
21 | class qos(nla):
22 | nla_map = (
23 | ('IFLA_VLAN_QOS_UNSPEC', 'none'),
24 | ('IFLA_VLAN_QOS_MAPPING', 'qos_mapping'),
25 | )
26 |
27 | class qos_mapping(nla):
28 | fields = (('from', 'I'), ('to', 'I'))
29 |
--------------------------------------------------------------------------------
/tests/test_linux/pr2test/marks.py:
--------------------------------------------------------------------------------
1 | import getpass
2 |
3 | import pytest
4 |
5 |
6 | def require_root(func=None):
7 | mark = pytest.mark.skipif(
8 | getpass.getuser() != 'root', reason='no root access'
9 | )
10 | if func:
11 | return mark(func)
12 | else:
13 | return mark
14 |
--------------------------------------------------------------------------------
/tests/test_linux/test_api/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/test_linux/test_api/__init__.py
--------------------------------------------------------------------------------
/tests/test_linux/test_devlink.py:
--------------------------------------------------------------------------------
1 | from pr2test.context_manager import skip_if_not_supported
2 |
3 | from pyroute2 import DL
4 |
5 |
6 | @skip_if_not_supported
7 | def test_list():
8 | with DL() as dl:
9 | dls = dl.get_dump()
10 | if not dls:
11 | raise RuntimeError('no devlink devices found')
12 |
13 | assert dl.list()
14 |
--------------------------------------------------------------------------------
/tests/test_linux/test_dhcp/captures/test_parser/test_android_reboot_request.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/test_linux/test_dhcp/captures/test_parser/test_android_reboot_request.pcap
--------------------------------------------------------------------------------
/tests/test_linux/test_dhcp/captures/test_parser/test_android_tethering_renew.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/test_linux/test_dhcp/captures/test_parser/test_android_tethering_renew.pcap
--------------------------------------------------------------------------------
/tests/test_linux/test_dhcp/captures/test_parser/test_decode_simple_lease_process.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/test_linux/test_dhcp/captures/test_parser/test_decode_simple_lease_process.pcap
--------------------------------------------------------------------------------
/tests/test_linux/test_dhcp/captures/test_parser/test_huawei_discover_option_148.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/test_linux/test_dhcp/captures/test_parser/test_huawei_discover_option_148.pcap
--------------------------------------------------------------------------------
/tests/test_linux/test_dhcp/captures/test_parser/test_invalid_client_id_option.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/test_linux/test_dhcp/captures/test_parser/test_invalid_client_id_option.pcap
--------------------------------------------------------------------------------
/tests/test_linux/test_dhcp/captures/test_parser/test_invalid_router_option.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/test_linux/test_dhcp/captures/test_parser/test_invalid_router_option.pcap
--------------------------------------------------------------------------------
/tests/test_linux/test_dhcp/captures/test_parser/test_netatmo_discover_request.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/test_linux/test_dhcp/captures/test_parser/test_netatmo_discover_request.pcap
--------------------------------------------------------------------------------
/tests/test_linux/test_dhcp/captures/test_parser/test_truncated_packet.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/test_linux/test_dhcp/captures/test_parser/test_truncated_packet.pcap
--------------------------------------------------------------------------------
/tests/test_linux/test_dhcp/captures/test_parser/test_washing_machine_request.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/test_linux/test_dhcp/captures/test_parser/test_washing_machine_request.pcap
--------------------------------------------------------------------------------
/tests/test_linux/test_dhcp/captures/test_parser/test_wii_discover.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/test_linux/test_dhcp/captures/test_parser/test_wii_discover.pcap
--------------------------------------------------------------------------------
/tests/test_linux/test_dhcp/captures/test_unit/test_ack_invalid_request_state.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/test_linux/test_dhcp/captures/test_unit/test_ack_invalid_request_state.pcap
--------------------------------------------------------------------------------
/tests/test_linux/test_dhcp/captures/test_unit/test_get_and_renew_lease.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/test_linux/test_dhcp/captures/test_unit/test_get_and_renew_lease.pcap
--------------------------------------------------------------------------------
/tests/test_linux/test_dhcp/captures/test_unit/test_init_reboot_nak.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/test_linux/test_dhcp/captures/test_unit/test_init_reboot_nak.pcap
--------------------------------------------------------------------------------
/tests/test_linux/test_dhcp/captures/test_unit/test_offer_wrong_xid.pcap:
--------------------------------------------------------------------------------
1 | test_requesting_timeout.pcap
--------------------------------------------------------------------------------
/tests/test_linux/test_dhcp/captures/test_unit/test_requesting_timeout.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/test_linux/test_dhcp/captures/test_unit/test_requesting_timeout.pcap
--------------------------------------------------------------------------------
/tests/test_linux/test_dhcp/captures/test_unit/test_truncated_packet.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/test_linux/test_dhcp/captures/test_unit/test_truncated_packet.pcap
--------------------------------------------------------------------------------
/tests/test_linux/test_dhcp/captures/test_unit/test_unexpected_dhcp_message.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/test_linux/test_dhcp/captures/test_unit/test_unexpected_dhcp_message.pcap
--------------------------------------------------------------------------------
/tests/test_linux/test_dhcp/captures/test_unit/test_unknown_message.pcap:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/test_linux/test_dhcp/captures/test_unit/test_unknown_message.pcap
--------------------------------------------------------------------------------
/tests/test_linux/test_dhcp/test_encode.py:
--------------------------------------------------------------------------------
1 | from typing import Any
2 |
3 | import pytest
4 |
5 | from pyroute2.dhcp.dhcp4msg import dhcp4msg
6 | from pyroute2.dhcp.enums import dhcp
7 |
8 |
9 | @pytest.mark.parametrize(
10 | ('option_name', 'option_value'),
11 | (
12 | ('name_server', ['1.1.1.2', '2.2.2.2']),
13 | ('lease_time', -1),
14 | ('host_name', 'some computer'),
15 | ('max_msg_size', 1500),
16 | ('subnet_mask', '255.255.255.0'),
17 | ('client_id', {'type': 1, 'key': '16:f4:cb:71:09:a1'}),
18 | ('client_id', {'type': 0, 'key': b'some-client-identifier'}),
19 | ('perform_mask_discovery', True),
20 | ('tcp_keepalive_garbage', False),
21 | ('host_name', [104, 97, 153, 104, 97]),
22 | ),
23 | )
24 | def test_encode_decode_options(option_name: str, option_value: Any):
25 | msg = dhcp4msg(
26 | {
27 | 'options': {
28 | 'message_type': dhcp.MessageType.ACK,
29 | option_name: option_value,
30 | }
31 | }
32 | )
33 | data = msg.encode().buf
34 | decoded_msg = dhcp4msg(buf=data).decode()
35 | assert (
36 | decoded_msg['options'][option_name]
37 | == msg['options'][option_name]
38 | == option_value
39 | )
40 |
41 |
42 | # TODO: test invalid client id
43 |
--------------------------------------------------------------------------------
/tests/test_linux/test_diag.py:
--------------------------------------------------------------------------------
1 | from socket import AF_UNIX
2 |
3 | from pr2test.marks import require_root
4 |
5 | from pyroute2 import DiagSocket
6 |
7 | pytestmark = [require_root()]
8 |
9 |
10 | def test_basic():
11 | sstats_set = set()
12 | pstats_set = set()
13 | sstats = None
14 | fd = None
15 |
16 | with DiagSocket() as ds:
17 | ds.bind()
18 | sstats = ds.get_sock_stats(family=AF_UNIX)
19 | for s in sstats:
20 | sstats_set.add(s['udiag_ino'])
21 |
22 | with open('/proc/net/unix') as fd:
23 | for line in fd.readlines():
24 | line = line.split()
25 | try:
26 | pstats_set.add(int(line[6]))
27 | except ValueError:
28 | pass
29 |
30 | assert len(sstats_set - pstats_set) < 10
31 | assert len(pstats_set - sstats_set) < 10
32 |
--------------------------------------------------------------------------------
/tests/test_linux/test_dquot/dquot.img.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/test_linux/test_dquot/dquot.img.gz
--------------------------------------------------------------------------------
/tests/test_linux/test_ethtool.py:
--------------------------------------------------------------------------------
1 | import gc
2 | import os
3 |
4 | from pyroute2 import Ethtool
5 |
6 |
7 | def get_fds():
8 | fd = os.open(f'/proc/{os.getpid()}/fd', os.O_RDONLY)
9 | try:
10 | return set(os.listdir(fd)) - {fd}
11 | finally:
12 | os.close(fd)
13 |
14 |
15 | def _test_pipe_leak():
16 | fds = get_fds()
17 | etht = Ethtool()
18 | etht.close()
19 | gc.collect()
20 | assert get_fds() == fds
21 |
22 |
23 | def _test_context_manager():
24 | fds = get_fds()
25 | with Ethtool():
26 | pass
27 | gc.collect()
28 | assert get_fds() == fds
29 |
--------------------------------------------------------------------------------
/tests/test_linux/test_generic/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/test_linux/test_generic/__init__.py
--------------------------------------------------------------------------------
/tests/test_linux/test_generic/test_basic.py:
--------------------------------------------------------------------------------
1 | import os
2 | from contextlib import ExitStack
3 |
4 | import pytest
5 |
6 | from pyroute2 import GenericNetlinkSocket, TaskStats
7 | from pyroute2.netlink import nlmsg
8 |
9 |
10 | def test_bind_first():
11 | with ExitStack() as sockets:
12 | ts = sockets.enter_context(TaskStats())
13 | gs = sockets.enter_context(GenericNetlinkSocket())
14 |
15 | with pytest.raises(RuntimeError) as ets:
16 | ts.get_pid_stat(os.getpid())
17 |
18 | with pytest.raises(RuntimeError) as egs:
19 | gs.nlm_request(nlmsg(), gs.prid)
20 |
21 | assert ets.value.args == egs.value.args
22 |
--------------------------------------------------------------------------------
/tests/test_linux/test_generic/test_mptcp.py:
--------------------------------------------------------------------------------
1 | from pr2test.context_manager import skip_if_not_supported
2 | from pr2test.marks import require_root
3 |
4 | from pyroute2 import MPTCP
5 |
6 | pytestmark = [require_root()]
7 |
8 |
9 | def get_endpoints(mptcp):
10 | return dict(
11 | (
12 | x.get_nested('MPTCP_PM_ATTR_ADDR', 'MPTCP_PM_ADDR_ATTR_ADDR4'),
13 | x.get_nested('MPTCP_PM_ATTR_ADDR', 'MPTCP_PM_ADDR_ATTR_ID'),
14 | )
15 | for x in mptcp.endpoint('show')
16 | )
17 |
18 |
19 | def get_limits(mptcp):
20 | return [
21 | (
22 | x.get_attr('MPTCP_PM_ATTR_SUBFLOWS'),
23 | x.get_attr('MPTCP_PM_ATTR_RCV_ADD_ADDRS'),
24 | )
25 | for x in mptcp.limits('show')
26 | ][0]
27 |
28 |
29 | @skip_if_not_supported
30 | def test_enpoint_add_addr4(context):
31 | with MPTCP() as mptcp:
32 | ipaddrs = [context.new_ipaddr for _ in range(3)]
33 | for ipaddr in ipaddrs:
34 | mptcp.endpoint('add', addr=ipaddr)
35 | mapping = get_endpoints(mptcp)
36 | assert set(mapping) >= set(ipaddrs)
37 | for ipaddr in ipaddrs:
38 | mptcp.endpoint('del', addr=ipaddr, id=mapping[ipaddr])
39 | assert not set(get_endpoints(mptcp)).intersection(set(ipaddrs))
40 |
41 |
42 | @skip_if_not_supported
43 | def test_limits(context):
44 | with MPTCP() as mptcp:
45 | save_subflows, save_rcv_add = get_limits(mptcp)
46 | mptcp.limits('set', subflows=2, rcv_add_addrs=3)
47 | assert get_limits(mptcp) == (2, 3)
48 | mptcp.limits('set', subflows=save_subflows, rcv_add_addrs=save_rcv_add)
49 | assert get_limits(mptcp) == (save_subflows, save_rcv_add)
50 |
--------------------------------------------------------------------------------
/tests/test_linux/test_generic/test_taskstats.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | from pr2test.marks import require_root
4 |
5 | from pyroute2 import TaskStats
6 |
7 | pytestmark = [require_root()]
8 |
9 |
10 | def test_basic():
11 | with TaskStats() as ts:
12 | ts.bind()
13 | ret = ts.get_pid_stat(os.getpid())[0]
14 |
15 | pid = ret.get_nested('TASKSTATS_TYPE_AGGR_PID', 'TASKSTATS_TYPE_PID')
16 | stats = ret.get_nested(
17 | 'TASKSTATS_TYPE_AGGR_PID', 'TASKSTATS_TYPE_STATS'
18 | )
19 |
20 | assert stats['cpu_count'] > 0
21 | assert stats['ac_pid'] == pid == os.getpid()
22 | assert stats['coremem'] > 0
23 | assert stats['virtmem'] > 0
24 |
--------------------------------------------------------------------------------
/tests/test_linux/test_integration/test_serialize.py:
--------------------------------------------------------------------------------
1 | import json
2 | import pickle
3 |
4 |
5 | def _check(context, loaded):
6 | names = set([x.get_attr('IFLA_IFNAME') for x in loaded])
7 | indices = set([x['index'] for x in loaded])
8 | assert names == {x.ifname for x in context.ndb.interfaces.dump()}
9 | assert indices == {x.index for x in context.ndb.interfaces.dump()}
10 |
11 |
12 | def test_pickle(context):
13 | links = tuple(context.ipr.link('dump'))
14 | saved = pickle.dumps(links)
15 | loaded = pickle.loads(saved)
16 | _check(context, loaded)
17 |
18 |
19 | def test_json(context):
20 | links = tuple(context.ipr.link('dump'))
21 | saved = json.dumps([x.dump() for x in links])
22 | msg_type = type(links[0])
23 | loaded = [msg_type().load(x) for x in json.loads(saved)]
24 | _check(context, loaded)
25 |
26 |
27 | def test_dump(context):
28 | links = tuple(context.ipr.link('dump'))
29 | saved = [(type(x), x.dump()) for x in links]
30 | loaded = [x[0]().load(x[1]) for x in saved]
31 | _check(context, loaded)
32 |
--------------------------------------------------------------------------------
/tests/test_linux/test_ipr/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/test_linux/test_ipr/__init__.py
--------------------------------------------------------------------------------
/tests/test_linux/test_ipr/test_basic.py:
--------------------------------------------------------------------------------
1 | import socket
2 |
3 | import pytest
4 |
5 | from pyroute2 import IPRoute
6 | from pyroute2.netlink import nlmsg
7 |
8 |
9 | def test_context_manager():
10 | with IPRoute() as ipr:
11 | ipr.get_links()
12 |
13 |
14 | def test_multiple_instances():
15 | ipr1 = IPRoute()
16 | ipr2 = IPRoute()
17 | ipr1.close()
18 | ipr2.close()
19 |
20 |
21 | def test_close():
22 | ipr = IPRoute()
23 | ipr.get_links()
24 | ipr.close()
25 | # Shouldn't be able to use the socket after closing
26 | with pytest.raises(socket.error):
27 | ipr.link('get', index=1)
28 |
29 |
30 | def test_fileno():
31 | with pytest.raises(OSError) as e:
32 | IPRoute(fileno=2048)
33 | assert e.value.errno == 9 # sendto -> Bad file descriptor
34 |
35 |
36 | def test_get_policy_map(context):
37 | assert isinstance(context.ipr.get_policy_map(), dict)
38 |
39 |
40 | def test_register_policy(context):
41 | context.ipr.register_policy(100, nlmsg)
42 | context.ipr.register_policy({101: nlmsg})
43 | context.ipr.register_policy(102, nlmsg)
44 |
45 | assert context.ipr.get_policy_map()[100] == nlmsg
46 | assert context.ipr.get_policy_map(101)[101] == nlmsg
47 | assert context.ipr.get_policy_map([102])[102] == nlmsg
48 |
49 | context.ipr.unregister_policy(100)
50 | context.ipr.unregister_policy([101])
51 | context.ipr.unregister_policy({102: nlmsg})
52 |
53 | assert 100 not in context.ipr.get_policy_map()
54 | assert 101 not in context.ipr.get_policy_map()
55 | assert 102 not in context.ipr.get_policy_map()
56 |
--------------------------------------------------------------------------------
/tests/test_linux/test_ipr/test_callbacks.py:
--------------------------------------------------------------------------------
1 | from pr2test.marks import require_root
2 |
3 | pytestmark = [require_root()]
4 |
5 |
6 | def callback(msg, cb_context):
7 | cb_context['counter'] += 1
8 |
9 |
10 | def test_callbacks_positive(context):
11 | ifname = context.new_ifname
12 | cb_context = {'counter': 0}
13 | interface = context.ndb.interfaces.create(
14 | ifname=ifname, kind='dummy'
15 | ).commit()
16 |
17 | context.ipr.register_callback(
18 | callback,
19 | lambda x: x.get('index', None) == interface['index'],
20 | (cb_context,),
21 | )
22 | context.ipr.link('set', index=interface['index'], state='up')
23 | context.ipr.link('get', index=interface['index'])
24 | counter = cb_context['counter']
25 | assert counter > 0
26 | context.ipr.unregister_callback(callback)
27 | context.ipr.link('set', index=interface['index'], state='down')
28 | context.ipr.link('get', index=interface['index'])
29 | assert cb_context['counter'] == counter
30 |
31 |
32 | def test_callbacks_negative(context):
33 | ifname = context.new_ifname
34 | cb_context = {'counter': 0}
35 | interface = context.ndb.interfaces.create(
36 | ifname=ifname, kind='dummy'
37 | ).commit()
38 |
39 | context.ipr.register_callback(
40 | callback, lambda x: x.get('index', None) == -1, (cb_context,)
41 | )
42 | context.ipr.link('set', index=interface['index'], state='up')
43 | context.ipr.link('get', index=interface['index'])
44 | counter = cb_context['counter']
45 | assert counter == 0
46 |
--------------------------------------------------------------------------------
/tests/test_linux/test_ipr/test_config.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from pr2test.marks import require_root
3 |
4 | from pyroute2 import IPRoute
5 |
6 | pytestmark = [require_root()]
7 |
8 |
9 | @pytest.mark.parametrize('nlm_echo', (True, False))
10 | def test_echo_route(context, nlm_echo):
11 | index, ifname = context.default_interface
12 | address = context.new_ipaddr
13 | gateway = context.get_ipaddr(r=0)
14 | target = context.get_ipaddr(r=1)
15 | spec = {'dst': target, 'dst_len': 32, 'gateway': gateway, 'oif': index}
16 | nla_check = {}
17 | for key, value in spec.items():
18 | nla_check[key] = value if nlm_echo else None
19 | with IPRoute(nlm_echo=nlm_echo) as ipr:
20 | context.ipr.addr('add', index=index, address=address, prefixlen=24)
21 | context.ipr.poll(context.ipr.addr, 'dump', address=address)
22 | response = tuple(ipr.route('add', **spec))[0]
23 | for key, value in nla_check.items():
24 | assert response.get(key) == value
25 |
--------------------------------------------------------------------------------
/tests/test_linux/test_ipr/test_ipbatch.py:
--------------------------------------------------------------------------------
1 | from pr2test.marks import require_root
2 |
3 | from pyroute2 import IPBatch
4 |
5 | pytestmark = [require_root()]
6 |
7 |
8 | def test_link_add(context):
9 | ifname = context.new_ifname
10 |
11 | ipb = IPBatch()
12 | ipb.link('add', ifname=ifname, kind='dummy')
13 | data = ipb.batch
14 | ipb.reset()
15 | ipb.close()
16 | context.ipr.sendto(data, (0, 0))
17 | context.ndb.interfaces.wait(ifname=ifname, timeout=3)
18 |
--------------------------------------------------------------------------------
/tests/test_linux/test_ipr/test_link_create.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from pr2test.marks import require_root
3 |
4 | from pyroute2.netlink.rtnl.ifinfmsg import ifinfmsg
5 |
6 | pytestmark = [require_root()]
7 |
8 |
9 | @pytest.mark.parametrize('smode', ('IPVLAN_MODE_L2', 'IPVLAN_MODE_L3'))
10 | def test_create_ipvlan(context, smode):
11 | master = context.new_ifname
12 | ipvlan = context.new_ifname
13 | # create the master link
14 | index = context.ndb.interfaces.create(
15 | ifname=master, kind='dummy'
16 | ).commit()['index']
17 | # check modes
18 | # maybe move modes dict somewhere else?
19 | cmode = ifinfmsg.ifinfo.data_map['ipvlan'].modes[smode]
20 | assert ifinfmsg.ifinfo.data_map['ipvlan'].modes[cmode] == smode
21 | # create ipvlan
22 | context.ipr.link(
23 | 'add', ifname=ipvlan, kind='ipvlan', link=index, mode=cmode
24 | )
25 | interface = context.ndb.interfaces.wait(ifname=ipvlan, timeout=5)
26 | assert interface['link'] == index
27 | assert interface['ipvlan_mode'] == cmode
28 |
--------------------------------------------------------------------------------
/tests/test_linux/test_ipr/test_match.py:
--------------------------------------------------------------------------------
1 | from functools import partial
2 |
3 |
4 | def test_match_callable(context):
5 | assert len(tuple(context.ipr.get_links(match=partial(lambda x: x)))) > 0
6 |
--------------------------------------------------------------------------------
/tests/test_linux/test_ipr/test_ntables.py:
--------------------------------------------------------------------------------
1 | def _test_ntables(self):
2 | setA = set(
3 | filter(
4 | lambda x: x is not None,
5 | [
6 | x.get_attr('NDTA_PARMS').get_attr('NDTPA_IFINDEX')
7 | for x in self.ip.get_ntables()
8 | ],
9 | )
10 | )
11 | setB = set([x['index'] for x in self.ip.get_links()])
12 | assert setA == setB
13 |
--------------------------------------------------------------------------------
/tests/test_linux/test_ipr/test_rule.py:
--------------------------------------------------------------------------------
1 | import socket
2 | import struct
3 |
4 | import pytest
5 | from pr2test.marks import require_root
6 |
7 | pytestmark = [require_root()]
8 |
9 |
10 | def test_flush_rules(context):
11 | ifaddr1 = context.new_ipaddr
12 | ifaddr2 = context.new_ipaddr
13 | init = len(tuple(context.ipr.get_rules(family=socket.AF_INET)))
14 | assert (
15 | len(tuple(context.ipr.get_rules(priority=lambda x: 100 < x < 500)))
16 | == 0
17 | )
18 | context.ipr.rule('add', table=10, priority=110)
19 | context.ipr.rule('add', table=15, priority=150, action='FR_ACT_PROHIBIT')
20 | context.ipr.rule('add', table=20, priority=200, src=ifaddr1)
21 | context.ipr.rule('add', table=25, priority=250, dst=ifaddr2)
22 | assert (
23 | len(tuple(context.ipr.get_rules(priority=lambda x: 100 < x < 500)))
24 | == 4
25 | )
26 | assert len(tuple(context.ipr.get_rules(src=ifaddr1))) == 1
27 | assert len(tuple(context.ipr.get_rules(dst=ifaddr2))) == 1
28 | context.ipr.flush_rules(
29 | family=socket.AF_INET, priority=lambda x: 100 < x < 500
30 | )
31 | assert (
32 | len(tuple(context.ipr.get_rules(priority=lambda x: 100 < x < 500)))
33 | == 0
34 | )
35 | assert len(tuple(context.ipr.get_rules(src=ifaddr1))) == 0
36 | assert len(tuple(context.ipr.get_rules(dst=ifaddr2))) == 0
37 | assert len(tuple(context.ipr.get_rules(family=socket.AF_INET))) == init
38 |
39 |
40 | def test_bad_table(context):
41 | with pytest.raises(struct.error):
42 | context.ipr.rule('add', table=-1, priority=32000)
43 |
--------------------------------------------------------------------------------
/tests/test_linux/test_ipr/test_stress.py:
--------------------------------------------------------------------------------
1 | import os
2 | import socket
3 |
4 | from pr2test.marks import require_root
5 |
6 | from pyroute2 import NetlinkDumpInterrupted
7 |
8 | pytestmark = [require_root()]
9 |
10 |
11 | def test_mass_ipv6(context):
12 | #
13 | ipv6net = context.new_ip6net
14 | base = str(ipv6net.network) + '{0}'
15 | limit = int(os.environ.get('PYROUTE2_SLIMIT', '0x800'), 16)
16 | index, ifname = context.default_interface
17 |
18 | # add addresses
19 | for idx in range(limit):
20 | context.ipr.addr(
21 | 'add',
22 | index=index,
23 | family=socket.AF_INET6,
24 | address=base.format(hex(idx)[2:]),
25 | prefixlen=48,
26 | )
27 |
28 | # assert addresses in two steps, to ease debug
29 | addrs = []
30 | for _ in range(3):
31 | try:
32 | addrs = tuple(context.ipr.get_addr(family=socket.AF_INET6))
33 | break
34 | except NetlinkDumpInterrupted:
35 | pass
36 | else:
37 | raise Exception('could not dump addresses')
38 | assert len(addrs) >= limit
39 |
--------------------------------------------------------------------------------
/tests/test_linux/test_ipr/test_vlan_filter.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from pr2test.marks import require_root
3 |
4 | pytestmark = [require_root()]
5 |
6 |
7 | def test_vlan_filter_dump(context):
8 | ifname1 = context.new_ifname
9 | ifname2 = context.new_ifname
10 | context.ndb.interfaces.create(
11 | ifname=ifname1, kind='bridge', state='up'
12 | ).commit()
13 | context.ndb.interfaces.create(
14 | ifname=ifname2, kind='bridge', state='up'
15 | ).commit()
16 | assert len(tuple(context.ipr.get_vlans())) >= 2
17 | for name in (ifname1, ifname2):
18 | assert len(tuple(context.ipr.get_vlans(ifname=name))) == 1
19 | assert (
20 | tuple(context.ipr.get_vlans(ifname=name))[0].get_attr(
21 | 'IFLA_IFNAME'
22 | )
23 | ) == name
24 | assert (
25 | tuple(context.ipr.get_vlans(ifname=name))[0].get_nested(
26 | 'IFLA_AF_SPEC', 'IFLA_BRIDGE_VLAN_INFO'
27 | )
28 | )['vid'] == 1
29 |
30 |
31 | @pytest.mark.parametrize(
32 | 'arg_name,vid_spec,vid',
33 | (
34 | ('vlan_info', {'vid': 568}, 568),
35 | ('af_spec', {'attrs': [['IFLA_BRIDGE_VLAN_INFO', {'vid': 567}]]}, 567),
36 | ),
37 | )
38 | def _test_vlan_filter_add(context, arg_name, vid_spec, vid):
39 | ifname_port = context.new_ifname
40 | ifname_bridge = context.new_ifname
41 | port = context.ndb.interfaces.create(
42 | ifname=ifname_port, kind='dummy', state='up'
43 | ).commit()
44 | (
45 | context.ndb.interfaces.create(
46 | ifname=ifname_bridge, kind='bridge', state='up'
47 | )
48 | .add_port(ifname_port)
49 | .commit()
50 | )
51 | assert vid not in context.ndb.vlans
52 | spec = {'index': port['index'], arg_name: vid_spec}
53 | context.ipr.vlan_filter('add', **spec)
54 | assert context.ndb.vlans.wait(vid=vid, timeout=5)
55 | context.ipr.vlan_filter('del', **spec)
56 | assert context.ndb.vlans.wait(vid=vid, timeout=5, action='remove')
57 |
--------------------------------------------------------------------------------
/tests/test_linux/test_ipvs.py:
--------------------------------------------------------------------------------
1 | from socket import IPPROTO_TCP
2 |
3 | import pytest
4 |
5 | from pyroute2 import IPVS, IPVSService
6 |
7 |
8 | class Context:
9 | def __init__(self, request, tmpdir):
10 | self.ipvs = IPVS()
11 | self.services = []
12 |
13 | def new_service(self, addr, port, protocol):
14 | service = IPVSService(addr=addr, port=port, protocol=protocol)
15 | self.ipvs.service("add", service=service)
16 | self.services.append(service)
17 | return service
18 |
19 | def teardown(self):
20 | for service in self.services:
21 | self.ipvs.service("del", service=service)
22 | self.services = []
23 |
24 | def service(self, command, service=None):
25 | return self.ipvs.service(command, service)
26 |
27 | def dest(self, command, service, dest=None):
28 | return self.ipvs.dest(command, service, dest)
29 |
30 |
31 | @pytest.fixture
32 | def ipvsadm(request, tmpdir):
33 | ctx = Context(request, tmpdir)
34 | yield ctx
35 | ctx.teardown()
36 |
37 |
38 | def test_basic(ipvsadm, context):
39 | ipaddr = context.new_ipaddr
40 | (
41 | context.ndb.interfaces[context.default_interface.ifname]
42 | .add_ip(f"{ipaddr}/24")
43 | .commit()
44 | )
45 | ipvsadm.new_service(addr=ipaddr, port=6000, protocol=IPPROTO_TCP)
46 | buffer = []
47 | for service in ipvsadm.service("dump"):
48 | if (
49 | service.get(('service', 'addr')) == ipaddr
50 | and service.get(('service', 'port')) == 6000
51 | and service.get(('service', 'protocol')) == IPPROTO_TCP
52 | ):
53 | break
54 | buffer.append(service)
55 | else:
56 | raise KeyError('service not found')
57 | print(buffer)
58 |
--------------------------------------------------------------------------------
/tests/test_linux/test_iwutil.py:
--------------------------------------------------------------------------------
1 | import collections
2 | import errno
3 |
4 | import pytest
5 | from pr2test.marks import require_root
6 |
7 | from pyroute2 import IW, IPRoute
8 | from pyroute2.netlink.exceptions import NetlinkError
9 |
10 |
11 | @pytest.fixture
12 | def ctx():
13 | iw = None
14 | ifname = None
15 | wiphy = None
16 | index = None
17 | try:
18 | iw = IW()
19 | except NetlinkError as e:
20 | if e.code == errno.ENOENT:
21 | pytest.skip('nl80211 not supported')
22 | raise
23 | ifaces = iw.get_interfaces_dump()
24 | if not ifaces:
25 | raise pytest.skip('no wireless interfaces found')
26 | for i in ifaces:
27 | ifname = i.get_attr('NL80211_ATTR_IFNAME')
28 | index = i.get_attr('NL80211_ATTR_IFINDEX')
29 | wiphy = i.get_attr('NL80211_ATTR_WIPHY')
30 | if index:
31 | break
32 | else:
33 | pytest.skip('can not detect the interface to use')
34 |
35 | yield collections.namedtuple(
36 | 'WirelessContext', ['iw', 'ifname', 'index', 'wiphy']
37 | )(iw, ifname, index, wiphy)
38 |
39 | iw.close()
40 |
41 |
42 | def test_list_wiphy(ctx):
43 | ctx.iw.list_wiphy()
44 |
45 |
46 | def test_list_dev(ctx):
47 | ctx.iw.list_dev()
48 |
49 |
50 | @require_root
51 | def test_scan(ctx):
52 | with IPRoute() as ipr:
53 | ipr.link('set', index=ctx.index, state='up')
54 | ctx.iw.scan(ctx.index)
55 |
--------------------------------------------------------------------------------
/tests/test_linux/test_ndb/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/test_linux/test_ndb/__init__.py
--------------------------------------------------------------------------------
/tests/test_linux/test_ndb/test_altnames.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from pr2test.context_manager import make_test_matrix, skip_if_not_supported
3 | from pr2test.marks import require_root
4 | from pr2test.tools import interface_exists
5 |
6 | pytestmark = [require_root()]
7 |
8 | test_matrix = make_test_matrix(
9 | targets=['local', 'netns'], dbs=['sqlite3/:memory:', 'postgres/pr2test']
10 | )
11 |
12 |
13 | @pytest.mark.xfail(reason='flaky test, to be fixed')
14 | @pytest.mark.parametrize('context', test_matrix, indirect=True)
15 | @skip_if_not_supported
16 | def test_altname_complex(context):
17 | index, ifname = context.default_interface
18 | altname1 = context.new_ifname
19 | altname2 = context.new_ifname
20 | with context.ndb.interfaces[ifname] as i:
21 | i.add_altname(altname1)
22 |
23 | assert interface_exists(context.netns, altname=altname1)
24 | assert not interface_exists(context.netns, altname=altname2)
25 |
26 | with context.ndb.interfaces[ifname] as i:
27 | i.del_altname(altname1)
28 | i.add_altname(altname2)
29 |
30 | assert interface_exists(context.netns, altname=altname2)
31 | assert not interface_exists(context.netns, altname=altname1)
32 |
33 | with context.ndb.interfaces[ifname] as i:
34 | i.del_altname(altname2)
35 |
36 | assert not interface_exists(context.netns, altname=altname1)
37 | assert not interface_exists(context.netns, altname=altname2)
38 |
--------------------------------------------------------------------------------
/tests/test_linux/test_ndb/test_backup.py:
--------------------------------------------------------------------------------
1 | import sqlite3
2 | import uuid
3 |
4 |
5 | def test_file_backup(context):
6 | filename = str(uuid.uuid4()) + '-backup.db'
7 | context.ndb.backup(filename)
8 | backup = sqlite3.connect(filename)
9 | cursor = backup.cursor()
10 | cursor.execute('SELECT f_IFLA_IFNAME FROM interfaces WHERE f_index > 0')
11 | interfaces_from_backup = {x[0] for x in cursor.fetchall()}
12 | with context.ndb.interfaces.summary() as summary:
13 | interfaces_from_ndb = {x.ifname for x in summary}
14 | assert interfaces_from_ndb == interfaces_from_backup
15 |
--------------------------------------------------------------------------------
/tests/test_linux/test_ndb/test_chaotic.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from pr2test.marks import require_root
3 | from pr2test.tools import address_exists
4 |
5 | from pyroute2 import NDB
6 |
7 | pytestmark = [require_root()]
8 |
9 |
10 | @pytest.mark.xfail(reason='flaky test, only to collect failure logs')
11 | def __test_add_del_ip_dict(context):
12 | ifname = context.new_ifname
13 | ifaddr1 = context.new_ipaddr
14 | ifaddr2 = context.new_ipaddr
15 | log_spec = (
16 | context.spec.log_spec[0] + '.chaotic',
17 | context.spec.log_spec[1],
18 | )
19 |
20 | with NDB(
21 | log=log_spec,
22 | sources=[
23 | {
24 | 'target': 'localhost',
25 | 'kind': 'ChaoticIPRoute',
26 | 'success_rate': 0.98,
27 | }
28 | ],
29 | ) as test_ndb:
30 | (
31 | test_ndb.interfaces.create(
32 | ifname=ifname, kind='dummy', state='down'
33 | )
34 | .add_ip({'address': ifaddr1, 'prefixlen': 24})
35 | .add_ip({'address': ifaddr2, 'prefixlen': 24})
36 | .commit()
37 | )
38 |
39 | assert address_exists(context.netns, ifname=ifname, address=ifaddr1)
40 | assert address_exists(context.netns, ifname=ifname, address=ifaddr2)
41 |
42 | (
43 | test_ndb.interfaces[{'ifname': ifname}]
44 | .del_ip({'address': ifaddr2, 'prefixlen': 24})
45 | .del_ip({'address': ifaddr1, 'prefixlen': 24})
46 | .commit()
47 | )
48 |
49 | assert not address_exists(
50 | context.netns, ifname=ifname, address=ifaddr1
51 | )
52 | assert not address_exists(
53 | context.netns, ifname=ifname, address=ifaddr2
54 | )
55 |
--------------------------------------------------------------------------------
/tests/test_linux/test_ndb/test_db.py:
--------------------------------------------------------------------------------
1 | import sqlite3
2 |
3 | import pytest
4 |
5 | from pyroute2 import NDB
6 |
7 | try:
8 | import psycopg2
9 | except ImportError:
10 | pytest.skip('no psycopg2 module installed', allow_module_level=True)
11 |
12 |
13 | def test_no_cleanup(spec):
14 | # start and stop the DB, leaving all the data in the DB file
15 | NDB(
16 | db_provider='sqlite3',
17 | db_spec=spec.db_spec,
18 | db_cleanup=False,
19 | log=spec.log_spec,
20 | ).close()
21 |
22 | # open the DB file
23 | db = sqlite3.connect(spec.db_spec)
24 | cursor = db.cursor()
25 | cursor.execute('SELECT * FROM interfaces')
26 | interfaces = cursor.fetchall()
27 |
28 | # at least two records: idx 0 and loopback
29 | assert len(interfaces) > 1
30 | # all the interfaces must be of the same source, 'localhost'
31 | assert set([x[0] for x in interfaces]) == set(('localhost',))
32 |
33 |
34 | def test_postgres_fail(spec):
35 | try:
36 | NDB(
37 | db_provider='postgres',
38 | db_spec={'dbname': 'some-nonsense-db-name'},
39 | log=spec.log_spec,
40 | ).close()
41 | except psycopg2.OperationalError:
42 | return
43 |
44 | raise Exception('postgresql exception was expected')
45 |
--------------------------------------------------------------------------------
/tests/test_linux/test_ndb/test_examples.py:
--------------------------------------------------------------------------------
1 | import os
2 | import pathlib
3 | import sys
4 |
5 | import pytest
6 | from pr2test.marks import require_root
7 |
8 | pytestmark = [require_root()]
9 |
10 |
11 | def get_examples(*argv):
12 | root = pathlib.Path(os.environ['WORKSPACE'])
13 | examples = [
14 | file
15 | for file in root.joinpath(*argv).iterdir()
16 | if not file.name.endswith('.swp')
17 | ]
18 | return {
19 | 'argnames': 'example',
20 | 'argvalues': examples,
21 | 'ids': [x.name for x in examples],
22 | }
23 |
24 |
25 | @pytest.mark.parametrize(**get_examples('examples', 'pyroute2-cli'))
26 | def test_cli_examples(example, pytester, context):
27 | with example.open('r') as text:
28 | result = pytester.run('pyroute2-cli', stdin=text)
29 | assert result.ret == 0
30 |
31 |
32 | @pytest.mark.parametrize(**get_examples('examples', 'ndb'))
33 | def test_ndb_examples(example, pytester, context):
34 | argv = []
35 | with example.open('r') as text:
36 | for line in text.readlines():
37 | line = line.strip()
38 | if line == ':notest:':
39 | pytest.skip()
40 | elif line.startswith(':test:argv:'):
41 | argv.append(line.split(':')[-1])
42 | elif line.startswith(':test:environ:'):
43 | key, value = line.split(':')[-1].split('=')
44 | os.environ[key] = value
45 | result = pytester.run(sys.executable, example.as_posix(), *argv)
46 | assert result.ret == 0
47 |
48 |
49 | def test_basic(tmpdir, pytester, context):
50 | pytester.makefile('.pr2', test='interfaces lo mtu')
51 | with open('test.pr2', 'r') as text:
52 | result = pytester.run("pyroute2-cli", stdin=text)
53 | assert result.ret == 0
54 | assert result.outlines == ['65536']
55 |
--------------------------------------------------------------------------------
/tests/test_linux/test_ndb/test_fdb.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from pr2test.context_manager import make_test_matrix
3 | from pr2test.marks import require_root
4 | from pr2test.tools import fdb_record_exists
5 |
6 | pytestmark = [require_root()]
7 |
8 | test_matrix = make_test_matrix(
9 | targets=['local', 'netns'],
10 | tables=[None],
11 | dbs=['sqlite3/:memory:', 'postgres/pr2test'],
12 | )
13 |
14 |
15 | @pytest.mark.parametrize('context', test_matrix, indirect=True)
16 | def test_fdb_create(context):
17 | spec = {
18 | 'ifindex': context.default_interface.index,
19 | 'lladdr': '00:11:22:33:44:55',
20 | }
21 |
22 | context.ndb.fdb.create(**spec).commit()
23 | assert fdb_record_exists(context.netns, **spec)
24 |
25 | context.ndb.fdb[spec].remove().commit()
26 | assert not fdb_record_exists(context.netns, **spec)
27 |
--------------------------------------------------------------------------------
/tests/test_linux/test_ndb/test_init.py:
--------------------------------------------------------------------------------
1 | import uuid
2 | from socket import AF_INET, AF_INET6
3 |
4 | import pytest
5 | from pr2test.marks import require_root
6 |
7 | from pyroute2 import NDB
8 | from pyroute2.netlink.rtnl import RTMGRP_IPV4_IFADDR, RTMGRP_LINK
9 |
10 | pytestmark = [require_root()]
11 |
12 |
13 | @pytest.mark.parametrize('kind', ('local', 'netns'))
14 | def test_netlink_groups(kind):
15 | spec = {
16 | 'target': 'localhost',
17 | 'kind': kind,
18 | 'groups': RTMGRP_LINK | RTMGRP_IPV4_IFADDR,
19 | }
20 | if kind == 'netns':
21 | spec['netns'] = str(uuid.uuid4())
22 | with NDB(sources=[spec]) as ndb:
23 | assert 'lo' in ndb.interfaces
24 | with ndb.interfaces['lo'] as lo:
25 | lo.set(state='up')
26 | addresses4 = ndb.addresses.dump()
27 | addresses4.select_records(family=AF_INET)
28 | assert addresses4.count() > 0
29 | addresses6 = ndb.addresses.dump()
30 | addresses6.select_records(family=AF_INET6)
31 | assert addresses6.count() == 0
32 | routes = ndb.routes.dump()
33 | assert routes.count() == 0
34 | neighbours = ndb.neighbours.dump()
35 | assert neighbours.count() == 0
36 |
--------------------------------------------------------------------------------
/tests/test_linux/test_ndb/test_probe.py:
--------------------------------------------------------------------------------
1 | import errno
2 |
3 | import pytest
4 | from pr2test.context_manager import make_test_matrix, skip_if_not_supported
5 | from pr2test.marks import require_root
6 |
7 | from pyroute2 import NetlinkError
8 |
9 | pytestmark = [require_root()]
10 | test_matrix = make_test_matrix(targets=['local', 'netns'])
11 |
12 |
13 | @pytest.mark.parametrize('context', test_matrix, indirect=True)
14 | @skip_if_not_supported
15 | def test_ping_ok(context):
16 | index, ifname = context.default_interface
17 | ipaddr = context.new_ipaddr
18 |
19 | with context.ndb.interfaces[ifname] as i:
20 | i.add_ip(address=ipaddr, prefixlen=24)
21 | i.set(state='up')
22 |
23 | with context.ndb.interfaces['lo'] as i:
24 | i.set(state='up')
25 |
26 | context.ndb.probes.create(kind='ping', dst=ipaddr).commit()
27 |
28 |
29 | @pytest.mark.parametrize(
30 | 'context', make_test_matrix(targets=['netns']), indirect=True
31 | )
32 | @skip_if_not_supported
33 | def test_ping_fail_ehostunreach(context):
34 | with context.ndb.interfaces['lo'] as i:
35 | i.set(state='down')
36 | with pytest.raises(NetlinkError) as e:
37 | context.ndb.probes.create(kind='ping', dst='127.0.0.1').commit()
38 | assert e.value.code == errno.EHOSTUNREACH
39 |
40 |
41 | @pytest.mark.parametrize(
42 | 'context', make_test_matrix(targets=['netns']), indirect=True
43 | )
44 | @skip_if_not_supported
45 | def test_ping_fail_etimedout(context):
46 | index, ifname = context.default_interface
47 | ipaddr = context.new_ipaddr
48 | target = context.new_ipaddr
49 |
50 | with context.ndb.interfaces[ifname] as i:
51 | i.add_ip(address=ipaddr, prefixlen=24)
52 | i.set(state='up')
53 | with context.ndb.interfaces['lo'] as i:
54 | i.set(state='up')
55 | with pytest.raises(NetlinkError) as e:
56 | context.ndb.probes.create(kind='ping', dst=target).commit()
57 | assert e.value.code == errno.ETIMEDOUT
58 |
--------------------------------------------------------------------------------
/tests/test_linux/test_ndb/test_rules.py:
--------------------------------------------------------------------------------
1 | from socket import AF_INET6
2 |
3 | import pytest
4 | from pr2test.context_manager import make_test_matrix
5 | from pr2test.marks import require_root
6 | from pr2test.tools import rule_exists
7 |
8 | pytestmark = [require_root()]
9 |
10 | test_matrix = make_test_matrix(
11 | targets=['local', 'netns'],
12 | tables=[100, 10000],
13 | dbs=['sqlite3/:memory:', 'postgres/pr2test'],
14 | )
15 |
16 |
17 | @pytest.mark.parametrize('context', test_matrix, indirect=True)
18 | def test_explicit_ipv6_src(context):
19 | ipnet = context.new_ip6net
20 | table = context.table
21 |
22 | spec = {
23 | 'family': AF_INET6,
24 | 'src': ipnet.network,
25 | 'src_len': ipnet.netmask,
26 | 'table': table,
27 | 'priority': 50,
28 | }
29 | context.register_rule(spec)
30 |
31 | context.ndb.rules.create(**spec).commit()
32 | assert rule_exists(context.netns, **spec)
33 |
34 | context.ndb.rules[spec].remove().commit()
35 | assert not rule_exists(context.netns, **spec)
36 |
37 |
38 | @pytest.mark.parametrize('context', test_matrix, indirect=True)
39 | def test_implicit_ipv6_src(context):
40 | ipnet = context.new_ip6net
41 | table = context.table
42 |
43 | spec = {
44 | 'src': ipnet.network,
45 | 'src_len': ipnet.netmask,
46 | 'table': table,
47 | 'priority': 50,
48 | }
49 | search_spec = spec.copy()
50 | search_spec['family'] = AF_INET6
51 | context.register_rule(search_spec)
52 |
53 | context.ndb.rules.create(**spec).commit()
54 | assert rule_exists(context.netns, **search_spec)
55 |
56 | context.ndb.rules[spec].remove().commit()
57 | assert not rule_exists(context.netns, **search_spec)
58 |
--------------------------------------------------------------------------------
/tests/test_linux/test_nlmsg/test_nlmsg.py:
--------------------------------------------------------------------------------
1 | from pr2test.marks import require_root
2 |
3 | pytestmark = [require_root()]
4 |
5 |
6 | def test_nlmsg_operators(context):
7 | ifname = context.new_ifname
8 | ipaddr1 = context.new_ipaddr
9 | ipaddr2 = context.new_ipaddr
10 | interface = (
11 | context.ndb.interfaces.create(ifname=ifname, kind='dummy', state='up')
12 | .add_ip(f'{ipaddr1}/24')
13 | .add_ip(f'{ipaddr2}/24')
14 | .commit()
15 | )
16 |
17 | r = tuple(context.ipr.addr('dump', index=interface['index']))
18 | complement = r[0] - r[1]
19 | intersection = r[0] & r[1]
20 |
21 | assert complement.get_attr('IFA_ADDRESS') == ipaddr1
22 | assert complement.get_attr('IFA_LABEL') is None
23 | assert 'prefixlen' not in complement
24 | assert 'index' not in complement
25 |
26 | assert intersection.get_attr('IFA_ADDRESS') is None
27 | assert intersection.get_attr('IFA_LABEL') == ifname
28 | assert intersection['prefixlen'] == 24
29 | assert intersection['index'] == context.ndb.interfaces[ifname]['index']
30 |
31 |
32 | def test_nlmsg_compare_equal(context):
33 | lvalue = tuple(context.ipr.get_links())[0]
34 | rvalue = tuple(context.ipr.get_links())[0]
35 | assert lvalue is not rvalue
36 | assert lvalue == rvalue
37 |
38 |
39 | def test_nlmsg_compare_not_equal(context):
40 | lvalue = tuple(context.ipr.get_links())[0]
41 | rvalue = tuple(context.ipr.get_links())[1]
42 | assert lvalue is not rvalue
43 | assert lvalue != rvalue
44 |
45 |
46 | def test_nlmsg_compare_int(context):
47 | lvalue = tuple(context.ipr.get_links())[0]
48 | rvalue = 42
49 | assert lvalue is not rvalue
50 | assert lvalue != rvalue
51 |
--------------------------------------------------------------------------------
/tests/test_linux/test_tc/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/test_linux/test_tc/__init__.py
--------------------------------------------------------------------------------
/tests/test_linux/test_wireguard/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/svinota/pyroute2/1be9a52f5d9144321158f9202d686fcac3a26028/tests/test_linux/test_wireguard/__init__.py
--------------------------------------------------------------------------------
/tests/test_minimal/test_iproute.py:
--------------------------------------------------------------------------------
1 | import getpass
2 |
3 | import pytest
4 |
5 | from pyroute2 import IPRoute
6 | from pyroute2.common import uifname
7 | from pyroute2.netlink import nlmsg
8 |
9 | pytestmark = [
10 | pytest.mark.skipif(getpass.getuser() != 'root', reason='no root access')
11 | ]
12 |
13 |
14 | @pytest.fixture
15 | def ipr():
16 | iproute = IPRoute()
17 | iproute.default_ifname = uifname()
18 | yield iproute
19 | index = iproute.link_lookup(ifname=iproute.default_ifname)
20 | if index:
21 | iproute.link('del', index=index)
22 | iproute.close()
23 |
24 |
25 | def test_dump(ipr):
26 | assert all([isinstance(message, nlmsg) for message in ipr.dump()])
27 |
28 |
29 | def test_tuntap(ipr):
30 | ipr.link('add', ifname=ipr.default_ifname, kind='tuntap', mode='tun')
31 | ipr.poll(
32 | ipr.link, 'dump', timeout=5, ifname=ipr.default_ifname, kind='tun'
33 | )
34 |
35 |
36 | def test_bridge(ipr):
37 | ipr.link('add', ifname=ipr.default_ifname, kind='bridge')
38 | interface = ipr.poll(
39 | ipr.link,
40 | 'dump',
41 | timeout=5,
42 | ifname=ipr.default_ifname,
43 | kind='bridge',
44 | br_stp_state=0,
45 | )[0]
46 | ipr.link('set', index=interface['index'], kind='bridge', br_stp_state=1)
47 | ipr.poll(
48 | ipr.link,
49 | 'dump',
50 | timeout=5,
51 | index=interface['index'],
52 | kind='bridge',
53 | br_stp_state=1,
54 | )
55 |
--------------------------------------------------------------------------------
/tests/test_neutron/test_ip_lib.py:
--------------------------------------------------------------------------------
1 | from inspect import signature
2 |
3 | import eventlet
4 | import pytest
5 |
6 | import pyroute2
7 | from pyroute2 import netlink, netns
8 | from pyroute2.config.eventlet import eventlet_config
9 | from pyroute2.netlink import exceptions, rtnl
10 | from pyroute2.netlink.rtnl import ifinfmsg, ndmsg
11 |
12 | eventlet.monkey_patch()
13 | eventlet_config()
14 |
15 |
16 | def parameters(func):
17 | try:
18 | return set(signature(func).parameters.keys())
19 | except ValueError:
20 | pytest.skip('ginature check error, skip test')
21 |
22 |
23 | def test_imports():
24 | assert parameters(pyroute2.NetNS) > set(('netns', 'flags', 'libc'))
25 | assert signature(pyroute2.IPRoute)
26 | assert issubclass(netlink.NetlinkError, Exception)
27 | assert issubclass(exceptions.NetlinkDumpInterrupted, Exception)
28 | assert netlink.NetlinkError == exceptions.NetlinkError
29 | assert netlink.nla_slot
30 | assert netlink.nla_base
31 | assert parameters(rtnl.rt_scope.get) == set(('key', 'default'))
32 | assert isinstance(rtnl.rt_proto, dict) and 'static' in rtnl.rt_proto
33 | assert parameters(netns._create) == set(('netns', 'libc', 'pid'))
34 | assert parameters(netns.listnetns) == set(('nspath',))
35 | assert ifinfmsg.IFF_ALLMULTI == 0x200
36 | assert {state[1]: state[0] for state in ndmsg.states.items()} == {
37 | 0: 'none',
38 | 1: 'incomplete',
39 | 2: 'reachable',
40 | 4: 'stale',
41 | 8: 'delay',
42 | 16: 'probe',
43 | 32: 'failed',
44 | 64: 'noarp',
45 | 128: 'permanent',
46 | }
47 |
48 |
49 | def test_dump():
50 | with pyroute2.IPRoute() as ipr:
51 | assert len(tuple(ipr.route('dump'))) > 0
52 | assert len(tuple(ipr.link('dump'))) > 0
53 |
--------------------------------------------------------------------------------
/tests/test_openbsd/conftest.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | from pyroute2 import IPRoute
4 |
5 |
6 | class BasicContextManager:
7 | def __init__(self, request, tmpdir):
8 | self.ipr = IPRoute()
9 |
10 | def teardown(self):
11 | self.ipr.close()
12 |
13 |
14 | @pytest.fixture
15 | def context(request, tmpdir):
16 | ctx = BasicContextManager(request, tmpdir)
17 | yield ctx
18 | ctx.teardown()
19 |
--------------------------------------------------------------------------------
/tests/test_openbsd/test_ipr/test_basic.py:
--------------------------------------------------------------------------------
1 | from pyroute2.common import get_address_family
2 | from pyroute2.netlink.rtnl import (
3 | RTM_NEWADDR,
4 | RTM_NEWLINK,
5 | RTM_NEWNEIGH,
6 | RTM_NEWROUTE,
7 | )
8 |
9 |
10 | def test_get_links(context):
11 | for msg in context.ipr.get_links():
12 | assert msg['header']['target'] == 'localhost'
13 | assert msg['header']['type'] == RTM_NEWLINK
14 | #
15 | assert msg['index'] > 0
16 | ifname = msg.get_attr('IFLA_IFNAME')
17 | assert isinstance(ifname, str)
18 |
19 |
20 | def test_get_addr(context):
21 | for msg in context.ipr.get_addr():
22 | assert msg['header']['target'] == 'localhost'
23 | assert msg['header']['type'] == RTM_NEWADDR
24 | #
25 | addr = msg.get_attr('IFA_ADDRESS')
26 | assert isinstance(addr, str)
27 | assert msg['family'] == get_address_family(addr)
28 | assert 0 <= msg['prefixlen'] <= 128
29 |
30 |
31 | def test_get_routes(context):
32 | for msg in context.ipr.get_routes():
33 | assert msg['header']['target'] == 'localhost'
34 | assert msg['header']['type'] == RTM_NEWROUTE
35 |
36 |
37 | def test_get_neighbours(context):
38 | for msg in context.ipr.get_neighbours():
39 | assert msg['header']['target'] == 'localhost'
40 | assert msg['header']['type'] == RTM_NEWNEIGH
41 | #
42 | dst = msg.get_attr('NDA_DST')
43 | lladdr = msg.get_attr('NDA_LLADDR')
44 | assert msg['family'] == get_address_family(dst)
45 | assert isinstance(lladdr, str)
46 | assert len(lladdr.split(':')) == 6
47 |
--------------------------------------------------------------------------------
/tests/test_process/test_catastrophe.py:
--------------------------------------------------------------------------------
1 | import os
2 | import time
3 | from signal import SIGKILL, SIGTERM
4 |
5 | import pytest
6 |
7 | from pyroute2.process import ChildProcess
8 |
9 |
10 | def child_process_timeout(x):
11 | time.sleep(x)
12 |
13 |
14 | def child_process_die(x):
15 | os.kill(os.getpid(), x)
16 |
17 |
18 | @pytest.mark.parametrize(
19 | 'func,argv,catch,kill,exitcode',
20 | (
21 | (child_process_timeout, [1], TimeoutError, None, -SIGKILL),
22 | (child_process_timeout, [7], TimeoutError, None, -SIGKILL),
23 | (child_process_timeout, [23], TimeoutError, None, -SIGKILL),
24 | (child_process_die, [SIGTERM], RuntimeError, None, -SIGTERM),
25 | (child_process_die, [SIGKILL], RuntimeError, None, -SIGKILL),
26 | (child_process_timeout, [30], RuntimeError, SIGTERM, -SIGTERM),
27 | (child_process_timeout, [30], RuntimeError, SIGKILL, -SIGKILL),
28 | ),
29 | ids=[
30 | 'timeout-1',
31 | 'timeout-7',
32 | 'timeout-23',
33 | 'die-SIGTERM',
34 | 'die-SIGKILL',
35 | 'kill-SIGTERM',
36 | 'kill-SIGKILL',
37 | ],
38 | )
39 | def test_child_fail(func, argv, catch, kill, exitcode):
40 | cp = ChildProcess(func, argv)
41 | ts_start = time.time()
42 | with pytest.raises(catch):
43 | cp.run()
44 | if kill is not None:
45 | os.kill(cp.pid, kill)
46 | cp.communicate(timeout=0.1)
47 | assert time.time() - ts_start < 1
48 | assert cp.exitcode == exitcode
49 | cp.close()
50 |
--------------------------------------------------------------------------------
/tests/test_repo/test_minimal.py:
--------------------------------------------------------------------------------
1 | import pyroute2
2 | from pyroute2 import minimal
3 |
4 |
5 | def test_modules():
6 | assert set(minimal.__all__) < set(pyroute2.__all__)
7 |
--------------------------------------------------------------------------------
/tests/test_repo/test_version.py:
--------------------------------------------------------------------------------
1 | import io
2 | import re
3 |
4 | import pytest
5 | from packaging.version import InvalidVersion, Version
6 |
7 |
8 | @pytest.fixture
9 | def files():
10 | context = {}
11 | for file in ('VERSION', 'CHANGELOG.rst'):
12 | with open(file, 'r') as f:
13 | obj = io.StringIO()
14 | obj.write(f.read())
15 | obj.seek(0)
16 | context[file] = obj
17 | yield context
18 |
19 |
20 | def test_static_version_file(files):
21 | assert re.match(
22 | r'^[0-9]\.[0-9]\.[0-9]{1,2}(a[0-9]+|b[0-9]+|rc[0-9]+){0,1}$',
23 | files['VERSION'].getvalue().strip(),
24 | )
25 |
26 |
27 | def test_changelog(files):
28 | line = ''
29 | for line in files['CHANGELOG.rst'].readlines():
30 | if line[0] == '*':
31 | break
32 |
33 | try:
34 | static_version = Version(files['VERSION'].getvalue().strip())
35 | last_changelog_version = Version(line.split()[1])
36 | except InvalidVersion as e:
37 | pytest.fail(f"Invalid version encountered: {e}")
38 |
39 | assert static_version >= last_changelog_version
40 |
--------------------------------------------------------------------------------
/tests/test_unit/test_addr_pool.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | from pyroute2.common import AddrPool
4 |
5 |
6 | def test_alloc_aligned():
7 | ap = AddrPool(minaddr=1, maxaddr=1024)
8 | for i in range(1024):
9 | ap.alloc()
10 | with pytest.raises(KeyError):
11 | ap.alloc()
12 |
13 |
14 | def test_alloc_odd():
15 | ap = AddrPool(minaddr=1, maxaddr=1020)
16 | for i in range(1020):
17 | ap.alloc()
18 | with pytest.raises(KeyError):
19 | ap.alloc()
20 |
21 |
22 | def test_reverse():
23 | ap = AddrPool(minaddr=1, maxaddr=1024, reverse=True)
24 | for i in range(512):
25 | assert ap.alloc() > ap.alloc()
26 |
27 |
28 | def test_free():
29 | ap = AddrPool(minaddr=1, maxaddr=1024)
30 | f = ap.alloc()
31 | ap.free(f)
32 |
33 |
34 | def test_free_fail():
35 | ap = AddrPool(minaddr=1, maxaddr=1024)
36 | with pytest.raises(KeyError):
37 | ap.free(0)
38 |
39 |
40 | def test_free_reverse_fail():
41 | ap = AddrPool(minaddr=1, maxaddr=1024, reverse=True)
42 | with pytest.raises(KeyError):
43 | ap.free(0)
44 |
45 |
46 | def test_locate():
47 | ap = AddrPool()
48 | f = ap.alloc()
49 | base1, bit1, is_allocated1 = ap.locate(f)
50 | base2, bit2, is_allocated2 = ap.locate(f + 1)
51 | assert base1 == base2
52 | assert bit2 == bit1 + 1
53 | assert is_allocated1
54 | assert not is_allocated2
55 |
--------------------------------------------------------------------------------
/tests/test_unit/test_config.py:
--------------------------------------------------------------------------------
1 | from pyroute2 import config
2 |
3 |
4 | def test_kernel_version():
5 | versions = {
6 | '1.2.3-test01': [1, 2, 3],
7 | '1.2.3.test01': [1, 2, 3],
8 | '10.1.12': [10, 1, 12],
9 | 'test.10.12': [],
10 | '2.10.test01': [2, 10],
11 | '5.16.5-200.fc35.x86_64': [5, 16, 5],
12 | '5.15.15.debug': [5, 15, 15],
13 | }
14 |
15 | for key, value in versions.items():
16 | assert config.parse_kernel_version(key) == value
17 |
--------------------------------------------------------------------------------
/tests/test_unit/test_entry_points/test_basic.py:
--------------------------------------------------------------------------------
1 | from pyroute2 import IPRoute
2 | from pyroute2 import NetlinkError as E1
3 | from pyroute2.netlink import NetlinkError as E2
4 | from pyroute2.netlink.exceptions import NetlinkError as E3
5 |
6 |
7 | def test_exceptions():
8 | assert E1 == E2 == E3
9 | with IPRoute() as ipr:
10 | for e in (E1, E2, E3):
11 | try:
12 | ipr.get_links(-1)
13 | except e:
14 | pass
15 |
--------------------------------------------------------------------------------
/tests/test_unit/test_nlmsg/addrmsg_ipv4.dump:
--------------------------------------------------------------------------------
1 | # pyroute2 hex dump sample
2 | #
3 | # lo: 127.0.0.1/8
4 | 4c:00:00:00:14:00:02:00:02:01:00:00:c5:4e:00:00:02:08:80:fe:01:00:00:00:08:00:01:00:7f:00:00:01:08:00:02:00:7f:00:00:01:07:00:03:00:6c:6f:00:00:08:00:08:00:80:00:00:00:14:00:06:00:ff:ff:ff:ff:ff:ff:ff:ff:05:01:00:00:05:01:00:00
5 |
6 | # parsed data should match messages below
7 | #: application/json
8 | [
9 | {
10 | "attrs": [
11 | [
12 | "IFA_ADDRESS",
13 | "127.0.0.1"
14 | ],
15 | [
16 | "IFA_LOCAL",
17 | "127.0.0.1"
18 | ],
19 | [
20 | "IFA_LABEL",
21 | "lo"
22 | ],
23 | [
24 | "IFA_FLAGS",
25 | 128
26 | ],
27 | [
28 | "IFA_CACHEINFO",
29 | {
30 | "cstamp": 261,
31 | "ifa_preferred": 4294967295,
32 | "ifa_valid": 4294967295,
33 | "tstamp": 261
34 | }
35 | ]
36 | ],
37 | "event": "RTM_NEWADDR",
38 | "family": 2,
39 | "flags": 128,
40 | "header": {
41 | "error": null,
42 | "flags": 2,
43 | "length": 76,
44 | "pid": 20165,
45 | "sequence_number": 258,
46 | "type": 20
47 | },
48 | "index": 1,
49 | "prefixlen": 8,
50 | "scope": 254
51 | }
52 | ]
53 |
--------------------------------------------------------------------------------
/tests/test_unit/test_nlmsg/iw_info_rsp.dump:
--------------------------------------------------------------------------------
1 | \x58\x00\x00\x00\x1b\x00\x00\x00\x32\xfa\xdd\x54\xf2\x7b\x00\x2e\x07\x01\x00\x00\x08\x00\x03\x00\x03\x00\x00\x00\x09\x00\x04\x00\x77\x6c\x6f\x31\x00\x00\x00\x00\x08\x00\x01\x00\x00\x00\x00\x00\x08\x00\x05\x00\x02\x00\x00\x00\x0c\x00\x99\x00\x01\x00\x00\x00\x00\x00\x00\x00\x0a\x00\x06\x00\xa4\x4e\x31\x43\x1c\x7d\x00\x00\x08\x00\x2e\x00\x05\x00\x00\x00
2 |
3 | # parsed data should match primes below
4 | #: application/json
5 | [
6 | {
7 | "attrs": [
8 | [
9 | "NL80211_ATTR_IFINDEX",
10 | 3
11 | ],
12 | [
13 | "NL80211_ATTR_IFNAME",
14 | "wlo1"
15 | ],
16 | [
17 | "NL80211_ATTR_WIPHY",
18 | 0
19 | ],
20 | [
21 | "NL80211_ATTR_IFTYPE",
22 | 2
23 | ],
24 | [
25 | "NL80211_ATTR_WDEV",
26 | 1
27 | ],
28 | [
29 | "NL80211_ATTR_MAC",
30 | "a4:4e:31:43:1c:7d"
31 | ],
32 | [
33 | "NL80211_ATTR_GENERATION",
34 | 5
35 | ]
36 | ],
37 | "cmd": 7,
38 | "event": "NL80211_CMD_NEW_INTERFACE",
39 | "header": {
40 | "error": null,
41 | "flags": 0,
42 | "length": 88,
43 | "pid": 771783666,
44 | "sequence_number": 1423833650,
45 | "type": 27
46 | },
47 | "reserved": 0,
48 | "version": 1
49 | }
50 | ]
51 |
--------------------------------------------------------------------------------
/tests/test_unit/test_nlmsg/test_attr.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | from pyroute2.netlink import nlmsg
4 |
5 | prime = {
6 | 'attrs': (
7 | ('A', 2),
8 | ('A', 3),
9 | ('A', 4),
10 | ('B', {'attrs': (('C', 5), ('D', {'attrs': (('E', 6), ('F', 7))}))}),
11 | )
12 | }
13 |
14 |
15 | @pytest.fixture
16 | def msg():
17 | msg = nlmsg()
18 | msg.setvalue(prime)
19 | yield msg
20 |
21 |
22 | def test_get_attr(msg):
23 | assert msg.get_attr('A') == 2
24 | assert msg.get_attr('C') is None
25 |
26 |
27 | def test_get_attrs(msg):
28 | assert msg.get_attrs('A') == [2, 3, 4]
29 | assert msg.get_attrs('C') == []
30 |
31 |
32 | def test_get_nested(msg):
33 | assert msg.get_nested('B', 'D', 'E') == 6
34 | assert msg.get_nested('B', 'D', 'F') == 7
35 | assert msg.get_nested('B', 'D', 'G') is None
36 | assert msg.get_nested('C', 'D', 'E') is None
37 |
--------------------------------------------------------------------------------
/tests/test_unit/test_nlmsg/uevent_udevd_backlight.dump:
--------------------------------------------------------------------------------
1 | # sample
2 | 63:68:61:6e:67:65:40:2f:64:65:76:69:63:65:73:2f:70:63:69:30:30:30:30:3a:30:30
3 | 2f:30:30:30:30:3a:30:30:3a:30:32:2e:30:2f:64:72:6d:2f:63:61:72:64:30:2f:63:61
4 | 72:64:30:2d:65:44:50:2d:31:2f:69:6e:74:65:6c:5f:62:61:63:6b:6c:69:67:68:74:00
5 | 41:43:54:49:4f:4e:3d:63:68:61:6e:67:65:00:44:45:56:50:41:54:48:3d:2f:64:65:76
6 | 69:63:65:73:2f:70:63:69:30:30:30:30:3a:30:30:2f:30:30:30:30:3a:30:30:3a:30:32
7 | 2e:30:2f:64:72:6d:2f:63:61:72:64:30:2f:63:61:72:64:30:2d:65:44:50:2d:31:2f:69
8 | 6e:74:65:6c:5f:62:61:63:6b:6c:69:67:68:74:00:53:55:42:53:59:53:54:45:4d:3d:62
9 | 61:63:6b:6c:69:67:68:74:00:53:4f:55:52:43:45:3d:73:79:73:66:73:00:53:45:51:4e
10 | 55:4d:3d:31:39:33:37:32:00
11 |
12 | # parsed data should match primes below
13 | #: application/x-python-code
14 | (
15 | {
16 | 'attrs': [],
17 | 'header': {
18 | 'sequence_number': 0,
19 | 'message': 'change@/devices/pci0000:00/0000:00:02.0/drm/card0/card0-eDP-1/intel_backlight',
20 | 'unparsed': b''
21 | },
22 | 'ACTION': 'change',
23 | 'DEVPATH': '/devices/pci0000:00/0000:00:02.0/drm/card0/card0-eDP-1/intel_backlight',
24 | 'SUBSYSTEM': 'backlight',
25 | 'SOURCE': 'sysfs',
26 | 'SEQNUM': '19372'
27 | },
28 | )
29 |
--------------------------------------------------------------------------------
/tests/test_unit/test_requests/common.py:
--------------------------------------------------------------------------------
1 | from pyroute2.requests.main import RequestProcessor
2 |
3 |
4 | class Request(dict):
5 | pass
6 |
7 |
8 | class Result(dict):
9 | pass
10 |
11 |
12 | def run_test(config, spec, result):
13 | processor = RequestProcessor(context=spec, prime=spec)
14 | for fspec in config['filters']:
15 | processor.add_filter(fspec['class'](*fspec['argv']))
16 | processor.finalize()
17 | assert Result(processor) == result
18 |
--------------------------------------------------------------------------------
/tests/test_windows/test_ipr.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | from pyroute2 import IPRoute
4 |
5 |
6 | @pytest.fixture
7 | def ipr():
8 | with IPRoute() as iproute:
9 | yield iproute
10 |
11 |
12 | @pytest.mark.parametrize('variant', ('links', 'addr', 'neighbours', 'routes'))
13 | def test_list(ipr, variant):
14 | for msg in getattr(ipr, f'get_{variant}')():
15 | assert msg['header']['target'] == 'localhost'
16 | assert msg['header']['type'] % 2 == 0
17 |
--------------------------------------------------------------------------------
/util/aafigure_mapper.py:
--------------------------------------------------------------------------------
1 | import contextlib
2 | import io
3 | import sys
4 |
5 | ret = io.StringIO()
6 |
7 | with contextlib.ExitStack() as ctx:
8 | map_file = ctx.enter_context(open(sys.argv[1], 'r'))
9 | img_file = ctx.enter_context(open(sys.argv[2], 'r'))
10 |
11 | mapping = {
12 | key.strip(): value.strip()
13 | for (key, value) in [x.split('|') for x in map_file.readlines()]
14 | }
15 | for line in img_file.readlines():
16 | if 'a href' not in line:
17 | for key, value in mapping.items():
18 | line = line.replace(key, f' {key}')
19 | ret.write(line)
20 |
21 | with open(sys.argv[2], 'w') as img_file:
22 | img_file.write(ret.getvalue())
23 |
--------------------------------------------------------------------------------
/util/aafigure_mapper.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | find docs \
4 | -name 'aafig-*svg' \
5 | -exec python util/aafigure_mapper.py docs/aafigure.map '{}' \;
6 |
--------------------------------------------------------------------------------
/util/find_python.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | #
4 | # Utility to find Python
5 | #
6 |
7 | function list_pythons() {
8 | #
9 | # List all python binaries/shims/links in a directory $1
10 | #
11 | ls -1 $1/python* 2>/dev/null | grep -E 'python[0-9.]+$'
12 | }
13 |
14 | function check_valid_python() {
15 | #
16 | # Return "$VERSION $1" for $1 if it returns a valid version string
17 | # and has the required modules: ensurepip
18 | #
19 | # Note on versions: X.Y.Z... => XY, e.g.:
20 | # 3.6.10 -> 36
21 | # 3.10.1b1 -> 310
22 | #
23 | # This is required to sort versions correctly. The last version
24 | # byte is ignored.
25 | #
26 | for MODULE in ensurepip sqlite3; do
27 | $1 -c "import $MODULE" >/dev/null 2>&1 || return
28 | done
29 | VERSION=$( $1 -V 2>/dev/null |\
30 | grep -E '^Python [0-9a-z.]+$' |\
31 | sed 's/Python \([3-9]\.[0-9]\+\).*$/\1/;s/\.//' )
32 | if [ ! -z "$VERSION" ]; then
33 | echo $VERSION $1
34 | fi
35 | }
36 |
37 | function list_valid_pythons() {
38 | #
39 | # Filter only valid Pythons in a directory $1, ignoring pyenv shims
40 | # not pointing to an installed Python binary.
41 | #
42 | for PYTHON in $( list_pythons $1 ); do
43 | PYTHON=$( check_valid_python $PYTHON )
44 | if [ ! -z "$PYTHON" ]; then
45 | echo $PYTHON
46 | fi
47 | done
48 | }
49 |
50 | function iterate_path() {
51 | #
52 | # Iterate dirs in the $PATH variable, sorting Python versions
53 | # within each directory.
54 | #
55 | for DIR in $( echo $PATH | sed 's/:/ /g' ); do
56 | list_valid_pythons $DIR | sort -r -n
57 | done
58 | }
59 |
60 | #
61 | # Take the first available Python with the highest version, respecting
62 | # the $PATH variable.
63 | #
64 | # If operating in a venv, it will return the venv Python, despite the
65 | # higher version may be available in the system directories.
66 | #
67 | iterate_path | head -1 | cut -d \ -f 2
68 |
--------------------------------------------------------------------------------
/util/imports_dict.awk:
--------------------------------------------------------------------------------
1 | /^[[:space:]]+pr2modules/ {
2 | next
3 | }
4 |
5 | /^[[:space:]]+[[:alpha:]]/ {
6 | deps[$1][key]++
7 | }
8 |
9 | /^[[:alpha:]]+/ {
10 | key = gensub(":", "", "g", $1)
11 | }
12 |
13 | END {
14 | for (i in deps) {
15 | print(i);
16 | for (k in deps[i]) {
17 | print("\t"k);
18 | };
19 | };
20 | }
21 |
--------------------------------------------------------------------------------
/util/update_version.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import subprocess
3 | from pathlib import Path
4 |
5 | version_module = "pyroute2/config/version.py"
6 | version_output_file = "VERSION"
7 | version_input_file = "VERSION"
8 |
9 |
10 | def get_project_version():
11 | """
12 | Get the project version
13 |
14 | 1. fetch version from git
15 | 2. if not available, fallback to the version file in the repo
16 | """
17 | version = None
18 |
19 | try:
20 | git_top_level = Path(
21 | subprocess.check_output(
22 | ("git", "rev-parse", "--show-toplevel"),
23 | stderr=subprocess.DEVNULL,
24 | )
25 | .decode("utf-8")
26 | .strip()
27 | )
28 | pyroute2_top_level = Path(__file__).parent.parent.absolute()
29 | # Only retrieve the git description from the pyroute2 directory
30 | if git_top_level == pyroute2_top_level:
31 | version = subprocess.check_output(
32 | ("git", "describe"), stderr=subprocess.DEVNULL
33 | ).decode("utf-8")
34 | except (FileNotFoundError, subprocess.CalledProcessError):
35 | pass
36 |
37 | if version is None:
38 | with open(version_input_file, "r") as f:
39 | version = f.read()
40 |
41 | version = version.strip().split("-")
42 |
43 | if len(version) > 1:
44 | version = "{version[0]}.post{version[1]}".format(**locals())
45 | else:
46 | version = version[0]
47 | return version
48 |
49 |
50 | if __name__ == "__main__":
51 | version = get_project_version()
52 | with open(version_module, "w") as f:
53 | f.write('__version__ = "%s"\n' % version)
54 | with open(version_output_file, "w") as f:
55 | f.write("%s\n" % version)
56 |
--------------------------------------------------------------------------------