1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
//! `net_shaper` Generic Netlink family — TX hardware shaping.
//!
//! The `net_shaper` family (kernel 6.13+) is a generic interface
//! to per-NIC, per-queue, and intermediate-node TX hardware
//! shapers — drivers like Intel `ice`, Mellanox `mlx5`, and
//! Broadcom `bnxt` expose their hierarchical scheduler trees
//! through it. Operators get a uniform way to set guaranteed /
//! peak bandwidth, burst size, scheduling priority, and RR
//! weights without leaving netlink for ethtool, devlink, or
//! driver-private ioctls.
//!
//! Second in-tree user of [`nlink-macros`] (after
//! [`super::dpll`]). The full family — 5 commands, 10 outer
//! attrs, 10 cap-set attrs, 2 nested handle attrs, 2 enums —
//! declares in ~200 lines of macro-derived Rust.
//!
//! [`nlink-macros`]: crate::macros
//!
//! # Construction
//!
//! ```no_run
//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
//! use nlink::netlink::{Connection, genl::net_shaper::NetShaper};
//!
//! let conn = Connection::<NetShaper>::new_async().await?;
//! // Family ID resolved against the kernel's "net-shaper"
//! // registration; `Error::is_not_found()` when the family
//! // isn't loaded (kernel < 6.13 or `CONFIG_NET_SHAPER=n`).
//! # Ok(())
//! # }
//! ```
//!
//! # Capability handshake
//!
//! Drivers expose different feature subsets — always query caps
//! before issuing a `set_shaper` to avoid the round-trip on
//! unsupported attributes:
//!
//! ```no_run
//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
//! # let eth0_ifindex: u32 = 2;
//! # let conn = nlink::Connection::<nlink::netlink::genl::net_shaper::NetShaper>::new_async().await?;
//! use nlink::netlink::genl::net_shaper::{
//! NetShaper, NetShaperHandle, NetShaperScope, NetShaperSetRequest,
//! };
//!
//! let caps = conn.get_caps(eth0_ifindex, NetShaperScope::Queue).await?;
//! if caps.support_bw_max {
//! let handle = NetShaperHandle::queue(0);
//! conn.set_shaper(NetShaperSetRequest::new(eth0_ifindex, handle).bw_max(1_000_000_000))
//! .await?;
//! } else {
//! tracing::warn!("driver doesn't support bw_max on QUEUE scope");
//! }
//! # Ok(())
//! # }
//! ```
//!
//! # Permissions
//!
//! `set`, `delete`, and `group` require `CAP_NET_ADMIN`.
//! `get` and `cap-get` are unprivileged.
//!
//! # Status
//!
//! Plan 153 §4.3. Shipped:
//!
//! | Command | Status |
//! |---|---|
//! | `NET_SHAPER_CMD_GET` (get + dump) | ✓ |
//! | `NET_SHAPER_CMD_SET` | ✓ |
//! | `NET_SHAPER_CMD_DELETE` | ✓ |
//! | `NET_SHAPER_CMD_CAP_GET` (get + dump) | ✓ |
//! | `NET_SHAPER_CMD_GROUP` | — (needs `Vec<NetlinkAttrs>` macro support; deferred) |
use crategenl_family;
pub use ;
pub use ;
/// `net_shaper` Generic Netlink family marker.
///
/// Constructed via [`Connection::<NetShaper>::new_async()`][Connection]
/// — the family ID is resolved against the kernel at connection
/// time. Returns
/// [`Error::FamilyNotFound`](crate::Error::FamilyNotFound) on
/// kernels without `CONFIG_NET_SHAPER` (the family is built-in
/// when the option is set; there's no separate module to load).
///
/// [Connection]: crate::netlink::Connection
;