#![doc = "Netlink raw family for tc qdisc, chain, class and filter configuration\nover rtnetlink.\n"]
#![allow(clippy::all)]
#![allow(unused_imports)]
#![allow(unused_assignments)]
#![allow(non_snake_case)]
#![allow(unused_variables)]
#![allow(irrefutable_let_patterns)]
#![allow(unreachable_code)]
#![allow(unreachable_patterns)]
#[cfg(test)]
mod tests;
use crate::builtin::{BuiltinBitfield32, BuiltinNfgenmsg, Nlmsghdr, PushDummy};
use crate::{
consts,
traits::{NetlinkRequest, Protocol},
utils::*,
};
pub const PROTONAME: &str = "tc";
pub const PROTONAME_CSTR: &CStr = c"tc";
pub const PROTONUM: u16 = 0u16;
#[doc = "Flags - defines an integer enumeration, with values for each entry occupying a bit, starting from bit 0, (e.g. 1, 2, 4, 8)"]
#[derive(Debug, Clone, Copy)]
pub enum ClsFlags {
SkipHw = 1 << 0,
SkipSw = 1 << 1,
InHw = 1 << 2,
NotInNw = 1 << 3,
Verbose = 1 << 4,
}
impl ClsFlags {
pub fn from_value(value: u64) -> Option<Self> {
Some(match value {
n if n == 1 << 0 => Self::SkipHw,
n if n == 1 << 1 => Self::SkipSw,
n if n == 1 << 2 => Self::InHw,
n if n == 1 << 3 => Self::NotInNw,
n if n == 1 << 4 => Self::Verbose,
_ => return None,
})
}
}
#[doc = "Flags - defines an integer enumeration, with values for each entry occupying a bit, starting from bit 0, (e.g. 1, 2, 4, 8)"]
#[derive(Debug, Clone, Copy)]
pub enum FlowerKeyCtrlFlags {
Frag = 1 << 0,
Firstfrag = 1 << 1,
Tuncsum = 1 << 2,
Tundf = 1 << 3,
Tunoam = 1 << 4,
Tuncrit = 1 << 5,
}
impl FlowerKeyCtrlFlags {
pub fn from_value(value: u64) -> Option<Self> {
Some(match value {
n if n == 1 << 0 => Self::Frag,
n if n == 1 << 1 => Self::Firstfrag,
n if n == 1 << 2 => Self::Tuncsum,
n if n == 1 << 3 => Self::Tundf,
n if n == 1 << 4 => Self::Tunoam,
n if n == 1 << 5 => Self::Tuncrit,
_ => return None,
})
}
}
#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
#[derive(Debug, Clone, Copy)]
pub enum Dualpi2DropOverload {
Overflow = 0,
Drop = 1,
}
impl Dualpi2DropOverload {
pub fn from_value(value: u64) -> Option<Self> {
Some(match value {
0 => Self::Overflow,
1 => Self::Drop,
_ => return None,
})
}
}
#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
#[derive(Debug, Clone, Copy)]
pub enum Dualpi2DropEarly {
DropDequeue = 0,
DropEnqueue = 1,
}
impl Dualpi2DropEarly {
pub fn from_value(value: u64) -> Option<Self> {
Some(match value {
0 => Self::DropDequeue,
1 => Self::DropEnqueue,
_ => return None,
})
}
}
#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
#[derive(Debug, Clone, Copy)]
pub enum Dualpi2EcnMask {
L4sEct = 1,
ClaEct = 2,
AnyEct = 3,
}
impl Dualpi2EcnMask {
pub fn from_value(value: u64) -> Option<Self> {
Some(match value {
1 => Self::L4sEct,
2 => Self::ClaEct,
3 => Self::AnyEct,
_ => return None,
})
}
}
#[doc = "Enum - defines an integer enumeration, with values for each entry incrementing by 1, (e.g. 0, 1, 2, 3)"]
#[derive(Debug, Clone, Copy)]
pub enum Dualpi2SplitGso {
NoSplitGso = 0,
SplitGso = 1,
}
impl Dualpi2SplitGso {
pub fn from_value(value: u64) -> Option<Self> {
Some(match value {
0 => Self::NoSplitGso,
1 => Self::SplitGso,
_ => return None,
})
}
}
#[repr(C, packed(4))]
pub struct Tcmsg {
pub family: u8,
pub _pad: [u8; 3usize],
pub ifindex: i32,
pub handle: u32,
pub parent: u32,
pub info: u32,
}
impl Clone for Tcmsg {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for Tcmsg {
fn default() -> Self {
Self::new()
}
}
impl Tcmsg {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 20usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 20usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 20usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 20usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<Tcmsg>() == 20usize);
20usize
}
}
impl std::fmt::Debug for Tcmsg {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fmt.debug_struct("Tcmsg")
.field("family", &self.family)
.field("ifindex", &self.ifindex)
.field("handle", &self.handle)
.field("parent", &self.parent)
.field("info", &self.info)
.finish()
}
}
#[repr(C, packed(4))]
pub struct TcStats {
#[doc = "Number of enqueued bytes\n"]
pub bytes: u64,
#[doc = "Number of enqueued packets\n"]
pub packets: u32,
#[doc = "Packets dropped because of lack of resources\n"]
pub drops: u32,
#[doc = "Number of throttle events when this flow goes out of allocated bandwidth\n"]
pub overlimits: u32,
#[doc = "Current flow byte rate\n"]
pub bps: u32,
#[doc = "Current flow packet rate\n"]
pub pps: u32,
pub qlen: u32,
pub backlog: u32,
pub _pad_36: [u8; 4usize],
}
impl Clone for TcStats {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcStats {
fn default() -> Self {
Self::new()
}
}
impl TcStats {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 40usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 40usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 40usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 40usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcStats>() == 40usize);
40usize
}
}
impl std::fmt::Debug for TcStats {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fmt.debug_struct("TcStats")
.field("bytes", &{ self.bytes })
.field("packets", &self.packets)
.field("drops", &self.drops)
.field("overlimits", &self.overlimits)
.field("bps", &self.bps)
.field("pps", &self.pps)
.field("qlen", &self.qlen)
.field("backlog", &self.backlog)
.finish()
}
}
#[repr(C, packed(4))]
pub struct TcCbsQopt {
pub offload: u8,
pub _pad: [u8; 3usize],
pub hicredit: i32,
pub locredit: i32,
pub idleslope: i32,
pub sendslope: i32,
}
impl Clone for TcCbsQopt {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcCbsQopt {
fn default() -> Self {
Self::new()
}
}
impl TcCbsQopt {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 20usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 20usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 20usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 20usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcCbsQopt>() == 20usize);
20usize
}
}
impl std::fmt::Debug for TcCbsQopt {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fmt.debug_struct("TcCbsQopt")
.field("offload", &self.offload)
.field("hicredit", &self.hicredit)
.field("locredit", &self.locredit)
.field("idleslope", &self.idleslope)
.field("sendslope", &self.sendslope)
.finish()
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcEtfQopt {
pub delta: i32,
pub clockid: i32,
pub flags: i32,
}
impl Clone for TcEtfQopt {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcEtfQopt {
fn default() -> Self {
Self::new()
}
}
impl TcEtfQopt {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 12usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 12usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 12usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 12usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcEtfQopt>() == 12usize);
12usize
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcFifoQopt {
#[doc = "Queue length; bytes for bfifo, packets for pfifo\n"]
pub limit: u32,
}
impl Clone for TcFifoQopt {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcFifoQopt {
fn default() -> Self {
Self::new()
}
}
impl TcFifoQopt {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 4usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 4usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 4usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 4usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcFifoQopt>() == 4usize);
4usize
}
}
#[repr(C, packed(4))]
pub struct TcHtbOpt {
pub rate: TcRatespec,
pub ceil: TcRatespec,
pub buffer: u32,
pub cbuffer: u32,
pub quantum: u32,
pub level: u32,
pub prio: u32,
}
impl Clone for TcHtbOpt {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcHtbOpt {
fn default() -> Self {
Self::new()
}
}
impl TcHtbOpt {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 44usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 44usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 44usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 44usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcHtbOpt>() == 44usize);
44usize
}
}
impl std::fmt::Debug for TcHtbOpt {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fmt.debug_struct("TcHtbOpt")
.field("rate", &self.rate)
.field("ceil", &self.ceil)
.field("buffer", &self.buffer)
.field("cbuffer", &self.cbuffer)
.field("quantum", &self.quantum)
.field("level", &self.level)
.field("prio", &self.prio)
.finish()
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcHtbGlob {
pub version: u32,
#[doc = "bps-\\>quantum divisor\n"]
pub rate2quantum: u32,
#[doc = "Default class number\n"]
pub defcls: u32,
#[doc = "Debug flags\n"]
pub debug: u32,
#[doc = "Count of non shaped packets\n"]
pub direct_pkts: u32,
}
impl Clone for TcHtbGlob {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcHtbGlob {
fn default() -> Self {
Self::new()
}
}
impl TcHtbGlob {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 20usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 20usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 20usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 20usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcHtbGlob>() == 20usize);
20usize
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcGredQopt {
#[doc = "HARD maximal queue length in bytes\n"]
pub limit: u32,
#[doc = "Min average length threshold in bytes\n"]
pub qth_min: u32,
#[doc = "Max average length threshold in bytes\n"]
pub qth_max: u32,
#[doc = "Up to 2\\^32 DPs\n"]
pub DP: u32,
pub backlog: u32,
pub qave: u32,
pub forced: u32,
pub early: u32,
pub other: u32,
pub pdrop: u32,
#[doc = "log(W)\n"]
pub Wlog: u8,
#[doc = "log(P_max / (qth-max - qth-min))\n"]
pub Plog: u8,
#[doc = "cell size for idle damping\n"]
pub Scell_log: u8,
#[doc = "Priority of this VQ\n"]
pub prio: u8,
pub packets: u32,
pub bytesin: u32,
}
impl Clone for TcGredQopt {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcGredQopt {
fn default() -> Self {
Self::new()
}
}
impl TcGredQopt {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 52usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 52usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 52usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 52usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcGredQopt>() == 52usize);
52usize
}
}
#[repr(C, packed(4))]
pub struct TcGredSopt {
pub DPs: u32,
pub def_DP: u32,
pub grio: u8,
pub flags: u8,
pub _pad: [u8; 2usize],
}
impl Clone for TcGredSopt {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcGredSopt {
fn default() -> Self {
Self::new()
}
}
impl TcGredSopt {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 12usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 12usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 12usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 12usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcGredSopt>() == 12usize);
12usize
}
}
impl std::fmt::Debug for TcGredSopt {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fmt.debug_struct("TcGredSopt")
.field("DPs", &self.DPs)
.field("def_DP", &self.def_DP)
.field("grio", &self.grio)
.field("flags", &self.flags)
.finish()
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcHfscQopt {
pub defcls: u16,
}
impl Clone for TcHfscQopt {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcHfscQopt {
fn default() -> Self {
Self::new()
}
}
impl TcHfscQopt {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 2usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 2usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 2usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 2usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcHfscQopt>() == 2usize);
2usize
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcMqprioQopt {
pub num_tc: u8,
pub prio_tc_map: [u8; 16usize],
pub hw: u8,
pub count: [u8; 32usize],
pub offset: [u8; 32usize],
}
impl Clone for TcMqprioQopt {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcMqprioQopt {
fn default() -> Self {
Self::new()
}
}
impl TcMqprioQopt {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 82usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 82usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 82usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 82usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcMqprioQopt>() == 82usize);
82usize
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcMultiqQopt {
#[doc = "Number of bands\n"]
pub bands: u16,
#[doc = "Maximum number of queues\n"]
pub max_bands: u16,
}
impl Clone for TcMultiqQopt {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcMultiqQopt {
fn default() -> Self {
Self::new()
}
}
impl TcMultiqQopt {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 4usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 4usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 4usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 4usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcMultiqQopt>() == 4usize);
4usize
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcNetemQopt {
#[doc = "Added delay in microseconds\n"]
pub latency: u32,
#[doc = "Fifo limit in packets\n"]
pub limit: u32,
#[doc = "Random packet loss (0=none, \\~0=100%)\n"]
pub loss: u32,
#[doc = "Re-ordering gap (0 for none)\n"]
pub gap: u32,
#[doc = "Random packet duplication (0=none, \\~0=100%)\n"]
pub duplicate: u32,
#[doc = "Random jitter latency in microseconds\n"]
pub jitter: u32,
}
impl Clone for TcNetemQopt {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcNetemQopt {
fn default() -> Self {
Self::new()
}
}
impl TcNetemQopt {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 24usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 24usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 24usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 24usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcNetemQopt>() == 24usize);
24usize
}
}
#[derive(Debug)]
#[doc = "State transition probabilities for 4 state model\n"]
#[repr(C, packed(4))]
pub struct TcNetemGimodel {
pub p13: u32,
pub p31: u32,
pub p32: u32,
pub p14: u32,
pub p23: u32,
}
impl Clone for TcNetemGimodel {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcNetemGimodel {
fn default() -> Self {
Self::new()
}
}
impl TcNetemGimodel {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 20usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 20usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 20usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 20usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcNetemGimodel>() == 20usize);
20usize
}
}
#[derive(Debug)]
#[doc = "Gilbert-Elliot models\n"]
#[repr(C, packed(4))]
pub struct TcNetemGemodel {
pub p: u32,
pub r: u32,
pub h: u32,
pub k1: u32,
}
impl Clone for TcNetemGemodel {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcNetemGemodel {
fn default() -> Self {
Self::new()
}
}
impl TcNetemGemodel {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 16usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 16usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 16usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 16usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcNetemGemodel>() == 16usize);
16usize
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcNetemCorr {
#[doc = "Delay correlation\n"]
pub delay_corr: u32,
#[doc = "Packet loss correlation\n"]
pub loss_corr: u32,
#[doc = "Duplicate correlation\n"]
pub dup_corr: u32,
}
impl Clone for TcNetemCorr {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcNetemCorr {
fn default() -> Self {
Self::new()
}
}
impl TcNetemCorr {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 12usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 12usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 12usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 12usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcNetemCorr>() == 12usize);
12usize
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcNetemReorder {
pub probability: u32,
pub correlation: u32,
}
impl Clone for TcNetemReorder {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcNetemReorder {
fn default() -> Self {
Self::new()
}
}
impl TcNetemReorder {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 8usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 8usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 8usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 8usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcNetemReorder>() == 8usize);
8usize
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcNetemCorrupt {
pub probability: u32,
pub correlation: u32,
}
impl Clone for TcNetemCorrupt {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcNetemCorrupt {
fn default() -> Self {
Self::new()
}
}
impl TcNetemCorrupt {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 8usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 8usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 8usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 8usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcNetemCorrupt>() == 8usize);
8usize
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcNetemRate {
pub rate: u32,
pub packet_overhead: i32,
pub cell_size: u32,
pub cell_overhead: i32,
}
impl Clone for TcNetemRate {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcNetemRate {
fn default() -> Self {
Self::new()
}
}
impl TcNetemRate {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 16usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 16usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 16usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 16usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcNetemRate>() == 16usize);
16usize
}
}
#[repr(C, packed(4))]
pub struct TcNetemSlot {
pub min_delay: i64,
pub max_delay: i64,
pub max_packets: i32,
pub max_bytes: i32,
pub dist_delay: i64,
pub dist_jitter: i64,
}
impl Clone for TcNetemSlot {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcNetemSlot {
fn default() -> Self {
Self::new()
}
}
impl TcNetemSlot {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 40usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 40usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 40usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 40usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcNetemSlot>() == 40usize);
40usize
}
}
impl std::fmt::Debug for TcNetemSlot {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fmt.debug_struct("TcNetemSlot")
.field("min_delay", &{ self.min_delay })
.field("max_delay", &{ self.max_delay })
.field("max_packets", &self.max_packets)
.field("max_bytes", &self.max_bytes)
.field("dist_delay", &{ self.dist_delay })
.field("dist_jitter", &{ self.dist_jitter })
.finish()
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcPlugQopt {
pub action: i32,
pub limit: u32,
}
impl Clone for TcPlugQopt {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcPlugQopt {
fn default() -> Self {
Self::new()
}
}
impl TcPlugQopt {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 8usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 8usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 8usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 8usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcPlugQopt>() == 8usize);
8usize
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcPrioQopt {
#[doc = "Number of bands\n"]
pub bands: u32,
#[doc = "Map of logical priority -\\> PRIO band\n"]
pub priomap: [u8; 16usize],
}
impl Clone for TcPrioQopt {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcPrioQopt {
fn default() -> Self {
Self::new()
}
}
impl TcPrioQopt {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 20usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 20usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 20usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 20usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcPrioQopt>() == 20usize);
20usize
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcRedQopt {
#[doc = "Hard queue length in packets\n"]
pub limit: u32,
#[doc = "Min average threshold in packets\n"]
pub qth_min: u32,
#[doc = "Max average threshold in packets\n"]
pub qth_max: u32,
#[doc = "log(W)\n"]
pub Wlog: u8,
#[doc = "log(P_max / (qth-max - qth-min))\n"]
pub Plog: u8,
#[doc = "Cell size for idle damping\n"]
pub Scell_log: u8,
pub flags: u8,
}
impl Clone for TcRedQopt {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcRedQopt {
fn default() -> Self {
Self::new()
}
}
impl TcRedQopt {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 16usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 16usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 16usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 16usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcRedQopt>() == 16usize);
16usize
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcSfbQopt {
pub rehash_interval: u32,
pub warmup_time: u32,
pub max: u32,
pub bin_size: u32,
pub increment: u32,
pub decrement: u32,
pub limit: u32,
pub penalty_rate: u32,
pub penalty_burst: u32,
}
impl Clone for TcSfbQopt {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcSfbQopt {
fn default() -> Self {
Self::new()
}
}
impl TcSfbQopt {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 36usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 36usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 36usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 36usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcSfbQopt>() == 36usize);
36usize
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcSfqQopt {
#[doc = "Bytes per round allocated to flow\n"]
pub quantum: u32,
#[doc = "Period of hash perturbation\n"]
pub perturb_period: i32,
#[doc = "Maximal packets in queue\n"]
pub limit: u32,
#[doc = "Hash divisor\n"]
pub divisor: u32,
#[doc = "Maximal number of flows\n"]
pub flows: u32,
}
impl Clone for TcSfqQopt {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcSfqQopt {
fn default() -> Self {
Self::new()
}
}
impl TcSfqQopt {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 20usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 20usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 20usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 20usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcSfqQopt>() == 20usize);
20usize
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcSfqredStats {
#[doc = "Early drops, below max threshold\n"]
pub prob_drop: u32,
#[doc = "Early drops, after max threshold\n"]
pub forced_drop: u32,
#[doc = "Marked packets, below max threshold\n"]
pub prob_mark: u32,
#[doc = "Marked packets, after max threshold\n"]
pub forced_mark: u32,
#[doc = "Marked packets, below max threshold\n"]
pub prob_mark_head: u32,
#[doc = "Marked packets, after max threshold\n"]
pub forced_mark_head: u32,
}
impl Clone for TcSfqredStats {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcSfqredStats {
fn default() -> Self {
Self::new()
}
}
impl TcSfqredStats {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 24usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 24usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 24usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 24usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcSfqredStats>() == 24usize);
24usize
}
}
#[repr(C, packed(4))]
pub struct TcSfqQoptV1 {
pub v0: TcSfqQopt,
#[doc = "Maximum number of packets per flow\n"]
pub depth: u32,
pub headdrop: u32,
#[doc = "HARD maximal flow queue length in bytes\n"]
pub limit: u32,
#[doc = "Min average length threshold in bytes\n"]
pub qth_min: u32,
#[doc = "Max average length threshold in bytes\n"]
pub qth_max: u32,
#[doc = "log(W)\n"]
pub Wlog: u8,
#[doc = "log(P_max / (qth-max - qth-min))\n"]
pub Plog: u8,
#[doc = "Cell size for idle damping\n"]
pub Scell_log: u8,
pub flags: u8,
#[doc = "probability, high resolution\n"]
pub max_P: u32,
pub stats: TcSfqredStats,
}
impl Clone for TcSfqQoptV1 {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcSfqQoptV1 {
fn default() -> Self {
Self::new()
}
}
impl TcSfqQoptV1 {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 72usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 72usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 72usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 72usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcSfqQoptV1>() == 72usize);
72usize
}
}
impl std::fmt::Debug for TcSfqQoptV1 {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fmt.debug_struct("TcSfqQoptV1")
.field("v0", &self.v0)
.field("depth", &self.depth)
.field("headdrop", &self.headdrop)
.field("limit", &self.limit)
.field("qth_min", &self.qth_min)
.field("qth_max", &self.qth_max)
.field("Wlog", &self.Wlog)
.field("Plog", &self.Plog)
.field("Scell_log", &self.Scell_log)
.field("flags", &self.flags)
.field("max_P", &self.max_P)
.field("stats", &self.stats)
.finish()
}
}
#[repr(C, packed(4))]
pub struct TcRatespec {
pub cell_log: u8,
pub linklayer: u8,
pub overhead: u8,
pub cell_align: u8,
pub mpu: u8,
pub _pad_5: [u8; 3usize],
pub rate: u32,
}
impl Clone for TcRatespec {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcRatespec {
fn default() -> Self {
Self::new()
}
}
impl TcRatespec {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 12usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 12usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 12usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 12usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcRatespec>() == 12usize);
12usize
}
}
impl std::fmt::Debug for TcRatespec {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fmt.debug_struct("TcRatespec")
.field("cell_log", &self.cell_log)
.field("linklayer", &self.linklayer)
.field("overhead", &self.overhead)
.field("cell_align", &self.cell_align)
.field("mpu", &self.mpu)
.field("rate", &self.rate)
.finish()
}
}
#[repr(C, packed(4))]
pub struct TcTbfQopt {
pub rate: TcRatespec,
pub peakrate: TcRatespec,
pub limit: u32,
pub buffer: u32,
pub mtu: u32,
}
impl Clone for TcTbfQopt {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcTbfQopt {
fn default() -> Self {
Self::new()
}
}
impl TcTbfQopt {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 36usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 36usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 36usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 36usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcTbfQopt>() == 36usize);
36usize
}
}
impl std::fmt::Debug for TcTbfQopt {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fmt.debug_struct("TcTbfQopt")
.field("rate", &self.rate)
.field("peakrate", &self.peakrate)
.field("limit", &self.limit)
.field("buffer", &self.buffer)
.field("mtu", &self.mtu)
.finish()
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcSizespec {
pub cell_log: u8,
pub size_log: u8,
pub cell_align: i16,
pub overhead: i32,
pub linklayer: u32,
pub mpu: u32,
pub mtu: u32,
pub tsize: u32,
}
impl Clone for TcSizespec {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcSizespec {
fn default() -> Self {
Self::new()
}
}
impl TcSizespec {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 24usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 24usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 24usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 24usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcSizespec>() == 24usize);
24usize
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct GnetEstimator {
#[doc = "Sampling period\n"]
pub interval: i8,
#[doc = "The log() of measurement window weight\n"]
pub ewma_log: u8,
}
impl Clone for GnetEstimator {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for GnetEstimator {
fn default() -> Self {
Self::new()
}
}
impl GnetEstimator {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 2usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 2usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 2usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 2usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<GnetEstimator>() == 2usize);
2usize
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcChokeXstats {
#[doc = "Early drops\n"]
pub early: u32,
#[doc = "Drops due to queue limits\n"]
pub pdrop: u32,
#[doc = "Drops due to drop() calls\n"]
pub other: u32,
#[doc = "Marked packets\n"]
pub marked: u32,
#[doc = "Drops due to flow match\n"]
pub matched: u32,
}
impl Clone for TcChokeXstats {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcChokeXstats {
fn default() -> Self {
Self::new()
}
}
impl TcChokeXstats {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 20usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 20usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 20usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 20usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcChokeXstats>() == 20usize);
20usize
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcCodelXstats {
#[doc = "Largest packet we\\'ve seen so far\n"]
pub maxpacket: u32,
#[doc = "How many drops we\\'ve done since the last time we entered dropping state\n"]
pub count: u32,
#[doc = "Count at entry to dropping state\n"]
pub lastcount: u32,
#[doc = "in-queue delay seen by most recently dequeued packet\n"]
pub ldelay: u32,
#[doc = "Time to drop next packet\n"]
pub drop_next: i32,
#[doc = "Number of times max qdisc packet limit was hit\n"]
pub drop_overlimit: u32,
#[doc = "Number of packets we\\'ve ECN marked instead of dropped\n"]
pub ecn_mark: u32,
#[doc = "Are we in a dropping state?\n"]
pub dropping: u32,
#[doc = "Number of CE marked packets because of ce-threshold\n"]
pub ce_mark: u32,
}
impl Clone for TcCodelXstats {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcCodelXstats {
fn default() -> Self {
Self::new()
}
}
impl TcCodelXstats {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 36usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 36usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 36usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 36usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcCodelXstats>() == 36usize);
36usize
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcFqCodelXstats {
pub r#type: u32,
#[doc = "Largest packet we\\'ve seen so far\n"]
pub maxpacket: u32,
#[doc = "Number of times max qdisc packet limit was hit\n"]
pub drop_overlimit: u32,
#[doc = "Number of packets we ECN marked instead of being dropped\n"]
pub ecn_mark: u32,
#[doc = "Number of times packets created a new flow\n"]
pub new_flow_count: u32,
#[doc = "Count of flows in new list\n"]
pub new_flows_len: u32,
#[doc = "Count of flows in old list\n"]
pub old_flows_len: u32,
#[doc = "Packets above ce-threshold\n"]
pub ce_mark: u32,
#[doc = "Memory usage in bytes\n"]
pub memory_usage: u32,
pub drop_overmemory: u32,
}
impl Clone for TcFqCodelXstats {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcFqCodelXstats {
fn default() -> Self {
Self::new()
}
}
impl TcFqCodelXstats {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 40usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 40usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 40usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 40usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcFqCodelXstats>() == 40usize);
40usize
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcDualpi2Xstats {
#[doc = "Current base PI probability\n"]
pub prob: u32,
#[doc = "Current C-queue delay in microseconds\n"]
pub delay_c: u32,
#[doc = "Current L-queue delay in microseconds\n"]
pub delay_l: u32,
#[doc = "Number of packets enqueued in the C-queue\n"]
pub pkts_in_c: u32,
#[doc = "Number of packets enqueued in the L-queue\n"]
pub pkts_in_l: u32,
#[doc = "Maximum number of packets seen by the DualPI2\n"]
pub maxq: u32,
#[doc = "All packets marked with ECN\n"]
pub ecn_mark: u32,
#[doc = "Only packets marked with ECN due to L-queue step AQM\n"]
pub step_mark: u32,
#[doc = "Current credit value for WRR\n"]
pub credit: i32,
#[doc = "Memory used in bytes by the DualPI2\n"]
pub memory_used: u32,
#[doc = "Maximum memory used in bytes by the DualPI2\n"]
pub max_memory_used: u32,
#[doc = "Memory limit in bytes\n"]
pub memory_limit: u32,
}
impl Clone for TcDualpi2Xstats {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcDualpi2Xstats {
fn default() -> Self {
Self::new()
}
}
impl TcDualpi2Xstats {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 48usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 48usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 48usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 48usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcDualpi2Xstats>() == 48usize);
48usize
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcFqPieXstats {
#[doc = "Total number of packets enqueued\n"]
pub packets_in: u32,
#[doc = "Packets dropped due to fq_pie_action\n"]
pub dropped: u32,
#[doc = "Dropped due to lack of space in queue\n"]
pub overlimit: u32,
#[doc = "Dropped due to lack of memory in queue\n"]
pub overmemory: u32,
#[doc = "Packets marked with ECN\n"]
pub ecn_mark: u32,
#[doc = "Count of new flows created by packets\n"]
pub new_flow_count: u32,
#[doc = "Count of flows in new list\n"]
pub new_flows_len: u32,
#[doc = "Count of flows in old list\n"]
pub old_flows_len: u32,
#[doc = "Total memory across all queues\n"]
pub memory_usage: u32,
}
impl Clone for TcFqPieXstats {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcFqPieXstats {
fn default() -> Self {
Self::new()
}
}
impl TcFqPieXstats {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 36usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 36usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 36usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 36usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcFqPieXstats>() == 36usize);
36usize
}
}
#[repr(C, packed(4))]
pub struct TcFqQdStats {
pub gc_flows: u64,
#[doc = "obsolete\n"]
pub highprio_packets: u64,
#[doc = "obsolete\n"]
pub tcp_retrans: u64,
pub throttled: u64,
pub flows_plimit: u64,
pub pkts_too_long: u64,
pub allocation_errors: u64,
pub time_next_delayed_flow: i64,
pub flows: u32,
pub inactive_flows: u32,
pub throttled_flows: u32,
pub unthrottle_latency_ns: u32,
#[doc = "Packets above ce-threshold\n"]
pub ce_mark: u64,
pub horizon_drops: u64,
pub horizon_caps: u64,
pub fastpath_packets: u64,
pub band_drops: [u8; 24usize],
pub band_pkt_count: [u8; 12usize],
pub _pad: [u8; 4usize],
}
impl Clone for TcFqQdStats {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcFqQdStats {
fn default() -> Self {
Self::new()
}
}
impl TcFqQdStats {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 152usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 152usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 152usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 152usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcFqQdStats>() == 152usize);
152usize
}
}
impl std::fmt::Debug for TcFqQdStats {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fmt.debug_struct("TcFqQdStats")
.field("gc_flows", &{ self.gc_flows })
.field("highprio_packets", &{ self.highprio_packets })
.field("tcp_retrans", &{ self.tcp_retrans })
.field("throttled", &{ self.throttled })
.field("flows_plimit", &{ self.flows_plimit })
.field("pkts_too_long", &{ self.pkts_too_long })
.field("allocation_errors", &{ self.allocation_errors })
.field("time_next_delayed_flow", &{ self.time_next_delayed_flow })
.field("flows", &self.flows)
.field("inactive_flows", &self.inactive_flows)
.field("throttled_flows", &self.throttled_flows)
.field("unthrottle_latency_ns", &self.unthrottle_latency_ns)
.field("ce_mark", &{ self.ce_mark })
.field("horizon_drops", &{ self.horizon_drops })
.field("horizon_caps", &{ self.horizon_caps })
.field("fastpath_packets", &{ self.fastpath_packets })
.field("band_drops", &self.band_drops)
.field("band_pkt_count", &self.band_pkt_count)
.finish()
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcHhfXstats {
#[doc = "Number of times max qdisc packet limit was hit\n"]
pub drop_overlimit: u32,
#[doc = "Number of times max heavy-hitters was hit\n"]
pub hh_overlimit: u32,
#[doc = "Number of captured heavy-hitters so far\n"]
pub hh_tot_count: u32,
#[doc = "Number of current heavy-hitters\n"]
pub hh_cur_count: u32,
}
impl Clone for TcHhfXstats {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcHhfXstats {
fn default() -> Self {
Self::new()
}
}
impl TcHhfXstats {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 16usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 16usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 16usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 16usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcHhfXstats>() == 16usize);
16usize
}
}
#[repr(C, packed(4))]
pub struct TcPieXstats {
#[doc = "Current probability\n"]
pub prob: u64,
#[doc = "Current delay in ms\n"]
pub delay: u32,
#[doc = "Current average dq rate in bits/pie-time\n"]
pub avg_dq_rate: u32,
#[doc = "Is avg-dq-rate being calculated?\n"]
pub dq_rate_estimating: u32,
#[doc = "Total number of packets enqueued\n"]
pub packets_in: u32,
#[doc = "Packets dropped due to pie action\n"]
pub dropped: u32,
#[doc = "Dropped due to lack of space in queue\n"]
pub overlimit: u32,
#[doc = "Maximum queue size\n"]
pub maxq: u32,
#[doc = "Packets marked with ECN\n"]
pub ecn_mark: u32,
}
impl Clone for TcPieXstats {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcPieXstats {
fn default() -> Self {
Self::new()
}
}
impl TcPieXstats {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 40usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 40usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 40usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 40usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcPieXstats>() == 40usize);
40usize
}
}
impl std::fmt::Debug for TcPieXstats {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fmt.debug_struct("TcPieXstats")
.field("prob", &{ self.prob })
.field("delay", &self.delay)
.field("avg_dq_rate", &self.avg_dq_rate)
.field("dq_rate_estimating", &self.dq_rate_estimating)
.field("packets_in", &self.packets_in)
.field("dropped", &self.dropped)
.field("overlimit", &self.overlimit)
.field("maxq", &self.maxq)
.field("ecn_mark", &self.ecn_mark)
.finish()
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcRedXstats {
#[doc = "Early drops\n"]
pub early: u32,
#[doc = "Drops due to queue limits\n"]
pub pdrop: u32,
#[doc = "Drops due to drop() calls\n"]
pub other: u32,
#[doc = "Marked packets\n"]
pub marked: u32,
}
impl Clone for TcRedXstats {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcRedXstats {
fn default() -> Self {
Self::new()
}
}
impl TcRedXstats {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 16usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 16usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 16usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 16usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcRedXstats>() == 16usize);
16usize
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcSfbXstats {
pub earlydrop: u32,
pub penaltydrop: u32,
pub bucketdrop: u32,
pub queuedrop: u32,
#[doc = "drops in child qdisc\n"]
pub childdrop: u32,
pub marked: u32,
pub maxqlen: u32,
pub maxprob: u32,
pub avgprob: u32,
}
impl Clone for TcSfbXstats {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcSfbXstats {
fn default() -> Self {
Self::new()
}
}
impl TcSfbXstats {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 36usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 36usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 36usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 36usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcSfbXstats>() == 36usize);
36usize
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcSfqXstats {
pub allot: i32,
}
impl Clone for TcSfqXstats {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcSfqXstats {
fn default() -> Self {
Self::new()
}
}
impl TcSfqXstats {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 4usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 4usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 4usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 4usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcSfqXstats>() == 4usize);
4usize
}
}
#[repr(C, packed(4))]
pub struct GnetStatsBasic {
pub bytes: u64,
pub packets: u32,
pub _pad_12: [u8; 4usize],
}
impl Clone for GnetStatsBasic {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for GnetStatsBasic {
fn default() -> Self {
Self::new()
}
}
impl GnetStatsBasic {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 16usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 16usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 16usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 16usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<GnetStatsBasic>() == 16usize);
16usize
}
}
impl std::fmt::Debug for GnetStatsBasic {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fmt.debug_struct("GnetStatsBasic")
.field("bytes", &{ self.bytes })
.field("packets", &self.packets)
.finish()
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct GnetStatsRateEst {
pub bps: u32,
pub pps: u32,
}
impl Clone for GnetStatsRateEst {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for GnetStatsRateEst {
fn default() -> Self {
Self::new()
}
}
impl GnetStatsRateEst {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 8usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 8usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 8usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 8usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<GnetStatsRateEst>() == 8usize);
8usize
}
}
#[repr(C, packed(4))]
pub struct GnetStatsRateEst64 {
pub bps: u64,
pub pps: u64,
}
impl Clone for GnetStatsRateEst64 {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for GnetStatsRateEst64 {
fn default() -> Self {
Self::new()
}
}
impl GnetStatsRateEst64 {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 16usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 16usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 16usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 16usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<GnetStatsRateEst64>() == 16usize);
16usize
}
}
impl std::fmt::Debug for GnetStatsRateEst64 {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fmt.debug_struct("GnetStatsRateEst64")
.field("bps", &{ self.bps })
.field("pps", &{ self.pps })
.finish()
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct GnetStatsQueue {
pub qlen: u32,
pub backlog: u32,
pub drops: u32,
pub requeues: u32,
pub overlimits: u32,
}
impl Clone for GnetStatsQueue {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for GnetStatsQueue {
fn default() -> Self {
Self::new()
}
}
impl GnetStatsQueue {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 20usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 20usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 20usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 20usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<GnetStatsQueue>() == 20usize);
20usize
}
}
#[repr(C, packed(4))]
pub struct TcU32Key {
pub _mask_be: u32,
pub _val_be: u32,
pub off: i32,
pub offmask: i32,
}
impl Clone for TcU32Key {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcU32Key {
fn default() -> Self {
Self::new()
}
}
impl TcU32Key {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 16usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 16usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 16usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 16usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcU32Key>() == 16usize);
16usize
}
pub fn mask(&self) -> u32 {
u32::from_be(self._mask_be)
}
pub fn set_mask(&mut self, value: u32) {
self._mask_be = value.to_be();
}
pub fn val(&self) -> u32 {
u32::from_be(self._val_be)
}
pub fn set_val(&mut self, value: u32) {
self._val_be = value.to_be();
}
}
impl std::fmt::Debug for TcU32Key {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fmt.debug_struct("TcU32Key")
.field("mask", &self.mask())
.field("val", &self.val())
.field("off", &self.off)
.field("offmask", &self.offmask)
.finish()
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcU32Mark {
pub val: u32,
pub mask: u32,
pub success: u32,
}
impl Clone for TcU32Mark {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcU32Mark {
fn default() -> Self {
Self::new()
}
}
impl TcU32Mark {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 12usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 12usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 12usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 12usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcU32Mark>() == 12usize);
12usize
}
}
#[repr(C, packed(4))]
pub struct TcU32Sel {
pub flags: u8,
pub offshift: u8,
pub nkeys: u8,
pub _pad_3: [u8; 1usize],
pub _offmask_be: u16,
pub off: u16,
pub offoff: i16,
pub hoff: i16,
pub _hmask_be: u32,
pub keys: TcU32Key,
}
impl Clone for TcU32Sel {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcU32Sel {
fn default() -> Self {
Self::new()
}
}
impl TcU32Sel {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 32usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 32usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 32usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 32usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcU32Sel>() == 32usize);
32usize
}
pub fn offmask(&self) -> u16 {
u16::from_be(self._offmask_be)
}
pub fn set_offmask(&mut self, value: u16) {
self._offmask_be = value.to_be();
}
pub fn hmask(&self) -> u32 {
u32::from_be(self._hmask_be)
}
pub fn set_hmask(&mut self, value: u32) {
self._hmask_be = value.to_be();
}
}
impl std::fmt::Debug for TcU32Sel {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fmt.debug_struct("TcU32Sel")
.field("flags", &self.flags)
.field("offshift", &self.offshift)
.field("nkeys", &self.nkeys)
.field("offmask", &self.offmask())
.field("off", &self.off)
.field("offoff", &self.offoff)
.field("hoff", &self.hoff)
.field("hmask", &self.hmask())
.field("keys", &self.keys)
.finish()
}
}
#[repr(C, packed(4))]
pub struct TcU32Pcnt {
pub rcnt: u64,
pub rhit: u64,
pub kcnts: u64,
}
impl Clone for TcU32Pcnt {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcU32Pcnt {
fn default() -> Self {
Self::new()
}
}
impl TcU32Pcnt {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 24usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 24usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 24usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 24usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcU32Pcnt>() == 24usize);
24usize
}
}
impl std::fmt::Debug for TcU32Pcnt {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fmt.debug_struct("TcU32Pcnt")
.field("rcnt", &{ self.rcnt })
.field("rhit", &{ self.rhit })
.field("kcnts", &{ self.kcnts })
.finish()
}
}
#[repr(C, packed(4))]
pub struct TcfT {
pub install: u64,
pub lastuse: u64,
pub expires: u64,
pub firstuse: u64,
}
impl Clone for TcfT {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcfT {
fn default() -> Self {
Self::new()
}
}
impl TcfT {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 32usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 32usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 32usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 32usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcfT>() == 32usize);
32usize
}
}
impl std::fmt::Debug for TcfT {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fmt.debug_struct("TcfT")
.field("install", &{ self.install })
.field("lastuse", &{ self.lastuse })
.field("expires", &{ self.expires })
.field("firstuse", &{ self.firstuse })
.finish()
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcGact {
pub index: u32,
pub capab: u32,
pub action: i32,
pub refcnt: i32,
pub bindcnt: i32,
}
impl Clone for TcGact {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcGact {
fn default() -> Self {
Self::new()
}
}
impl TcGact {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 20usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 20usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 20usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 20usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcGact>() == 20usize);
20usize
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcGactP {
pub ptype: u16,
pub pval: u16,
pub paction: i32,
}
impl Clone for TcGactP {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcGactP {
fn default() -> Self {
Self::new()
}
}
impl TcGactP {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 8usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 8usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 8usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 8usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcGactP>() == 8usize);
8usize
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcfEmatchTreeHdr {
pub nmatches: u16,
pub progid: u16,
}
impl Clone for TcfEmatchTreeHdr {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcfEmatchTreeHdr {
fn default() -> Self {
Self::new()
}
}
impl TcfEmatchTreeHdr {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 4usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 4usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 4usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 4usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcfEmatchTreeHdr>() == 4usize);
4usize
}
}
#[repr(C, packed(4))]
pub struct TcBasicPcnt {
pub rcnt: u64,
pub rhit: u64,
}
impl Clone for TcBasicPcnt {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcBasicPcnt {
fn default() -> Self {
Self::new()
}
}
impl TcBasicPcnt {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 16usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 16usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 16usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 16usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcBasicPcnt>() == 16usize);
16usize
}
}
impl std::fmt::Debug for TcBasicPcnt {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fmt.debug_struct("TcBasicPcnt")
.field("rcnt", &{ self.rcnt })
.field("rhit", &{ self.rhit })
.finish()
}
}
#[repr(C, packed(4))]
pub struct TcMatchallPcnt {
pub rhit: u64,
}
impl Clone for TcMatchallPcnt {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcMatchallPcnt {
fn default() -> Self {
Self::new()
}
}
impl TcMatchallPcnt {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 8usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 8usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 8usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 8usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcMatchallPcnt>() == 8usize);
8usize
}
}
impl std::fmt::Debug for TcMatchallPcnt {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fmt.debug_struct("TcMatchallPcnt")
.field("rhit", &{ self.rhit })
.finish()
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcMpls {
pub index: u32,
pub capab: u32,
pub action: i32,
pub refcnt: i32,
pub bindcnt: i32,
pub m_action: i32,
}
impl Clone for TcMpls {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcMpls {
fn default() -> Self {
Self::new()
}
}
impl TcMpls {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 24usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 24usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 24usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 24usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcMpls>() == 24usize);
24usize
}
}
#[repr(C, packed(4))]
pub struct TcPolice {
pub index: u32,
pub action: i32,
pub limit: u32,
pub burst: u32,
pub mtu: u32,
pub rate: TcRatespec,
pub peakrate: TcRatespec,
pub refcnt: i32,
pub bindcnt: i32,
pub capab: u32,
}
impl Clone for TcPolice {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcPolice {
fn default() -> Self {
Self::new()
}
}
impl TcPolice {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 56usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 56usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 56usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 56usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcPolice>() == 56usize);
56usize
}
}
impl std::fmt::Debug for TcPolice {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fmt.debug_struct("TcPolice")
.field("index", &self.index)
.field("action", &self.action)
.field("limit", &self.limit)
.field("burst", &self.burst)
.field("mtu", &self.mtu)
.field("rate", &self.rate)
.field("peakrate", &self.peakrate)
.field("refcnt", &self.refcnt)
.field("bindcnt", &self.bindcnt)
.field("capab", &self.capab)
.finish()
}
}
#[repr(C, packed(4))]
pub struct TcPeditSel {
pub index: u32,
pub capab: u32,
pub action: i32,
pub refcnt: i32,
pub bindcnt: i32,
pub nkeys: u8,
pub flags: u8,
pub _pad_22: [u8; 2usize],
pub keys: TcPeditKey,
}
impl Clone for TcPeditSel {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcPeditSel {
fn default() -> Self {
Self::new()
}
}
impl TcPeditSel {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 48usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 48usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 48usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 48usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcPeditSel>() == 48usize);
48usize
}
}
impl std::fmt::Debug for TcPeditSel {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fmt.debug_struct("TcPeditSel")
.field("index", &self.index)
.field("capab", &self.capab)
.field("action", &self.action)
.field("refcnt", &self.refcnt)
.field("bindcnt", &self.bindcnt)
.field("nkeys", &self.nkeys)
.field("flags", &self.flags)
.field("keys", &self.keys)
.finish()
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcPeditKey {
pub mask: u32,
pub val: u32,
pub off: u32,
pub at: u32,
pub offmask: u32,
pub shift: u32,
}
impl Clone for TcPeditKey {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcPeditKey {
fn default() -> Self {
Self::new()
}
}
impl TcPeditKey {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 24usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 24usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 24usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 24usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcPeditKey>() == 24usize);
24usize
}
}
#[derive(Debug)]
#[repr(C, packed(4))]
pub struct TcVlan {
pub index: u32,
pub capab: u32,
pub action: i32,
pub refcnt: i32,
pub bindcnt: i32,
pub v_action: i32,
}
impl Clone for TcVlan {
fn clone(&self) -> Self {
Self::new_from_array(*self.as_array())
}
}
#[doc = "Create zero-initialized struct"]
impl Default for TcVlan {
fn default() -> Self {
Self::new()
}
}
impl TcVlan {
#[doc = "Create zero-initialized struct"]
pub fn new() -> Self {
Self::new_from_array([0u8; Self::len()])
}
#[doc = "Copy from contents from slice"]
pub fn new_from_slice(other: &[u8]) -> Option<Self> {
if other.len() != Self::len() {
return None;
}
let mut buf = [0u8; Self::len()];
buf.clone_from_slice(other);
Some(Self::new_from_array(buf))
}
#[doc = "Copy from contents from another slice, padding with zeros or truncating when needed"]
pub fn new_from_zeroed(other: &[u8]) -> Self {
let mut buf = [0u8; Self::len()];
let len = buf.len().min(other.len());
buf[..len].clone_from_slice(&other[..len]);
Self::new_from_array(buf)
}
pub fn new_from_array(buf: [u8; 24usize]) -> Self {
unsafe { std::mem::transmute(buf) }
}
pub fn as_slice(&self) -> &[u8] {
unsafe {
let ptr: *const u8 = std::mem::transmute(self as *const Self);
std::slice::from_raw_parts(ptr, Self::len())
}
}
pub fn from_slice(buf: &[u8]) -> &Self {
assert!(buf.len() >= Self::len());
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf.as_ptr()) }
}
pub fn as_array(&self) -> &[u8; 24usize] {
unsafe { std::mem::transmute(self) }
}
pub fn from_array(buf: &[u8; 24usize]) -> &Self {
assert!(buf.as_ptr() as usize % std::mem::align_of::<Self>() == 0);
unsafe { std::mem::transmute(buf) }
}
pub fn into_array(self) -> [u8; 24usize] {
unsafe { std::mem::transmute(self) }
}
pub const fn len() -> usize {
const _: () = assert!(std::mem::size_of::<TcVlan>() == 24usize);
24usize
}
}
#[derive(Clone)]
pub enum Attrs<'a> {
Kind(&'a CStr),
Options(OptionsMsg<'a>),
Stats(TcStats),
Xstats(TcaStatsAppMsg<'a>),
Rate(GnetEstimator),
Fcnt(u32),
Stats2(IterableTcaStatsAttrs<'a>),
Stab(IterableTcaStabAttrs<'a>),
Pad(&'a [u8]),
DumpInvisible(()),
Chain(u32),
HwOffload(u8),
IngressBlock(u32),
EgressBlock(u32),
DumpFlags(BuiltinBitfield32),
ExtWarnMsg(&'a CStr),
}
impl<'a> IterableAttrs<'a> {
pub fn get_kind(&self) -> Result<&'a CStr, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(Attrs::Kind(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"Attrs",
"Kind",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_options(&self) -> Result<OptionsMsg<'a>, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(Attrs::Options(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"Attrs",
"Options",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_stats(&self) -> Result<TcStats, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(Attrs::Stats(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"Attrs",
"Stats",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_xstats(&self) -> Result<TcaStatsAppMsg<'a>, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(Attrs::Xstats(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"Attrs",
"Xstats",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_rate(&self) -> Result<GnetEstimator, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(Attrs::Rate(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"Attrs",
"Rate",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_fcnt(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(Attrs::Fcnt(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"Attrs",
"Fcnt",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_stats2(&self) -> Result<IterableTcaStatsAttrs<'a>, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(Attrs::Stats2(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"Attrs",
"Stats2",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_stab(&self) -> Result<IterableTcaStabAttrs<'a>, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(Attrs::Stab(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"Attrs",
"Stab",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(Attrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"Attrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_dump_invisible(&self) -> Result<(), ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(Attrs::DumpInvisible(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"Attrs",
"DumpInvisible",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_chain(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(Attrs::Chain(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"Attrs",
"Chain",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_hw_offload(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(Attrs::HwOffload(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"Attrs",
"HwOffload",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_ingress_block(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(Attrs::IngressBlock(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"Attrs",
"IngressBlock",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_egress_block(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(Attrs::EgressBlock(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"Attrs",
"EgressBlock",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_dump_flags(&self) -> Result<BuiltinBitfield32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(Attrs::DumpFlags(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"Attrs",
"DumpFlags",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_ext_warn_msg(&self) -> Result<&'a CStr, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(Attrs::ExtWarnMsg(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"Attrs",
"ExtWarnMsg",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
#[derive(Debug, Clone)]
pub enum OptionsMsg<'a> {
Basic(IterableBasicAttrs<'a>),
Bpf(IterableBpfAttrs<'a>),
Bfifo(TcFifoQopt),
Cake(IterableCakeAttrs<'a>),
Cbs(IterableCbsAttrs<'a>),
Cgroup(IterableCgroupAttrs<'a>),
Choke(IterableChokeAttrs<'a>),
Clsact,
Codel(IterableCodelAttrs<'a>),
Drr(IterableDrrAttrs<'a>),
Dualpi2(IterableDualpi2Attrs<'a>),
Etf(IterableEtfAttrs<'a>),
Ets(IterableEtsAttrs<'a>),
Flow(IterableFlowAttrs<'a>),
Flower(IterableFlowerAttrs<'a>),
Fq(IterableFqAttrs<'a>),
FqCodel(IterableFqCodelAttrs<'a>),
FqPie(IterableFqPieAttrs<'a>),
Fw(IterableFwAttrs<'a>),
Gred(IterableGredAttrs<'a>),
Hfsc(TcHfscQopt),
Hhf(IterableHhfAttrs<'a>),
Htb(IterableHtbAttrs<'a>),
Ingress,
Matchall(IterableMatchallAttrs<'a>),
Mq,
Mqprio(TcMqprioQopt),
Multiq(TcMultiqQopt),
Netem(TcNetemQopt, IterableNetemAttrs<'a>),
Pfifo(TcFifoQopt),
PfifoFast(TcPrioQopt),
PfifoHeadDrop(TcFifoQopt),
Pie(IterablePieAttrs<'a>),
Plug(TcPlugQopt),
Prio(TcPrioQopt),
Qfq(IterableQfqAttrs<'a>),
Red(IterableRedAttrs<'a>),
Route(IterableRouteAttrs<'a>),
Sfb(TcSfbQopt),
Sfq(TcSfqQoptV1),
Taprio(IterableTaprioAttrs<'a>),
Tbf(IterableTbfAttrs<'a>),
U32(IterableU32Attrs<'a>),
}
impl<'a> OptionsMsg<'a> {
fn select_with_loc(selector: &'a CStr, buf: &'a [u8], loc: usize) -> Option<Self> {
match selector.to_bytes() {
b"basic" => Some(OptionsMsg::Basic(IterableBasicAttrs::with_loc(buf, loc))),
b"bpf" => Some(OptionsMsg::Bpf(IterableBpfAttrs::with_loc(buf, loc))),
b"bfifo" => Some(OptionsMsg::Bfifo(TcFifoQopt::new_from_zeroed(buf))),
b"cake" => Some(OptionsMsg::Cake(IterableCakeAttrs::with_loc(buf, loc))),
b"cbs" => Some(OptionsMsg::Cbs(IterableCbsAttrs::with_loc(buf, loc))),
b"cgroup" => Some(OptionsMsg::Cgroup(IterableCgroupAttrs::with_loc(buf, loc))),
b"choke" => Some(OptionsMsg::Choke(IterableChokeAttrs::with_loc(buf, loc))),
b"clsact" => Some(OptionsMsg::Clsact),
b"codel" => Some(OptionsMsg::Codel(IterableCodelAttrs::with_loc(buf, loc))),
b"drr" => Some(OptionsMsg::Drr(IterableDrrAttrs::with_loc(buf, loc))),
b"dualpi2" => Some(OptionsMsg::Dualpi2(IterableDualpi2Attrs::with_loc(
buf, loc,
))),
b"etf" => Some(OptionsMsg::Etf(IterableEtfAttrs::with_loc(buf, loc))),
b"ets" => Some(OptionsMsg::Ets(IterableEtsAttrs::with_loc(buf, loc))),
b"flow" => Some(OptionsMsg::Flow(IterableFlowAttrs::with_loc(buf, loc))),
b"flower" => Some(OptionsMsg::Flower(IterableFlowerAttrs::with_loc(buf, loc))),
b"fq" => Some(OptionsMsg::Fq(IterableFqAttrs::with_loc(buf, loc))),
b"fq_codel" => Some(OptionsMsg::FqCodel(IterableFqCodelAttrs::with_loc(
buf, loc,
))),
b"fq_pie" => Some(OptionsMsg::FqPie(IterableFqPieAttrs::with_loc(buf, loc))),
b"fw" => Some(OptionsMsg::Fw(IterableFwAttrs::with_loc(buf, loc))),
b"gred" => Some(OptionsMsg::Gred(IterableGredAttrs::with_loc(buf, loc))),
b"hfsc" => Some(OptionsMsg::Hfsc(TcHfscQopt::new_from_zeroed(buf))),
b"hhf" => Some(OptionsMsg::Hhf(IterableHhfAttrs::with_loc(buf, loc))),
b"htb" => Some(OptionsMsg::Htb(IterableHtbAttrs::with_loc(buf, loc))),
b"ingress" => Some(OptionsMsg::Ingress),
b"matchall" => Some(OptionsMsg::Matchall(IterableMatchallAttrs::with_loc(
buf, loc,
))),
b"mq" => Some(OptionsMsg::Mq),
b"mqprio" => Some(OptionsMsg::Mqprio(TcMqprioQopt::new_from_zeroed(buf))),
b"multiq" => Some(OptionsMsg::Multiq(TcMultiqQopt::new_from_zeroed(buf))),
b"netem" => {
let (header, attrs) = buf.split_at(buf.len().min(TcNetemQopt::len()));
Some(OptionsMsg::Netem(
TcNetemQopt::new_from_slice(header)?,
IterableNetemAttrs::with_loc(attrs, loc),
))
}
b"pfifo" => Some(OptionsMsg::Pfifo(TcFifoQopt::new_from_zeroed(buf))),
b"pfifo_fast" => Some(OptionsMsg::PfifoFast(TcPrioQopt::new_from_zeroed(buf))),
b"pfifo_head_drop" => Some(OptionsMsg::PfifoHeadDrop(TcFifoQopt::new_from_zeroed(buf))),
b"pie" => Some(OptionsMsg::Pie(IterablePieAttrs::with_loc(buf, loc))),
b"plug" => Some(OptionsMsg::Plug(TcPlugQopt::new_from_zeroed(buf))),
b"prio" => Some(OptionsMsg::Prio(TcPrioQopt::new_from_zeroed(buf))),
b"qfq" => Some(OptionsMsg::Qfq(IterableQfqAttrs::with_loc(buf, loc))),
b"red" => Some(OptionsMsg::Red(IterableRedAttrs::with_loc(buf, loc))),
b"route" => Some(OptionsMsg::Route(IterableRouteAttrs::with_loc(buf, loc))),
b"sfb" => Some(OptionsMsg::Sfb(TcSfbQopt::new_from_zeroed(buf))),
b"sfq" => Some(OptionsMsg::Sfq(TcSfqQoptV1::new_from_zeroed(buf))),
b"taprio" => Some(OptionsMsg::Taprio(IterableTaprioAttrs::with_loc(buf, loc))),
b"tbf" => Some(OptionsMsg::Tbf(IterableTbfAttrs::with_loc(buf, loc))),
b"u32" => Some(OptionsMsg::U32(IterableU32Attrs::with_loc(buf, loc))),
_ => None,
}
}
}
#[derive(Debug, Clone)]
pub enum TcaStatsAppMsg<'a> {
Cake(IterableCakeStatsAttrs<'a>),
Choke(TcChokeXstats),
Codel(TcCodelXstats),
Dualpi2(TcDualpi2Xstats),
Fq(TcFqQdStats),
FqCodel(TcFqCodelXstats),
FqPie(TcFqPieXstats),
Hhf(TcHhfXstats),
Pie(TcPieXstats),
Red(TcRedXstats),
Sfb(TcSfbXstats),
Sfq(TcSfqXstats),
}
impl<'a> TcaStatsAppMsg<'a> {
fn select_with_loc(selector: &'a CStr, buf: &'a [u8], loc: usize) -> Option<Self> {
match selector.to_bytes() {
b"cake" => Some(TcaStatsAppMsg::Cake(IterableCakeStatsAttrs::with_loc(
buf, loc,
))),
b"choke" => Some(TcaStatsAppMsg::Choke(TcChokeXstats::new_from_zeroed(buf))),
b"codel" => Some(TcaStatsAppMsg::Codel(TcCodelXstats::new_from_zeroed(buf))),
b"dualpi2" => Some(TcaStatsAppMsg::Dualpi2(TcDualpi2Xstats::new_from_zeroed(
buf,
))),
b"fq" => Some(TcaStatsAppMsg::Fq(TcFqQdStats::new_from_zeroed(buf))),
b"fq_codel" => Some(TcaStatsAppMsg::FqCodel(TcFqCodelXstats::new_from_zeroed(
buf,
))),
b"fq_pie" => Some(TcaStatsAppMsg::FqPie(TcFqPieXstats::new_from_zeroed(buf))),
b"hhf" => Some(TcaStatsAppMsg::Hhf(TcHhfXstats::new_from_zeroed(buf))),
b"pie" => Some(TcaStatsAppMsg::Pie(TcPieXstats::new_from_zeroed(buf))),
b"red" => Some(TcaStatsAppMsg::Red(TcRedXstats::new_from_zeroed(buf))),
b"sfb" => Some(TcaStatsAppMsg::Sfb(TcSfbXstats::new_from_zeroed(buf))),
b"sfq" => Some(TcaStatsAppMsg::Sfq(TcSfqXstats::new_from_zeroed(buf))),
_ => None,
}
}
}
impl Attrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableAttrs<'a> {
IterableAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Kind",
2u16 => "Options",
3u16 => "Stats",
4u16 => "Xstats",
5u16 => "Rate",
6u16 => "Fcnt",
7u16 => "Stats2",
8u16 => "Stab",
9u16 => "Pad",
10u16 => "DumpInvisible",
11u16 => "Chain",
12u16 => "HwOffload",
13u16 => "IngressBlock",
14u16 => "EgressBlock",
15u16 => "DumpFlags",
16u16 => "ExtWarnMsg",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableAttrs<'a> {
type Item = Result<Attrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => Attrs::Kind({
let res = CStr::from_bytes_with_nul(next).ok();
let Some(val) = res else { break };
val
}),
2u16 => Attrs::Options({
let res = {
let Ok(selector) = self.get_kind() else { break };
match OptionsMsg::select_with_loc(selector, next, self.orig_loc) {
Some(sub) => Some(sub),
None if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
None => continue,
}
};
let Some(val) = res else { break };
val
}),
3u16 => Attrs::Stats({
let res = Some(TcStats::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
4u16 => Attrs::Xstats({
let res = {
let Ok(selector) = self.get_kind() else { break };
match TcaStatsAppMsg::select_with_loc(selector, next, self.orig_loc) {
Some(sub) => Some(sub),
None if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
None => continue,
}
};
let Some(val) = res else { break };
val
}),
5u16 => Attrs::Rate({
let res = Some(GnetEstimator::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
6u16 => Attrs::Fcnt({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
7u16 => Attrs::Stats2({
let res = Some(IterableTcaStatsAttrs::with_loc(next, self.orig_loc));
let Some(val) = res else { break };
val
}),
8u16 => Attrs::Stab({
let res = Some(IterableTcaStabAttrs::with_loc(next, self.orig_loc));
let Some(val) = res else { break };
val
}),
9u16 => Attrs::Pad({
let res = Some(next);
let Some(val) = res else { break };
val
}),
10u16 => Attrs::DumpInvisible(()),
11u16 => Attrs::Chain({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
12u16 => Attrs::HwOffload({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
13u16 => Attrs::IngressBlock({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
14u16 => Attrs::EgressBlock({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
15u16 => Attrs::DumpFlags({
let res = BuiltinBitfield32::new_from_slice(next);
let Some(val) = res else { break };
val
}),
16u16 => Attrs::ExtWarnMsg({
let res = CStr::from_bytes_with_nul(next).ok();
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"Attrs",
r#type.and_then(|t| Attrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("Attrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
Attrs::Kind(val) => fmt.field("Kind", &val),
Attrs::Options(val) => fmt.field("Options", &val),
Attrs::Stats(val) => fmt.field("Stats", &val),
Attrs::Xstats(val) => fmt.field("Xstats", &val),
Attrs::Rate(val) => fmt.field("Rate", &val),
Attrs::Fcnt(val) => fmt.field("Fcnt", &val),
Attrs::Stats2(val) => fmt.field("Stats2", &val),
Attrs::Stab(val) => fmt.field("Stab", &val),
Attrs::Pad(val) => fmt.field("Pad", &val),
Attrs::DumpInvisible(val) => fmt.field("DumpInvisible", &val),
Attrs::Chain(val) => fmt.field("Chain", &val),
Attrs::HwOffload(val) => fmt.field("HwOffload", &val),
Attrs::IngressBlock(val) => fmt.field("IngressBlock", &val),
Attrs::EgressBlock(val) => fmt.field("EgressBlock", &val),
Attrs::DumpFlags(val) => fmt.field("DumpFlags", &val),
Attrs::ExtWarnMsg(val) => fmt.field("ExtWarnMsg", &val),
};
}
fmt.finish()
}
}
impl IterableAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("Attrs", offset));
return (stack, missing_type.and_then(|t| Attrs::attr_from_type(t)));
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
let mut missing = None;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
Attrs::Kind(val) => {
if last_off == offset {
stack.push(("Kind", last_off));
break;
}
}
Attrs::Options(val) => {
if last_off == offset {
stack.push(("Options", last_off));
break;
}
}
Attrs::Stats(val) => {
if last_off == offset {
stack.push(("Stats", last_off));
break;
}
}
Attrs::Xstats(val) => {
if last_off == offset {
stack.push(("Xstats", last_off));
break;
}
}
Attrs::Rate(val) => {
if last_off == offset {
stack.push(("Rate", last_off));
break;
}
}
Attrs::Fcnt(val) => {
if last_off == offset {
stack.push(("Fcnt", last_off));
break;
}
}
Attrs::Stats2(val) => {
(stack, missing) = val.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
Attrs::Stab(val) => {
(stack, missing) = val.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
Attrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
Attrs::DumpInvisible(val) => {
if last_off == offset {
stack.push(("DumpInvisible", last_off));
break;
}
}
Attrs::Chain(val) => {
if last_off == offset {
stack.push(("Chain", last_off));
break;
}
}
Attrs::HwOffload(val) => {
if last_off == offset {
stack.push(("HwOffload", last_off));
break;
}
}
Attrs::IngressBlock(val) => {
if last_off == offset {
stack.push(("IngressBlock", last_off));
break;
}
}
Attrs::EgressBlock(val) => {
if last_off == offset {
stack.push(("EgressBlock", last_off));
break;
}
}
Attrs::DumpFlags(val) => {
if last_off == offset {
stack.push(("DumpFlags", last_off));
break;
}
}
Attrs::ExtWarnMsg(val) => {
if last_off == offset {
stack.push(("ExtWarnMsg", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("Attrs", cur));
}
(stack, missing)
}
}
#[derive(Clone)]
pub enum ActAttrs<'a> {
Kind(&'a CStr),
Options(ActOptionsMsg<'a>),
Index(u32),
Stats(IterableTcaStatsAttrs<'a>),
Pad(&'a [u8]),
Cookie(&'a [u8]),
Flags(BuiltinBitfield32),
HwStats(BuiltinBitfield32),
UsedHwStats(BuiltinBitfield32),
InHwCount(u32),
}
impl<'a> IterableActAttrs<'a> {
pub fn get_kind(&self) -> Result<&'a CStr, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActAttrs::Kind(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActAttrs",
"Kind",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_options(&self) -> Result<ActOptionsMsg<'a>, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActAttrs::Options(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActAttrs",
"Options",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_index(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActAttrs::Index(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActAttrs",
"Index",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_stats(&self) -> Result<IterableTcaStatsAttrs<'a>, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActAttrs::Stats(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActAttrs",
"Stats",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActAttrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActAttrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_cookie(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActAttrs::Cookie(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActAttrs",
"Cookie",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_flags(&self) -> Result<BuiltinBitfield32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActAttrs::Flags(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActAttrs",
"Flags",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_hw_stats(&self) -> Result<BuiltinBitfield32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActAttrs::HwStats(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActAttrs",
"HwStats",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_used_hw_stats(&self) -> Result<BuiltinBitfield32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActAttrs::UsedHwStats(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActAttrs",
"UsedHwStats",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_in_hw_count(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActAttrs::InHwCount(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActAttrs",
"InHwCount",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
#[derive(Debug, Clone)]
pub enum ActOptionsMsg<'a> {
Bpf(IterableActBpfAttrs<'a>),
Connmark(IterableActConnmarkAttrs<'a>),
Csum(IterableActCsumAttrs<'a>),
Ct(IterableActCtAttrs<'a>),
Ctinfo(IterableActCtinfoAttrs<'a>),
Gact(IterableActGactAttrs<'a>),
Gate(IterableActGateAttrs<'a>),
Ife(IterableActIfeAttrs<'a>),
Mirred(IterableActMirredAttrs<'a>),
Mpls(IterableActMplsAttrs<'a>),
Nat(IterableActNatAttrs<'a>),
Pedit(IterableActPeditAttrs<'a>),
Police(IterablePoliceAttrs<'a>),
Sample(IterableActSampleAttrs<'a>),
Simple(IterableActSimpleAttrs<'a>),
Skbedit(IterableActSkbeditAttrs<'a>),
Skbmod(IterableActSkbmodAttrs<'a>),
TunnelKey(IterableActTunnelKeyAttrs<'a>),
Vlan(IterableActVlanAttrs<'a>),
}
impl<'a> ActOptionsMsg<'a> {
fn select_with_loc(selector: &'a CStr, buf: &'a [u8], loc: usize) -> Option<Self> {
match selector.to_bytes() {
b"bpf" => Some(ActOptionsMsg::Bpf(IterableActBpfAttrs::with_loc(buf, loc))),
b"connmark" => Some(ActOptionsMsg::Connmark(IterableActConnmarkAttrs::with_loc(
buf, loc,
))),
b"csum" => Some(ActOptionsMsg::Csum(IterableActCsumAttrs::with_loc(
buf, loc,
))),
b"ct" => Some(ActOptionsMsg::Ct(IterableActCtAttrs::with_loc(buf, loc))),
b"ctinfo" => Some(ActOptionsMsg::Ctinfo(IterableActCtinfoAttrs::with_loc(
buf, loc,
))),
b"gact" => Some(ActOptionsMsg::Gact(IterableActGactAttrs::with_loc(
buf, loc,
))),
b"gate" => Some(ActOptionsMsg::Gate(IterableActGateAttrs::with_loc(
buf, loc,
))),
b"ife" => Some(ActOptionsMsg::Ife(IterableActIfeAttrs::with_loc(buf, loc))),
b"mirred" => Some(ActOptionsMsg::Mirred(IterableActMirredAttrs::with_loc(
buf, loc,
))),
b"mpls" => Some(ActOptionsMsg::Mpls(IterableActMplsAttrs::with_loc(
buf, loc,
))),
b"nat" => Some(ActOptionsMsg::Nat(IterableActNatAttrs::with_loc(buf, loc))),
b"pedit" => Some(ActOptionsMsg::Pedit(IterableActPeditAttrs::with_loc(
buf, loc,
))),
b"police" => Some(ActOptionsMsg::Police(IterablePoliceAttrs::with_loc(
buf, loc,
))),
b"sample" => Some(ActOptionsMsg::Sample(IterableActSampleAttrs::with_loc(
buf, loc,
))),
b"simple" => Some(ActOptionsMsg::Simple(IterableActSimpleAttrs::with_loc(
buf, loc,
))),
b"skbedit" => Some(ActOptionsMsg::Skbedit(IterableActSkbeditAttrs::with_loc(
buf, loc,
))),
b"skbmod" => Some(ActOptionsMsg::Skbmod(IterableActSkbmodAttrs::with_loc(
buf, loc,
))),
b"tunnel_key" => Some(ActOptionsMsg::TunnelKey(
IterableActTunnelKeyAttrs::with_loc(buf, loc),
)),
b"vlan" => Some(ActOptionsMsg::Vlan(IterableActVlanAttrs::with_loc(
buf, loc,
))),
_ => None,
}
}
}
impl ActAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableActAttrs<'a> {
IterableActAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Kind",
2u16 => "Options",
3u16 => "Index",
4u16 => "Stats",
5u16 => "Pad",
6u16 => "Cookie",
7u16 => "Flags",
8u16 => "HwStats",
9u16 => "UsedHwStats",
10u16 => "InHwCount",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableActAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableActAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableActAttrs<'a> {
type Item = Result<ActAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => ActAttrs::Kind({
let res = CStr::from_bytes_with_nul(next).ok();
let Some(val) = res else { break };
val
}),
2u16 => ActAttrs::Options({
let res = {
let Ok(selector) = self.get_kind() else { break };
match ActOptionsMsg::select_with_loc(selector, next, self.orig_loc) {
Some(sub) => Some(sub),
None if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
None => continue,
}
};
let Some(val) = res else { break };
val
}),
3u16 => ActAttrs::Index({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
4u16 => ActAttrs::Stats({
let res = Some(IterableTcaStatsAttrs::with_loc(next, self.orig_loc));
let Some(val) = res else { break };
val
}),
5u16 => ActAttrs::Pad({
let res = Some(next);
let Some(val) = res else { break };
val
}),
6u16 => ActAttrs::Cookie({
let res = Some(next);
let Some(val) = res else { break };
val
}),
7u16 => ActAttrs::Flags({
let res = BuiltinBitfield32::new_from_slice(next);
let Some(val) = res else { break };
val
}),
8u16 => ActAttrs::HwStats({
let res = BuiltinBitfield32::new_from_slice(next);
let Some(val) = res else { break };
val
}),
9u16 => ActAttrs::UsedHwStats({
let res = BuiltinBitfield32::new_from_slice(next);
let Some(val) = res else { break };
val
}),
10u16 => ActAttrs::InHwCount({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"ActAttrs",
r#type.and_then(|t| ActAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableActAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("ActAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
ActAttrs::Kind(val) => fmt.field("Kind", &val),
ActAttrs::Options(val) => fmt.field("Options", &val),
ActAttrs::Index(val) => fmt.field("Index", &val),
ActAttrs::Stats(val) => fmt.field("Stats", &val),
ActAttrs::Pad(val) => fmt.field("Pad", &val),
ActAttrs::Cookie(val) => fmt.field("Cookie", &val),
ActAttrs::Flags(val) => fmt.field("Flags", &val),
ActAttrs::HwStats(val) => fmt.field("HwStats", &val),
ActAttrs::UsedHwStats(val) => fmt.field("UsedHwStats", &val),
ActAttrs::InHwCount(val) => fmt.field("InHwCount", &val),
};
}
fmt.finish()
}
}
impl IterableActAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("ActAttrs", offset));
return (
stack,
missing_type.and_then(|t| ActAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
let mut missing = None;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
ActAttrs::Kind(val) => {
if last_off == offset {
stack.push(("Kind", last_off));
break;
}
}
ActAttrs::Options(val) => {
if last_off == offset {
stack.push(("Options", last_off));
break;
}
}
ActAttrs::Index(val) => {
if last_off == offset {
stack.push(("Index", last_off));
break;
}
}
ActAttrs::Stats(val) => {
(stack, missing) = val.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
ActAttrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
ActAttrs::Cookie(val) => {
if last_off == offset {
stack.push(("Cookie", last_off));
break;
}
}
ActAttrs::Flags(val) => {
if last_off == offset {
stack.push(("Flags", last_off));
break;
}
}
ActAttrs::HwStats(val) => {
if last_off == offset {
stack.push(("HwStats", last_off));
break;
}
}
ActAttrs::UsedHwStats(val) => {
if last_off == offset {
stack.push(("UsedHwStats", last_off));
break;
}
}
ActAttrs::InHwCount(val) => {
if last_off == offset {
stack.push(("InHwCount", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("ActAttrs", cur));
}
(stack, missing)
}
}
#[derive(Clone)]
pub enum ActBpfAttrs<'a> {
Tm(TcfT),
Parms(&'a [u8]),
OpsLen(u16),
Ops(&'a [u8]),
Fd(u32),
Name(&'a CStr),
Pad(&'a [u8]),
Tag(&'a [u8]),
Id(&'a [u8]),
}
impl<'a> IterableActBpfAttrs<'a> {
pub fn get_tm(&self) -> Result<TcfT, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActBpfAttrs::Tm(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActBpfAttrs",
"Tm",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_parms(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActBpfAttrs::Parms(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActBpfAttrs",
"Parms",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_ops_len(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActBpfAttrs::OpsLen(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActBpfAttrs",
"OpsLen",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_ops(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActBpfAttrs::Ops(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActBpfAttrs",
"Ops",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_fd(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActBpfAttrs::Fd(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActBpfAttrs",
"Fd",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_name(&self) -> Result<&'a CStr, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActBpfAttrs::Name(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActBpfAttrs",
"Name",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActBpfAttrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActBpfAttrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_tag(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActBpfAttrs::Tag(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActBpfAttrs",
"Tag",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_id(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActBpfAttrs::Id(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActBpfAttrs",
"Id",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl ActBpfAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableActBpfAttrs<'a> {
IterableActBpfAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Tm",
2u16 => "Parms",
3u16 => "OpsLen",
4u16 => "Ops",
5u16 => "Fd",
6u16 => "Name",
7u16 => "Pad",
8u16 => "Tag",
9u16 => "Id",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableActBpfAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableActBpfAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableActBpfAttrs<'a> {
type Item = Result<ActBpfAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => ActBpfAttrs::Tm({
let res = Some(TcfT::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
2u16 => ActBpfAttrs::Parms({
let res = Some(next);
let Some(val) = res else { break };
val
}),
3u16 => ActBpfAttrs::OpsLen({
let res = parse_u16(next);
let Some(val) = res else { break };
val
}),
4u16 => ActBpfAttrs::Ops({
let res = Some(next);
let Some(val) = res else { break };
val
}),
5u16 => ActBpfAttrs::Fd({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
6u16 => ActBpfAttrs::Name({
let res = CStr::from_bytes_with_nul(next).ok();
let Some(val) = res else { break };
val
}),
7u16 => ActBpfAttrs::Pad({
let res = Some(next);
let Some(val) = res else { break };
val
}),
8u16 => ActBpfAttrs::Tag({
let res = Some(next);
let Some(val) = res else { break };
val
}),
9u16 => ActBpfAttrs::Id({
let res = Some(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"ActBpfAttrs",
r#type.and_then(|t| ActBpfAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableActBpfAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("ActBpfAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
ActBpfAttrs::Tm(val) => fmt.field("Tm", &val),
ActBpfAttrs::Parms(val) => fmt.field("Parms", &val),
ActBpfAttrs::OpsLen(val) => fmt.field("OpsLen", &val),
ActBpfAttrs::Ops(val) => fmt.field("Ops", &val),
ActBpfAttrs::Fd(val) => fmt.field("Fd", &val),
ActBpfAttrs::Name(val) => fmt.field("Name", &val),
ActBpfAttrs::Pad(val) => fmt.field("Pad", &val),
ActBpfAttrs::Tag(val) => fmt.field("Tag", &val),
ActBpfAttrs::Id(val) => fmt.field("Id", &val),
};
}
fmt.finish()
}
}
impl IterableActBpfAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("ActBpfAttrs", offset));
return (
stack,
missing_type.and_then(|t| ActBpfAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
ActBpfAttrs::Tm(val) => {
if last_off == offset {
stack.push(("Tm", last_off));
break;
}
}
ActBpfAttrs::Parms(val) => {
if last_off == offset {
stack.push(("Parms", last_off));
break;
}
}
ActBpfAttrs::OpsLen(val) => {
if last_off == offset {
stack.push(("OpsLen", last_off));
break;
}
}
ActBpfAttrs::Ops(val) => {
if last_off == offset {
stack.push(("Ops", last_off));
break;
}
}
ActBpfAttrs::Fd(val) => {
if last_off == offset {
stack.push(("Fd", last_off));
break;
}
}
ActBpfAttrs::Name(val) => {
if last_off == offset {
stack.push(("Name", last_off));
break;
}
}
ActBpfAttrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
ActBpfAttrs::Tag(val) => {
if last_off == offset {
stack.push(("Tag", last_off));
break;
}
}
ActBpfAttrs::Id(val) => {
if last_off == offset {
stack.push(("Id", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("ActBpfAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum ActConnmarkAttrs<'a> {
Parms(&'a [u8]),
Tm(TcfT),
Pad(&'a [u8]),
}
impl<'a> IterableActConnmarkAttrs<'a> {
pub fn get_parms(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActConnmarkAttrs::Parms(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActConnmarkAttrs",
"Parms",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_tm(&self) -> Result<TcfT, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActConnmarkAttrs::Tm(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActConnmarkAttrs",
"Tm",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActConnmarkAttrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActConnmarkAttrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl ActConnmarkAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableActConnmarkAttrs<'a> {
IterableActConnmarkAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Parms",
2u16 => "Tm",
3u16 => "Pad",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableActConnmarkAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableActConnmarkAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableActConnmarkAttrs<'a> {
type Item = Result<ActConnmarkAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => ActConnmarkAttrs::Parms({
let res = Some(next);
let Some(val) = res else { break };
val
}),
2u16 => ActConnmarkAttrs::Tm({
let res = Some(TcfT::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
3u16 => ActConnmarkAttrs::Pad({
let res = Some(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"ActConnmarkAttrs",
r#type.and_then(|t| ActConnmarkAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableActConnmarkAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("ActConnmarkAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
ActConnmarkAttrs::Parms(val) => fmt.field("Parms", &val),
ActConnmarkAttrs::Tm(val) => fmt.field("Tm", &val),
ActConnmarkAttrs::Pad(val) => fmt.field("Pad", &val),
};
}
fmt.finish()
}
}
impl IterableActConnmarkAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("ActConnmarkAttrs", offset));
return (
stack,
missing_type.and_then(|t| ActConnmarkAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
ActConnmarkAttrs::Parms(val) => {
if last_off == offset {
stack.push(("Parms", last_off));
break;
}
}
ActConnmarkAttrs::Tm(val) => {
if last_off == offset {
stack.push(("Tm", last_off));
break;
}
}
ActConnmarkAttrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("ActConnmarkAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum ActCsumAttrs<'a> {
Parms(&'a [u8]),
Tm(TcfT),
Pad(&'a [u8]),
}
impl<'a> IterableActCsumAttrs<'a> {
pub fn get_parms(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActCsumAttrs::Parms(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActCsumAttrs",
"Parms",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_tm(&self) -> Result<TcfT, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActCsumAttrs::Tm(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActCsumAttrs",
"Tm",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActCsumAttrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActCsumAttrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl ActCsumAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableActCsumAttrs<'a> {
IterableActCsumAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Parms",
2u16 => "Tm",
3u16 => "Pad",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableActCsumAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableActCsumAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableActCsumAttrs<'a> {
type Item = Result<ActCsumAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => ActCsumAttrs::Parms({
let res = Some(next);
let Some(val) = res else { break };
val
}),
2u16 => ActCsumAttrs::Tm({
let res = Some(TcfT::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
3u16 => ActCsumAttrs::Pad({
let res = Some(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"ActCsumAttrs",
r#type.and_then(|t| ActCsumAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableActCsumAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("ActCsumAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
ActCsumAttrs::Parms(val) => fmt.field("Parms", &val),
ActCsumAttrs::Tm(val) => fmt.field("Tm", &val),
ActCsumAttrs::Pad(val) => fmt.field("Pad", &val),
};
}
fmt.finish()
}
}
impl IterableActCsumAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("ActCsumAttrs", offset));
return (
stack,
missing_type.and_then(|t| ActCsumAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
ActCsumAttrs::Parms(val) => {
if last_off == offset {
stack.push(("Parms", last_off));
break;
}
}
ActCsumAttrs::Tm(val) => {
if last_off == offset {
stack.push(("Tm", last_off));
break;
}
}
ActCsumAttrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("ActCsumAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum ActCtAttrs<'a> {
Parms(&'a [u8]),
Tm(TcfT),
Action(u16),
Zone(u16),
Mark(u32),
MarkMask(u32),
Labels(&'a [u8]),
LabelsMask(&'a [u8]),
NatIpv4Min(u32),
NatIpv4Max(u32),
NatIpv6Min(&'a [u8]),
NatIpv6Max(&'a [u8]),
NatPortMin(u16),
NatPortMax(u16),
Pad(&'a [u8]),
HelperName(&'a CStr),
HelperFamily(u8),
HelperProto(u8),
}
impl<'a> IterableActCtAttrs<'a> {
pub fn get_parms(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActCtAttrs::Parms(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActCtAttrs",
"Parms",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_tm(&self) -> Result<TcfT, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActCtAttrs::Tm(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActCtAttrs",
"Tm",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_action(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActCtAttrs::Action(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActCtAttrs",
"Action",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_zone(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActCtAttrs::Zone(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActCtAttrs",
"Zone",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_mark(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActCtAttrs::Mark(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActCtAttrs",
"Mark",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_mark_mask(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActCtAttrs::MarkMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActCtAttrs",
"MarkMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_labels(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActCtAttrs::Labels(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActCtAttrs",
"Labels",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_labels_mask(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActCtAttrs::LabelsMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActCtAttrs",
"LabelsMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_nat_ipv4_min(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActCtAttrs::NatIpv4Min(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActCtAttrs",
"NatIpv4Min",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_nat_ipv4_max(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActCtAttrs::NatIpv4Max(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActCtAttrs",
"NatIpv4Max",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_nat_ipv6_min(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActCtAttrs::NatIpv6Min(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActCtAttrs",
"NatIpv6Min",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_nat_ipv6_max(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActCtAttrs::NatIpv6Max(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActCtAttrs",
"NatIpv6Max",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_nat_port_min(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActCtAttrs::NatPortMin(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActCtAttrs",
"NatPortMin",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_nat_port_max(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActCtAttrs::NatPortMax(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActCtAttrs",
"NatPortMax",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActCtAttrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActCtAttrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_helper_name(&self) -> Result<&'a CStr, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActCtAttrs::HelperName(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActCtAttrs",
"HelperName",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_helper_family(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActCtAttrs::HelperFamily(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActCtAttrs",
"HelperFamily",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_helper_proto(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActCtAttrs::HelperProto(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActCtAttrs",
"HelperProto",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl ActCtAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableActCtAttrs<'a> {
IterableActCtAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Parms",
2u16 => "Tm",
3u16 => "Action",
4u16 => "Zone",
5u16 => "Mark",
6u16 => "MarkMask",
7u16 => "Labels",
8u16 => "LabelsMask",
9u16 => "NatIpv4Min",
10u16 => "NatIpv4Max",
11u16 => "NatIpv6Min",
12u16 => "NatIpv6Max",
13u16 => "NatPortMin",
14u16 => "NatPortMax",
15u16 => "Pad",
16u16 => "HelperName",
17u16 => "HelperFamily",
18u16 => "HelperProto",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableActCtAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableActCtAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableActCtAttrs<'a> {
type Item = Result<ActCtAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => ActCtAttrs::Parms({
let res = Some(next);
let Some(val) = res else { break };
val
}),
2u16 => ActCtAttrs::Tm({
let res = Some(TcfT::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
3u16 => ActCtAttrs::Action({
let res = parse_u16(next);
let Some(val) = res else { break };
val
}),
4u16 => ActCtAttrs::Zone({
let res = parse_u16(next);
let Some(val) = res else { break };
val
}),
5u16 => ActCtAttrs::Mark({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
6u16 => ActCtAttrs::MarkMask({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
7u16 => ActCtAttrs::Labels({
let res = Some(next);
let Some(val) = res else { break };
val
}),
8u16 => ActCtAttrs::LabelsMask({
let res = Some(next);
let Some(val) = res else { break };
val
}),
9u16 => ActCtAttrs::NatIpv4Min({
let res = parse_be_u32(next);
let Some(val) = res else { break };
val
}),
10u16 => ActCtAttrs::NatIpv4Max({
let res = parse_be_u32(next);
let Some(val) = res else { break };
val
}),
11u16 => ActCtAttrs::NatIpv6Min({
let res = Some(next);
let Some(val) = res else { break };
val
}),
12u16 => ActCtAttrs::NatIpv6Max({
let res = Some(next);
let Some(val) = res else { break };
val
}),
13u16 => ActCtAttrs::NatPortMin({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
14u16 => ActCtAttrs::NatPortMax({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
15u16 => ActCtAttrs::Pad({
let res = Some(next);
let Some(val) = res else { break };
val
}),
16u16 => ActCtAttrs::HelperName({
let res = CStr::from_bytes_with_nul(next).ok();
let Some(val) = res else { break };
val
}),
17u16 => ActCtAttrs::HelperFamily({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
18u16 => ActCtAttrs::HelperProto({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"ActCtAttrs",
r#type.and_then(|t| ActCtAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableActCtAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("ActCtAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
ActCtAttrs::Parms(val) => fmt.field("Parms", &val),
ActCtAttrs::Tm(val) => fmt.field("Tm", &val),
ActCtAttrs::Action(val) => fmt.field("Action", &val),
ActCtAttrs::Zone(val) => fmt.field("Zone", &val),
ActCtAttrs::Mark(val) => fmt.field("Mark", &val),
ActCtAttrs::MarkMask(val) => fmt.field("MarkMask", &val),
ActCtAttrs::Labels(val) => fmt.field("Labels", &val),
ActCtAttrs::LabelsMask(val) => fmt.field("LabelsMask", &val),
ActCtAttrs::NatIpv4Min(val) => fmt.field("NatIpv4Min", &val),
ActCtAttrs::NatIpv4Max(val) => fmt.field("NatIpv4Max", &val),
ActCtAttrs::NatIpv6Min(val) => fmt.field("NatIpv6Min", &val),
ActCtAttrs::NatIpv6Max(val) => fmt.field("NatIpv6Max", &val),
ActCtAttrs::NatPortMin(val) => fmt.field("NatPortMin", &val),
ActCtAttrs::NatPortMax(val) => fmt.field("NatPortMax", &val),
ActCtAttrs::Pad(val) => fmt.field("Pad", &val),
ActCtAttrs::HelperName(val) => fmt.field("HelperName", &val),
ActCtAttrs::HelperFamily(val) => fmt.field("HelperFamily", &val),
ActCtAttrs::HelperProto(val) => fmt.field("HelperProto", &val),
};
}
fmt.finish()
}
}
impl IterableActCtAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("ActCtAttrs", offset));
return (
stack,
missing_type.and_then(|t| ActCtAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
ActCtAttrs::Parms(val) => {
if last_off == offset {
stack.push(("Parms", last_off));
break;
}
}
ActCtAttrs::Tm(val) => {
if last_off == offset {
stack.push(("Tm", last_off));
break;
}
}
ActCtAttrs::Action(val) => {
if last_off == offset {
stack.push(("Action", last_off));
break;
}
}
ActCtAttrs::Zone(val) => {
if last_off == offset {
stack.push(("Zone", last_off));
break;
}
}
ActCtAttrs::Mark(val) => {
if last_off == offset {
stack.push(("Mark", last_off));
break;
}
}
ActCtAttrs::MarkMask(val) => {
if last_off == offset {
stack.push(("MarkMask", last_off));
break;
}
}
ActCtAttrs::Labels(val) => {
if last_off == offset {
stack.push(("Labels", last_off));
break;
}
}
ActCtAttrs::LabelsMask(val) => {
if last_off == offset {
stack.push(("LabelsMask", last_off));
break;
}
}
ActCtAttrs::NatIpv4Min(val) => {
if last_off == offset {
stack.push(("NatIpv4Min", last_off));
break;
}
}
ActCtAttrs::NatIpv4Max(val) => {
if last_off == offset {
stack.push(("NatIpv4Max", last_off));
break;
}
}
ActCtAttrs::NatIpv6Min(val) => {
if last_off == offset {
stack.push(("NatIpv6Min", last_off));
break;
}
}
ActCtAttrs::NatIpv6Max(val) => {
if last_off == offset {
stack.push(("NatIpv6Max", last_off));
break;
}
}
ActCtAttrs::NatPortMin(val) => {
if last_off == offset {
stack.push(("NatPortMin", last_off));
break;
}
}
ActCtAttrs::NatPortMax(val) => {
if last_off == offset {
stack.push(("NatPortMax", last_off));
break;
}
}
ActCtAttrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
ActCtAttrs::HelperName(val) => {
if last_off == offset {
stack.push(("HelperName", last_off));
break;
}
}
ActCtAttrs::HelperFamily(val) => {
if last_off == offset {
stack.push(("HelperFamily", last_off));
break;
}
}
ActCtAttrs::HelperProto(val) => {
if last_off == offset {
stack.push(("HelperProto", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("ActCtAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum ActCtinfoAttrs<'a> {
Pad(&'a [u8]),
Tm(TcfT),
Act(&'a [u8]),
Zone(u16),
ParmsDscpMask(u32),
ParmsDscpStatemask(u32),
ParmsCpmarkMask(u32),
StatsDscpSet(u64),
StatsDscpError(u64),
StatsCpmarkSet(u64),
}
impl<'a> IterableActCtinfoAttrs<'a> {
pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActCtinfoAttrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActCtinfoAttrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_tm(&self) -> Result<TcfT, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActCtinfoAttrs::Tm(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActCtinfoAttrs",
"Tm",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_act(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActCtinfoAttrs::Act(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActCtinfoAttrs",
"Act",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_zone(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActCtinfoAttrs::Zone(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActCtinfoAttrs",
"Zone",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_parms_dscp_mask(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActCtinfoAttrs::ParmsDscpMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActCtinfoAttrs",
"ParmsDscpMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_parms_dscp_statemask(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActCtinfoAttrs::ParmsDscpStatemask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActCtinfoAttrs",
"ParmsDscpStatemask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_parms_cpmark_mask(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActCtinfoAttrs::ParmsCpmarkMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActCtinfoAttrs",
"ParmsCpmarkMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_stats_dscp_set(&self) -> Result<u64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActCtinfoAttrs::StatsDscpSet(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActCtinfoAttrs",
"StatsDscpSet",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_stats_dscp_error(&self) -> Result<u64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActCtinfoAttrs::StatsDscpError(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActCtinfoAttrs",
"StatsDscpError",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_stats_cpmark_set(&self) -> Result<u64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActCtinfoAttrs::StatsCpmarkSet(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActCtinfoAttrs",
"StatsCpmarkSet",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl ActCtinfoAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableActCtinfoAttrs<'a> {
IterableActCtinfoAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Pad",
2u16 => "Tm",
3u16 => "Act",
4u16 => "Zone",
5u16 => "ParmsDscpMask",
6u16 => "ParmsDscpStatemask",
7u16 => "ParmsCpmarkMask",
8u16 => "StatsDscpSet",
9u16 => "StatsDscpError",
10u16 => "StatsCpmarkSet",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableActCtinfoAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableActCtinfoAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableActCtinfoAttrs<'a> {
type Item = Result<ActCtinfoAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => ActCtinfoAttrs::Pad({
let res = Some(next);
let Some(val) = res else { break };
val
}),
2u16 => ActCtinfoAttrs::Tm({
let res = Some(TcfT::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
3u16 => ActCtinfoAttrs::Act({
let res = Some(next);
let Some(val) = res else { break };
val
}),
4u16 => ActCtinfoAttrs::Zone({
let res = parse_u16(next);
let Some(val) = res else { break };
val
}),
5u16 => ActCtinfoAttrs::ParmsDscpMask({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
6u16 => ActCtinfoAttrs::ParmsDscpStatemask({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
7u16 => ActCtinfoAttrs::ParmsCpmarkMask({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
8u16 => ActCtinfoAttrs::StatsDscpSet({
let res = parse_u64(next);
let Some(val) = res else { break };
val
}),
9u16 => ActCtinfoAttrs::StatsDscpError({
let res = parse_u64(next);
let Some(val) = res else { break };
val
}),
10u16 => ActCtinfoAttrs::StatsCpmarkSet({
let res = parse_u64(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"ActCtinfoAttrs",
r#type.and_then(|t| ActCtinfoAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableActCtinfoAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("ActCtinfoAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
ActCtinfoAttrs::Pad(val) => fmt.field("Pad", &val),
ActCtinfoAttrs::Tm(val) => fmt.field("Tm", &val),
ActCtinfoAttrs::Act(val) => fmt.field("Act", &val),
ActCtinfoAttrs::Zone(val) => fmt.field("Zone", &val),
ActCtinfoAttrs::ParmsDscpMask(val) => fmt.field("ParmsDscpMask", &val),
ActCtinfoAttrs::ParmsDscpStatemask(val) => fmt.field("ParmsDscpStatemask", &val),
ActCtinfoAttrs::ParmsCpmarkMask(val) => fmt.field("ParmsCpmarkMask", &val),
ActCtinfoAttrs::StatsDscpSet(val) => fmt.field("StatsDscpSet", &val),
ActCtinfoAttrs::StatsDscpError(val) => fmt.field("StatsDscpError", &val),
ActCtinfoAttrs::StatsCpmarkSet(val) => fmt.field("StatsCpmarkSet", &val),
};
}
fmt.finish()
}
}
impl IterableActCtinfoAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("ActCtinfoAttrs", offset));
return (
stack,
missing_type.and_then(|t| ActCtinfoAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
ActCtinfoAttrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
ActCtinfoAttrs::Tm(val) => {
if last_off == offset {
stack.push(("Tm", last_off));
break;
}
}
ActCtinfoAttrs::Act(val) => {
if last_off == offset {
stack.push(("Act", last_off));
break;
}
}
ActCtinfoAttrs::Zone(val) => {
if last_off == offset {
stack.push(("Zone", last_off));
break;
}
}
ActCtinfoAttrs::ParmsDscpMask(val) => {
if last_off == offset {
stack.push(("ParmsDscpMask", last_off));
break;
}
}
ActCtinfoAttrs::ParmsDscpStatemask(val) => {
if last_off == offset {
stack.push(("ParmsDscpStatemask", last_off));
break;
}
}
ActCtinfoAttrs::ParmsCpmarkMask(val) => {
if last_off == offset {
stack.push(("ParmsCpmarkMask", last_off));
break;
}
}
ActCtinfoAttrs::StatsDscpSet(val) => {
if last_off == offset {
stack.push(("StatsDscpSet", last_off));
break;
}
}
ActCtinfoAttrs::StatsDscpError(val) => {
if last_off == offset {
stack.push(("StatsDscpError", last_off));
break;
}
}
ActCtinfoAttrs::StatsCpmarkSet(val) => {
if last_off == offset {
stack.push(("StatsCpmarkSet", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("ActCtinfoAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum ActGateAttrs<'a> {
Tm(TcfT),
Parms(&'a [u8]),
Pad(&'a [u8]),
Priority(i32),
EntryList(&'a [u8]),
BaseTime(u64),
CycleTime(u64),
CycleTimeExt(u64),
Flags(u32),
Clockid(i32),
}
impl<'a> IterableActGateAttrs<'a> {
pub fn get_tm(&self) -> Result<TcfT, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActGateAttrs::Tm(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActGateAttrs",
"Tm",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_parms(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActGateAttrs::Parms(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActGateAttrs",
"Parms",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActGateAttrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActGateAttrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_priority(&self) -> Result<i32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActGateAttrs::Priority(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActGateAttrs",
"Priority",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_entry_list(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActGateAttrs::EntryList(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActGateAttrs",
"EntryList",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_base_time(&self) -> Result<u64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActGateAttrs::BaseTime(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActGateAttrs",
"BaseTime",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_cycle_time(&self) -> Result<u64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActGateAttrs::CycleTime(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActGateAttrs",
"CycleTime",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_cycle_time_ext(&self) -> Result<u64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActGateAttrs::CycleTimeExt(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActGateAttrs",
"CycleTimeExt",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_flags(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActGateAttrs::Flags(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActGateAttrs",
"Flags",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_clockid(&self) -> Result<i32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActGateAttrs::Clockid(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActGateAttrs",
"Clockid",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl ActGateAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableActGateAttrs<'a> {
IterableActGateAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Tm",
2u16 => "Parms",
3u16 => "Pad",
4u16 => "Priority",
5u16 => "EntryList",
6u16 => "BaseTime",
7u16 => "CycleTime",
8u16 => "CycleTimeExt",
9u16 => "Flags",
10u16 => "Clockid",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableActGateAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableActGateAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableActGateAttrs<'a> {
type Item = Result<ActGateAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => ActGateAttrs::Tm({
let res = Some(TcfT::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
2u16 => ActGateAttrs::Parms({
let res = Some(next);
let Some(val) = res else { break };
val
}),
3u16 => ActGateAttrs::Pad({
let res = Some(next);
let Some(val) = res else { break };
val
}),
4u16 => ActGateAttrs::Priority({
let res = parse_i32(next);
let Some(val) = res else { break };
val
}),
5u16 => ActGateAttrs::EntryList({
let res = Some(next);
let Some(val) = res else { break };
val
}),
6u16 => ActGateAttrs::BaseTime({
let res = parse_u64(next);
let Some(val) = res else { break };
val
}),
7u16 => ActGateAttrs::CycleTime({
let res = parse_u64(next);
let Some(val) = res else { break };
val
}),
8u16 => ActGateAttrs::CycleTimeExt({
let res = parse_u64(next);
let Some(val) = res else { break };
val
}),
9u16 => ActGateAttrs::Flags({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
10u16 => ActGateAttrs::Clockid({
let res = parse_i32(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"ActGateAttrs",
r#type.and_then(|t| ActGateAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableActGateAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("ActGateAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
ActGateAttrs::Tm(val) => fmt.field("Tm", &val),
ActGateAttrs::Parms(val) => fmt.field("Parms", &val),
ActGateAttrs::Pad(val) => fmt.field("Pad", &val),
ActGateAttrs::Priority(val) => fmt.field("Priority", &val),
ActGateAttrs::EntryList(val) => fmt.field("EntryList", &val),
ActGateAttrs::BaseTime(val) => fmt.field("BaseTime", &val),
ActGateAttrs::CycleTime(val) => fmt.field("CycleTime", &val),
ActGateAttrs::CycleTimeExt(val) => fmt.field("CycleTimeExt", &val),
ActGateAttrs::Flags(val) => fmt.field("Flags", &val),
ActGateAttrs::Clockid(val) => fmt.field("Clockid", &val),
};
}
fmt.finish()
}
}
impl IterableActGateAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("ActGateAttrs", offset));
return (
stack,
missing_type.and_then(|t| ActGateAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
ActGateAttrs::Tm(val) => {
if last_off == offset {
stack.push(("Tm", last_off));
break;
}
}
ActGateAttrs::Parms(val) => {
if last_off == offset {
stack.push(("Parms", last_off));
break;
}
}
ActGateAttrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
ActGateAttrs::Priority(val) => {
if last_off == offset {
stack.push(("Priority", last_off));
break;
}
}
ActGateAttrs::EntryList(val) => {
if last_off == offset {
stack.push(("EntryList", last_off));
break;
}
}
ActGateAttrs::BaseTime(val) => {
if last_off == offset {
stack.push(("BaseTime", last_off));
break;
}
}
ActGateAttrs::CycleTime(val) => {
if last_off == offset {
stack.push(("CycleTime", last_off));
break;
}
}
ActGateAttrs::CycleTimeExt(val) => {
if last_off == offset {
stack.push(("CycleTimeExt", last_off));
break;
}
}
ActGateAttrs::Flags(val) => {
if last_off == offset {
stack.push(("Flags", last_off));
break;
}
}
ActGateAttrs::Clockid(val) => {
if last_off == offset {
stack.push(("Clockid", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("ActGateAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum ActIfeAttrs<'a> {
Parms(&'a [u8]),
Tm(TcfT),
Dmac(&'a [u8]),
Smac(&'a [u8]),
Type(u16),
Metalst(&'a [u8]),
Pad(&'a [u8]),
}
impl<'a> IterableActIfeAttrs<'a> {
pub fn get_parms(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActIfeAttrs::Parms(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActIfeAttrs",
"Parms",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_tm(&self) -> Result<TcfT, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActIfeAttrs::Tm(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActIfeAttrs",
"Tm",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_dmac(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActIfeAttrs::Dmac(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActIfeAttrs",
"Dmac",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_smac(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActIfeAttrs::Smac(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActIfeAttrs",
"Smac",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_type(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActIfeAttrs::Type(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActIfeAttrs",
"Type",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_metalst(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActIfeAttrs::Metalst(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActIfeAttrs",
"Metalst",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActIfeAttrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActIfeAttrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl ActIfeAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableActIfeAttrs<'a> {
IterableActIfeAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Parms",
2u16 => "Tm",
3u16 => "Dmac",
4u16 => "Smac",
5u16 => "Type",
6u16 => "Metalst",
7u16 => "Pad",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableActIfeAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableActIfeAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableActIfeAttrs<'a> {
type Item = Result<ActIfeAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => ActIfeAttrs::Parms({
let res = Some(next);
let Some(val) = res else { break };
val
}),
2u16 => ActIfeAttrs::Tm({
let res = Some(TcfT::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
3u16 => ActIfeAttrs::Dmac({
let res = Some(next);
let Some(val) = res else { break };
val
}),
4u16 => ActIfeAttrs::Smac({
let res = Some(next);
let Some(val) = res else { break };
val
}),
5u16 => ActIfeAttrs::Type({
let res = parse_u16(next);
let Some(val) = res else { break };
val
}),
6u16 => ActIfeAttrs::Metalst({
let res = Some(next);
let Some(val) = res else { break };
val
}),
7u16 => ActIfeAttrs::Pad({
let res = Some(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"ActIfeAttrs",
r#type.and_then(|t| ActIfeAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableActIfeAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("ActIfeAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
ActIfeAttrs::Parms(val) => fmt.field("Parms", &val),
ActIfeAttrs::Tm(val) => fmt.field("Tm", &val),
ActIfeAttrs::Dmac(val) => fmt.field("Dmac", &val),
ActIfeAttrs::Smac(val) => fmt.field("Smac", &val),
ActIfeAttrs::Type(val) => fmt.field("Type", &val),
ActIfeAttrs::Metalst(val) => fmt.field("Metalst", &val),
ActIfeAttrs::Pad(val) => fmt.field("Pad", &val),
};
}
fmt.finish()
}
}
impl IterableActIfeAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("ActIfeAttrs", offset));
return (
stack,
missing_type.and_then(|t| ActIfeAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
ActIfeAttrs::Parms(val) => {
if last_off == offset {
stack.push(("Parms", last_off));
break;
}
}
ActIfeAttrs::Tm(val) => {
if last_off == offset {
stack.push(("Tm", last_off));
break;
}
}
ActIfeAttrs::Dmac(val) => {
if last_off == offset {
stack.push(("Dmac", last_off));
break;
}
}
ActIfeAttrs::Smac(val) => {
if last_off == offset {
stack.push(("Smac", last_off));
break;
}
}
ActIfeAttrs::Type(val) => {
if last_off == offset {
stack.push(("Type", last_off));
break;
}
}
ActIfeAttrs::Metalst(val) => {
if last_off == offset {
stack.push(("Metalst", last_off));
break;
}
}
ActIfeAttrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("ActIfeAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum ActMirredAttrs<'a> {
Tm(TcfT),
Parms(&'a [u8]),
Pad(&'a [u8]),
Blockid(&'a [u8]),
}
impl<'a> IterableActMirredAttrs<'a> {
pub fn get_tm(&self) -> Result<TcfT, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActMirredAttrs::Tm(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActMirredAttrs",
"Tm",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_parms(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActMirredAttrs::Parms(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActMirredAttrs",
"Parms",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActMirredAttrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActMirredAttrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_blockid(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActMirredAttrs::Blockid(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActMirredAttrs",
"Blockid",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl ActMirredAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableActMirredAttrs<'a> {
IterableActMirredAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Tm",
2u16 => "Parms",
3u16 => "Pad",
4u16 => "Blockid",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableActMirredAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableActMirredAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableActMirredAttrs<'a> {
type Item = Result<ActMirredAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => ActMirredAttrs::Tm({
let res = Some(TcfT::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
2u16 => ActMirredAttrs::Parms({
let res = Some(next);
let Some(val) = res else { break };
val
}),
3u16 => ActMirredAttrs::Pad({
let res = Some(next);
let Some(val) = res else { break };
val
}),
4u16 => ActMirredAttrs::Blockid({
let res = Some(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"ActMirredAttrs",
r#type.and_then(|t| ActMirredAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableActMirredAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("ActMirredAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
ActMirredAttrs::Tm(val) => fmt.field("Tm", &val),
ActMirredAttrs::Parms(val) => fmt.field("Parms", &val),
ActMirredAttrs::Pad(val) => fmt.field("Pad", &val),
ActMirredAttrs::Blockid(val) => fmt.field("Blockid", &val),
};
}
fmt.finish()
}
}
impl IterableActMirredAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("ActMirredAttrs", offset));
return (
stack,
missing_type.and_then(|t| ActMirredAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
ActMirredAttrs::Tm(val) => {
if last_off == offset {
stack.push(("Tm", last_off));
break;
}
}
ActMirredAttrs::Parms(val) => {
if last_off == offset {
stack.push(("Parms", last_off));
break;
}
}
ActMirredAttrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
ActMirredAttrs::Blockid(val) => {
if last_off == offset {
stack.push(("Blockid", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("ActMirredAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum ActMplsAttrs<'a> {
Tm(TcfT),
Parms(TcMpls),
Pad(&'a [u8]),
Proto(u16),
Label(u32),
Tc(u8),
Ttl(u8),
Bos(u8),
}
impl<'a> IterableActMplsAttrs<'a> {
pub fn get_tm(&self) -> Result<TcfT, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActMplsAttrs::Tm(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActMplsAttrs",
"Tm",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_parms(&self) -> Result<TcMpls, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActMplsAttrs::Parms(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActMplsAttrs",
"Parms",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActMplsAttrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActMplsAttrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_proto(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActMplsAttrs::Proto(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActMplsAttrs",
"Proto",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_label(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActMplsAttrs::Label(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActMplsAttrs",
"Label",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_tc(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActMplsAttrs::Tc(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActMplsAttrs",
"Tc",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_ttl(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActMplsAttrs::Ttl(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActMplsAttrs",
"Ttl",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_bos(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActMplsAttrs::Bos(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActMplsAttrs",
"Bos",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl ActMplsAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableActMplsAttrs<'a> {
IterableActMplsAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Tm",
2u16 => "Parms",
3u16 => "Pad",
4u16 => "Proto",
5u16 => "Label",
6u16 => "Tc",
7u16 => "Ttl",
8u16 => "Bos",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableActMplsAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableActMplsAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableActMplsAttrs<'a> {
type Item = Result<ActMplsAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => ActMplsAttrs::Tm({
let res = Some(TcfT::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
2u16 => ActMplsAttrs::Parms({
let res = Some(TcMpls::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
3u16 => ActMplsAttrs::Pad({
let res = Some(next);
let Some(val) = res else { break };
val
}),
4u16 => ActMplsAttrs::Proto({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
5u16 => ActMplsAttrs::Label({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
6u16 => ActMplsAttrs::Tc({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
7u16 => ActMplsAttrs::Ttl({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
8u16 => ActMplsAttrs::Bos({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"ActMplsAttrs",
r#type.and_then(|t| ActMplsAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableActMplsAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("ActMplsAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
ActMplsAttrs::Tm(val) => fmt.field("Tm", &val),
ActMplsAttrs::Parms(val) => fmt.field("Parms", &val),
ActMplsAttrs::Pad(val) => fmt.field("Pad", &val),
ActMplsAttrs::Proto(val) => fmt.field("Proto", &val),
ActMplsAttrs::Label(val) => fmt.field("Label", &val),
ActMplsAttrs::Tc(val) => fmt.field("Tc", &val),
ActMplsAttrs::Ttl(val) => fmt.field("Ttl", &val),
ActMplsAttrs::Bos(val) => fmt.field("Bos", &val),
};
}
fmt.finish()
}
}
impl IterableActMplsAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("ActMplsAttrs", offset));
return (
stack,
missing_type.and_then(|t| ActMplsAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
ActMplsAttrs::Tm(val) => {
if last_off == offset {
stack.push(("Tm", last_off));
break;
}
}
ActMplsAttrs::Parms(val) => {
if last_off == offset {
stack.push(("Parms", last_off));
break;
}
}
ActMplsAttrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
ActMplsAttrs::Proto(val) => {
if last_off == offset {
stack.push(("Proto", last_off));
break;
}
}
ActMplsAttrs::Label(val) => {
if last_off == offset {
stack.push(("Label", last_off));
break;
}
}
ActMplsAttrs::Tc(val) => {
if last_off == offset {
stack.push(("Tc", last_off));
break;
}
}
ActMplsAttrs::Ttl(val) => {
if last_off == offset {
stack.push(("Ttl", last_off));
break;
}
}
ActMplsAttrs::Bos(val) => {
if last_off == offset {
stack.push(("Bos", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("ActMplsAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum ActNatAttrs<'a> {
Parms(&'a [u8]),
Tm(TcfT),
Pad(&'a [u8]),
}
impl<'a> IterableActNatAttrs<'a> {
pub fn get_parms(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActNatAttrs::Parms(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActNatAttrs",
"Parms",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_tm(&self) -> Result<TcfT, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActNatAttrs::Tm(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActNatAttrs",
"Tm",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActNatAttrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActNatAttrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl ActNatAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableActNatAttrs<'a> {
IterableActNatAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Parms",
2u16 => "Tm",
3u16 => "Pad",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableActNatAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableActNatAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableActNatAttrs<'a> {
type Item = Result<ActNatAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => ActNatAttrs::Parms({
let res = Some(next);
let Some(val) = res else { break };
val
}),
2u16 => ActNatAttrs::Tm({
let res = Some(TcfT::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
3u16 => ActNatAttrs::Pad({
let res = Some(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"ActNatAttrs",
r#type.and_then(|t| ActNatAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableActNatAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("ActNatAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
ActNatAttrs::Parms(val) => fmt.field("Parms", &val),
ActNatAttrs::Tm(val) => fmt.field("Tm", &val),
ActNatAttrs::Pad(val) => fmt.field("Pad", &val),
};
}
fmt.finish()
}
}
impl IterableActNatAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("ActNatAttrs", offset));
return (
stack,
missing_type.and_then(|t| ActNatAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
ActNatAttrs::Parms(val) => {
if last_off == offset {
stack.push(("Parms", last_off));
break;
}
}
ActNatAttrs::Tm(val) => {
if last_off == offset {
stack.push(("Tm", last_off));
break;
}
}
ActNatAttrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("ActNatAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum ActPeditAttrs<'a> {
Tm(TcfT),
Parms(TcPeditSel),
Pad(&'a [u8]),
ParmsEx(&'a [u8]),
KeysEx(&'a [u8]),
KeyEx(&'a [u8]),
}
impl<'a> IterableActPeditAttrs<'a> {
pub fn get_tm(&self) -> Result<TcfT, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActPeditAttrs::Tm(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActPeditAttrs",
"Tm",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_parms(&self) -> Result<TcPeditSel, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActPeditAttrs::Parms(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActPeditAttrs",
"Parms",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActPeditAttrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActPeditAttrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_parms_ex(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActPeditAttrs::ParmsEx(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActPeditAttrs",
"ParmsEx",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_keys_ex(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActPeditAttrs::KeysEx(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActPeditAttrs",
"KeysEx",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_ex(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActPeditAttrs::KeyEx(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActPeditAttrs",
"KeyEx",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl ActPeditAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableActPeditAttrs<'a> {
IterableActPeditAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Tm",
2u16 => "Parms",
3u16 => "Pad",
4u16 => "ParmsEx",
5u16 => "KeysEx",
6u16 => "KeyEx",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableActPeditAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableActPeditAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableActPeditAttrs<'a> {
type Item = Result<ActPeditAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => ActPeditAttrs::Tm({
let res = Some(TcfT::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
2u16 => ActPeditAttrs::Parms({
let res = Some(TcPeditSel::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
3u16 => ActPeditAttrs::Pad({
let res = Some(next);
let Some(val) = res else { break };
val
}),
4u16 => ActPeditAttrs::ParmsEx({
let res = Some(next);
let Some(val) = res else { break };
val
}),
5u16 => ActPeditAttrs::KeysEx({
let res = Some(next);
let Some(val) = res else { break };
val
}),
6u16 => ActPeditAttrs::KeyEx({
let res = Some(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"ActPeditAttrs",
r#type.and_then(|t| ActPeditAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableActPeditAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("ActPeditAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
ActPeditAttrs::Tm(val) => fmt.field("Tm", &val),
ActPeditAttrs::Parms(val) => fmt.field("Parms", &val),
ActPeditAttrs::Pad(val) => fmt.field("Pad", &val),
ActPeditAttrs::ParmsEx(val) => fmt.field("ParmsEx", &val),
ActPeditAttrs::KeysEx(val) => fmt.field("KeysEx", &val),
ActPeditAttrs::KeyEx(val) => fmt.field("KeyEx", &val),
};
}
fmt.finish()
}
}
impl IterableActPeditAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("ActPeditAttrs", offset));
return (
stack,
missing_type.and_then(|t| ActPeditAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
ActPeditAttrs::Tm(val) => {
if last_off == offset {
stack.push(("Tm", last_off));
break;
}
}
ActPeditAttrs::Parms(val) => {
if last_off == offset {
stack.push(("Parms", last_off));
break;
}
}
ActPeditAttrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
ActPeditAttrs::ParmsEx(val) => {
if last_off == offset {
stack.push(("ParmsEx", last_off));
break;
}
}
ActPeditAttrs::KeysEx(val) => {
if last_off == offset {
stack.push(("KeysEx", last_off));
break;
}
}
ActPeditAttrs::KeyEx(val) => {
if last_off == offset {
stack.push(("KeyEx", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("ActPeditAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum ActSimpleAttrs<'a> {
Tm(TcfT),
Parms(&'a [u8]),
Data(&'a [u8]),
Pad(&'a [u8]),
}
impl<'a> IterableActSimpleAttrs<'a> {
pub fn get_tm(&self) -> Result<TcfT, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActSimpleAttrs::Tm(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActSimpleAttrs",
"Tm",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_parms(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActSimpleAttrs::Parms(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActSimpleAttrs",
"Parms",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_data(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActSimpleAttrs::Data(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActSimpleAttrs",
"Data",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActSimpleAttrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActSimpleAttrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl ActSimpleAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableActSimpleAttrs<'a> {
IterableActSimpleAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Tm",
2u16 => "Parms",
3u16 => "Data",
4u16 => "Pad",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableActSimpleAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableActSimpleAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableActSimpleAttrs<'a> {
type Item = Result<ActSimpleAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => ActSimpleAttrs::Tm({
let res = Some(TcfT::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
2u16 => ActSimpleAttrs::Parms({
let res = Some(next);
let Some(val) = res else { break };
val
}),
3u16 => ActSimpleAttrs::Data({
let res = Some(next);
let Some(val) = res else { break };
val
}),
4u16 => ActSimpleAttrs::Pad({
let res = Some(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"ActSimpleAttrs",
r#type.and_then(|t| ActSimpleAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableActSimpleAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("ActSimpleAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
ActSimpleAttrs::Tm(val) => fmt.field("Tm", &val),
ActSimpleAttrs::Parms(val) => fmt.field("Parms", &val),
ActSimpleAttrs::Data(val) => fmt.field("Data", &val),
ActSimpleAttrs::Pad(val) => fmt.field("Pad", &val),
};
}
fmt.finish()
}
}
impl IterableActSimpleAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("ActSimpleAttrs", offset));
return (
stack,
missing_type.and_then(|t| ActSimpleAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
ActSimpleAttrs::Tm(val) => {
if last_off == offset {
stack.push(("Tm", last_off));
break;
}
}
ActSimpleAttrs::Parms(val) => {
if last_off == offset {
stack.push(("Parms", last_off));
break;
}
}
ActSimpleAttrs::Data(val) => {
if last_off == offset {
stack.push(("Data", last_off));
break;
}
}
ActSimpleAttrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("ActSimpleAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum ActSkbeditAttrs<'a> {
Tm(TcfT),
Parms(&'a [u8]),
Priority(u32),
QueueMapping(u16),
Mark(u32),
Pad(&'a [u8]),
Ptype(u16),
Mask(u32),
Flags(u64),
QueueMappingMax(u16),
}
impl<'a> IterableActSkbeditAttrs<'a> {
pub fn get_tm(&self) -> Result<TcfT, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActSkbeditAttrs::Tm(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActSkbeditAttrs",
"Tm",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_parms(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActSkbeditAttrs::Parms(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActSkbeditAttrs",
"Parms",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_priority(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActSkbeditAttrs::Priority(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActSkbeditAttrs",
"Priority",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_queue_mapping(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActSkbeditAttrs::QueueMapping(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActSkbeditAttrs",
"QueueMapping",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_mark(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActSkbeditAttrs::Mark(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActSkbeditAttrs",
"Mark",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActSkbeditAttrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActSkbeditAttrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_ptype(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActSkbeditAttrs::Ptype(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActSkbeditAttrs",
"Ptype",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_mask(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActSkbeditAttrs::Mask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActSkbeditAttrs",
"Mask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_flags(&self) -> Result<u64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActSkbeditAttrs::Flags(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActSkbeditAttrs",
"Flags",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_queue_mapping_max(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActSkbeditAttrs::QueueMappingMax(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActSkbeditAttrs",
"QueueMappingMax",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl ActSkbeditAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableActSkbeditAttrs<'a> {
IterableActSkbeditAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Tm",
2u16 => "Parms",
3u16 => "Priority",
4u16 => "QueueMapping",
5u16 => "Mark",
6u16 => "Pad",
7u16 => "Ptype",
8u16 => "Mask",
9u16 => "Flags",
10u16 => "QueueMappingMax",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableActSkbeditAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableActSkbeditAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableActSkbeditAttrs<'a> {
type Item = Result<ActSkbeditAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => ActSkbeditAttrs::Tm({
let res = Some(TcfT::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
2u16 => ActSkbeditAttrs::Parms({
let res = Some(next);
let Some(val) = res else { break };
val
}),
3u16 => ActSkbeditAttrs::Priority({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
4u16 => ActSkbeditAttrs::QueueMapping({
let res = parse_u16(next);
let Some(val) = res else { break };
val
}),
5u16 => ActSkbeditAttrs::Mark({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
6u16 => ActSkbeditAttrs::Pad({
let res = Some(next);
let Some(val) = res else { break };
val
}),
7u16 => ActSkbeditAttrs::Ptype({
let res = parse_u16(next);
let Some(val) = res else { break };
val
}),
8u16 => ActSkbeditAttrs::Mask({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
9u16 => ActSkbeditAttrs::Flags({
let res = parse_u64(next);
let Some(val) = res else { break };
val
}),
10u16 => ActSkbeditAttrs::QueueMappingMax({
let res = parse_u16(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"ActSkbeditAttrs",
r#type.and_then(|t| ActSkbeditAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableActSkbeditAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("ActSkbeditAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
ActSkbeditAttrs::Tm(val) => fmt.field("Tm", &val),
ActSkbeditAttrs::Parms(val) => fmt.field("Parms", &val),
ActSkbeditAttrs::Priority(val) => fmt.field("Priority", &val),
ActSkbeditAttrs::QueueMapping(val) => fmt.field("QueueMapping", &val),
ActSkbeditAttrs::Mark(val) => fmt.field("Mark", &val),
ActSkbeditAttrs::Pad(val) => fmt.field("Pad", &val),
ActSkbeditAttrs::Ptype(val) => fmt.field("Ptype", &val),
ActSkbeditAttrs::Mask(val) => fmt.field("Mask", &val),
ActSkbeditAttrs::Flags(val) => fmt.field("Flags", &val),
ActSkbeditAttrs::QueueMappingMax(val) => fmt.field("QueueMappingMax", &val),
};
}
fmt.finish()
}
}
impl IterableActSkbeditAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("ActSkbeditAttrs", offset));
return (
stack,
missing_type.and_then(|t| ActSkbeditAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
ActSkbeditAttrs::Tm(val) => {
if last_off == offset {
stack.push(("Tm", last_off));
break;
}
}
ActSkbeditAttrs::Parms(val) => {
if last_off == offset {
stack.push(("Parms", last_off));
break;
}
}
ActSkbeditAttrs::Priority(val) => {
if last_off == offset {
stack.push(("Priority", last_off));
break;
}
}
ActSkbeditAttrs::QueueMapping(val) => {
if last_off == offset {
stack.push(("QueueMapping", last_off));
break;
}
}
ActSkbeditAttrs::Mark(val) => {
if last_off == offset {
stack.push(("Mark", last_off));
break;
}
}
ActSkbeditAttrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
ActSkbeditAttrs::Ptype(val) => {
if last_off == offset {
stack.push(("Ptype", last_off));
break;
}
}
ActSkbeditAttrs::Mask(val) => {
if last_off == offset {
stack.push(("Mask", last_off));
break;
}
}
ActSkbeditAttrs::Flags(val) => {
if last_off == offset {
stack.push(("Flags", last_off));
break;
}
}
ActSkbeditAttrs::QueueMappingMax(val) => {
if last_off == offset {
stack.push(("QueueMappingMax", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("ActSkbeditAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum ActSkbmodAttrs<'a> {
Tm(TcfT),
Parms(&'a [u8]),
Dmac(&'a [u8]),
Smac(&'a [u8]),
Etype(&'a [u8]),
Pad(&'a [u8]),
}
impl<'a> IterableActSkbmodAttrs<'a> {
pub fn get_tm(&self) -> Result<TcfT, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActSkbmodAttrs::Tm(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActSkbmodAttrs",
"Tm",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_parms(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActSkbmodAttrs::Parms(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActSkbmodAttrs",
"Parms",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_dmac(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActSkbmodAttrs::Dmac(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActSkbmodAttrs",
"Dmac",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_smac(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActSkbmodAttrs::Smac(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActSkbmodAttrs",
"Smac",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_etype(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActSkbmodAttrs::Etype(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActSkbmodAttrs",
"Etype",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActSkbmodAttrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActSkbmodAttrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl ActSkbmodAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableActSkbmodAttrs<'a> {
IterableActSkbmodAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Tm",
2u16 => "Parms",
3u16 => "Dmac",
4u16 => "Smac",
5u16 => "Etype",
6u16 => "Pad",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableActSkbmodAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableActSkbmodAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableActSkbmodAttrs<'a> {
type Item = Result<ActSkbmodAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => ActSkbmodAttrs::Tm({
let res = Some(TcfT::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
2u16 => ActSkbmodAttrs::Parms({
let res = Some(next);
let Some(val) = res else { break };
val
}),
3u16 => ActSkbmodAttrs::Dmac({
let res = Some(next);
let Some(val) = res else { break };
val
}),
4u16 => ActSkbmodAttrs::Smac({
let res = Some(next);
let Some(val) = res else { break };
val
}),
5u16 => ActSkbmodAttrs::Etype({
let res = Some(next);
let Some(val) = res else { break };
val
}),
6u16 => ActSkbmodAttrs::Pad({
let res = Some(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"ActSkbmodAttrs",
r#type.and_then(|t| ActSkbmodAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableActSkbmodAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("ActSkbmodAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
ActSkbmodAttrs::Tm(val) => fmt.field("Tm", &val),
ActSkbmodAttrs::Parms(val) => fmt.field("Parms", &val),
ActSkbmodAttrs::Dmac(val) => fmt.field("Dmac", &val),
ActSkbmodAttrs::Smac(val) => fmt.field("Smac", &val),
ActSkbmodAttrs::Etype(val) => fmt.field("Etype", &val),
ActSkbmodAttrs::Pad(val) => fmt.field("Pad", &val),
};
}
fmt.finish()
}
}
impl IterableActSkbmodAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("ActSkbmodAttrs", offset));
return (
stack,
missing_type.and_then(|t| ActSkbmodAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
ActSkbmodAttrs::Tm(val) => {
if last_off == offset {
stack.push(("Tm", last_off));
break;
}
}
ActSkbmodAttrs::Parms(val) => {
if last_off == offset {
stack.push(("Parms", last_off));
break;
}
}
ActSkbmodAttrs::Dmac(val) => {
if last_off == offset {
stack.push(("Dmac", last_off));
break;
}
}
ActSkbmodAttrs::Smac(val) => {
if last_off == offset {
stack.push(("Smac", last_off));
break;
}
}
ActSkbmodAttrs::Etype(val) => {
if last_off == offset {
stack.push(("Etype", last_off));
break;
}
}
ActSkbmodAttrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("ActSkbmodAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum ActTunnelKeyAttrs<'a> {
Tm(TcfT),
Parms(&'a [u8]),
EncIpv4Src(u32),
EncIpv4Dst(u32),
EncIpv6Src(&'a [u8]),
EncIpv6Dst(&'a [u8]),
EncKeyId(u64),
Pad(&'a [u8]),
EncDstPort(u16),
NoCsum(u8),
EncOpts(&'a [u8]),
EncTos(u8),
EncTtl(u8),
NoFrag(()),
}
impl<'a> IterableActTunnelKeyAttrs<'a> {
pub fn get_tm(&self) -> Result<TcfT, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActTunnelKeyAttrs::Tm(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActTunnelKeyAttrs",
"Tm",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_parms(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActTunnelKeyAttrs::Parms(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActTunnelKeyAttrs",
"Parms",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_enc_ipv4_src(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActTunnelKeyAttrs::EncIpv4Src(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActTunnelKeyAttrs",
"EncIpv4Src",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_enc_ipv4_dst(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActTunnelKeyAttrs::EncIpv4Dst(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActTunnelKeyAttrs",
"EncIpv4Dst",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_enc_ipv6_src(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActTunnelKeyAttrs::EncIpv6Src(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActTunnelKeyAttrs",
"EncIpv6Src",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_enc_ipv6_dst(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActTunnelKeyAttrs::EncIpv6Dst(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActTunnelKeyAttrs",
"EncIpv6Dst",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_enc_key_id(&self) -> Result<u64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActTunnelKeyAttrs::EncKeyId(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActTunnelKeyAttrs",
"EncKeyId",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActTunnelKeyAttrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActTunnelKeyAttrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_enc_dst_port(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActTunnelKeyAttrs::EncDstPort(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActTunnelKeyAttrs",
"EncDstPort",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_no_csum(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActTunnelKeyAttrs::NoCsum(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActTunnelKeyAttrs",
"NoCsum",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_enc_opts(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActTunnelKeyAttrs::EncOpts(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActTunnelKeyAttrs",
"EncOpts",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_enc_tos(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActTunnelKeyAttrs::EncTos(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActTunnelKeyAttrs",
"EncTos",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_enc_ttl(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActTunnelKeyAttrs::EncTtl(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActTunnelKeyAttrs",
"EncTtl",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_no_frag(&self) -> Result<(), ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActTunnelKeyAttrs::NoFrag(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActTunnelKeyAttrs",
"NoFrag",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl ActTunnelKeyAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableActTunnelKeyAttrs<'a> {
IterableActTunnelKeyAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Tm",
2u16 => "Parms",
3u16 => "EncIpv4Src",
4u16 => "EncIpv4Dst",
5u16 => "EncIpv6Src",
6u16 => "EncIpv6Dst",
7u16 => "EncKeyId",
8u16 => "Pad",
9u16 => "EncDstPort",
10u16 => "NoCsum",
11u16 => "EncOpts",
12u16 => "EncTos",
13u16 => "EncTtl",
14u16 => "NoFrag",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableActTunnelKeyAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableActTunnelKeyAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableActTunnelKeyAttrs<'a> {
type Item = Result<ActTunnelKeyAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => ActTunnelKeyAttrs::Tm({
let res = Some(TcfT::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
2u16 => ActTunnelKeyAttrs::Parms({
let res = Some(next);
let Some(val) = res else { break };
val
}),
3u16 => ActTunnelKeyAttrs::EncIpv4Src({
let res = parse_be_u32(next);
let Some(val) = res else { break };
val
}),
4u16 => ActTunnelKeyAttrs::EncIpv4Dst({
let res = parse_be_u32(next);
let Some(val) = res else { break };
val
}),
5u16 => ActTunnelKeyAttrs::EncIpv6Src({
let res = Some(next);
let Some(val) = res else { break };
val
}),
6u16 => ActTunnelKeyAttrs::EncIpv6Dst({
let res = Some(next);
let Some(val) = res else { break };
val
}),
7u16 => ActTunnelKeyAttrs::EncKeyId({
let res = parse_be_u64(next);
let Some(val) = res else { break };
val
}),
8u16 => ActTunnelKeyAttrs::Pad({
let res = Some(next);
let Some(val) = res else { break };
val
}),
9u16 => ActTunnelKeyAttrs::EncDstPort({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
10u16 => ActTunnelKeyAttrs::NoCsum({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
11u16 => ActTunnelKeyAttrs::EncOpts({
let res = Some(next);
let Some(val) = res else { break };
val
}),
12u16 => ActTunnelKeyAttrs::EncTos({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
13u16 => ActTunnelKeyAttrs::EncTtl({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
14u16 => ActTunnelKeyAttrs::NoFrag(()),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"ActTunnelKeyAttrs",
r#type.and_then(|t| ActTunnelKeyAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableActTunnelKeyAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("ActTunnelKeyAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
ActTunnelKeyAttrs::Tm(val) => fmt.field("Tm", &val),
ActTunnelKeyAttrs::Parms(val) => fmt.field("Parms", &val),
ActTunnelKeyAttrs::EncIpv4Src(val) => fmt.field("EncIpv4Src", &val),
ActTunnelKeyAttrs::EncIpv4Dst(val) => fmt.field("EncIpv4Dst", &val),
ActTunnelKeyAttrs::EncIpv6Src(val) => fmt.field("EncIpv6Src", &val),
ActTunnelKeyAttrs::EncIpv6Dst(val) => fmt.field("EncIpv6Dst", &val),
ActTunnelKeyAttrs::EncKeyId(val) => fmt.field("EncKeyId", &val),
ActTunnelKeyAttrs::Pad(val) => fmt.field("Pad", &val),
ActTunnelKeyAttrs::EncDstPort(val) => fmt.field("EncDstPort", &val),
ActTunnelKeyAttrs::NoCsum(val) => fmt.field("NoCsum", &val),
ActTunnelKeyAttrs::EncOpts(val) => fmt.field("EncOpts", &val),
ActTunnelKeyAttrs::EncTos(val) => fmt.field("EncTos", &val),
ActTunnelKeyAttrs::EncTtl(val) => fmt.field("EncTtl", &val),
ActTunnelKeyAttrs::NoFrag(val) => fmt.field("NoFrag", &val),
};
}
fmt.finish()
}
}
impl IterableActTunnelKeyAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("ActTunnelKeyAttrs", offset));
return (
stack,
missing_type.and_then(|t| ActTunnelKeyAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
ActTunnelKeyAttrs::Tm(val) => {
if last_off == offset {
stack.push(("Tm", last_off));
break;
}
}
ActTunnelKeyAttrs::Parms(val) => {
if last_off == offset {
stack.push(("Parms", last_off));
break;
}
}
ActTunnelKeyAttrs::EncIpv4Src(val) => {
if last_off == offset {
stack.push(("EncIpv4Src", last_off));
break;
}
}
ActTunnelKeyAttrs::EncIpv4Dst(val) => {
if last_off == offset {
stack.push(("EncIpv4Dst", last_off));
break;
}
}
ActTunnelKeyAttrs::EncIpv6Src(val) => {
if last_off == offset {
stack.push(("EncIpv6Src", last_off));
break;
}
}
ActTunnelKeyAttrs::EncIpv6Dst(val) => {
if last_off == offset {
stack.push(("EncIpv6Dst", last_off));
break;
}
}
ActTunnelKeyAttrs::EncKeyId(val) => {
if last_off == offset {
stack.push(("EncKeyId", last_off));
break;
}
}
ActTunnelKeyAttrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
ActTunnelKeyAttrs::EncDstPort(val) => {
if last_off == offset {
stack.push(("EncDstPort", last_off));
break;
}
}
ActTunnelKeyAttrs::NoCsum(val) => {
if last_off == offset {
stack.push(("NoCsum", last_off));
break;
}
}
ActTunnelKeyAttrs::EncOpts(val) => {
if last_off == offset {
stack.push(("EncOpts", last_off));
break;
}
}
ActTunnelKeyAttrs::EncTos(val) => {
if last_off == offset {
stack.push(("EncTos", last_off));
break;
}
}
ActTunnelKeyAttrs::EncTtl(val) => {
if last_off == offset {
stack.push(("EncTtl", last_off));
break;
}
}
ActTunnelKeyAttrs::NoFrag(val) => {
if last_off == offset {
stack.push(("NoFrag", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("ActTunnelKeyAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum ActVlanAttrs<'a> {
Tm(TcfT),
Parms(TcVlan),
PushVlanId(u16),
PushVlanProtocol(u16),
Pad(&'a [u8]),
PushVlanPriority(u8),
PushEthDst(&'a [u8]),
PushEthSrc(&'a [u8]),
}
impl<'a> IterableActVlanAttrs<'a> {
pub fn get_tm(&self) -> Result<TcfT, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActVlanAttrs::Tm(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActVlanAttrs",
"Tm",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_parms(&self) -> Result<TcVlan, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActVlanAttrs::Parms(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActVlanAttrs",
"Parms",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_push_vlan_id(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActVlanAttrs::PushVlanId(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActVlanAttrs",
"PushVlanId",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_push_vlan_protocol(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActVlanAttrs::PushVlanProtocol(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActVlanAttrs",
"PushVlanProtocol",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActVlanAttrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActVlanAttrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_push_vlan_priority(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActVlanAttrs::PushVlanPriority(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActVlanAttrs",
"PushVlanPriority",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_push_eth_dst(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActVlanAttrs::PushEthDst(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActVlanAttrs",
"PushEthDst",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_push_eth_src(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActVlanAttrs::PushEthSrc(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActVlanAttrs",
"PushEthSrc",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl ActVlanAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableActVlanAttrs<'a> {
IterableActVlanAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Tm",
2u16 => "Parms",
3u16 => "PushVlanId",
4u16 => "PushVlanProtocol",
5u16 => "Pad",
6u16 => "PushVlanPriority",
7u16 => "PushEthDst",
8u16 => "PushEthSrc",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableActVlanAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableActVlanAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableActVlanAttrs<'a> {
type Item = Result<ActVlanAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => ActVlanAttrs::Tm({
let res = Some(TcfT::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
2u16 => ActVlanAttrs::Parms({
let res = Some(TcVlan::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
3u16 => ActVlanAttrs::PushVlanId({
let res = parse_u16(next);
let Some(val) = res else { break };
val
}),
4u16 => ActVlanAttrs::PushVlanProtocol({
let res = parse_u16(next);
let Some(val) = res else { break };
val
}),
5u16 => ActVlanAttrs::Pad({
let res = Some(next);
let Some(val) = res else { break };
val
}),
6u16 => ActVlanAttrs::PushVlanPriority({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
7u16 => ActVlanAttrs::PushEthDst({
let res = Some(next);
let Some(val) = res else { break };
val
}),
8u16 => ActVlanAttrs::PushEthSrc({
let res = Some(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"ActVlanAttrs",
r#type.and_then(|t| ActVlanAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableActVlanAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("ActVlanAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
ActVlanAttrs::Tm(val) => fmt.field("Tm", &val),
ActVlanAttrs::Parms(val) => fmt.field("Parms", &val),
ActVlanAttrs::PushVlanId(val) => fmt.field("PushVlanId", &val),
ActVlanAttrs::PushVlanProtocol(val) => fmt.field("PushVlanProtocol", &val),
ActVlanAttrs::Pad(val) => fmt.field("Pad", &val),
ActVlanAttrs::PushVlanPriority(val) => fmt.field("PushVlanPriority", &val),
ActVlanAttrs::PushEthDst(val) => fmt.field("PushEthDst", &val),
ActVlanAttrs::PushEthSrc(val) => fmt.field("PushEthSrc", &val),
};
}
fmt.finish()
}
}
impl IterableActVlanAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("ActVlanAttrs", offset));
return (
stack,
missing_type.and_then(|t| ActVlanAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
ActVlanAttrs::Tm(val) => {
if last_off == offset {
stack.push(("Tm", last_off));
break;
}
}
ActVlanAttrs::Parms(val) => {
if last_off == offset {
stack.push(("Parms", last_off));
break;
}
}
ActVlanAttrs::PushVlanId(val) => {
if last_off == offset {
stack.push(("PushVlanId", last_off));
break;
}
}
ActVlanAttrs::PushVlanProtocol(val) => {
if last_off == offset {
stack.push(("PushVlanProtocol", last_off));
break;
}
}
ActVlanAttrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
ActVlanAttrs::PushVlanPriority(val) => {
if last_off == offset {
stack.push(("PushVlanPriority", last_off));
break;
}
}
ActVlanAttrs::PushEthDst(val) => {
if last_off == offset {
stack.push(("PushEthDst", last_off));
break;
}
}
ActVlanAttrs::PushEthSrc(val) => {
if last_off == offset {
stack.push(("PushEthSrc", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("ActVlanAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum BasicAttrs<'a> {
Classid(u32),
Ematches(IterableEmatchAttrs<'a>),
Act(IterableArrayActAttrs<'a>),
Police(IterablePoliceAttrs<'a>),
Pcnt(TcBasicPcnt),
Pad(&'a [u8]),
}
impl<'a> IterableBasicAttrs<'a> {
pub fn get_classid(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(BasicAttrs::Classid(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"BasicAttrs",
"Classid",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_ematches(&self) -> Result<IterableEmatchAttrs<'a>, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(BasicAttrs::Ematches(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"BasicAttrs",
"Ematches",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_act(
&self,
) -> Result<ArrayIterable<IterableArrayActAttrs<'a>, IterableActAttrs<'a>>, ErrorContext> {
for attr in self.clone() {
if let Ok(BasicAttrs::Act(val)) = attr {
return Ok(ArrayIterable::new(val));
}
}
Err(ErrorContext::new_missing(
"BasicAttrs",
"Act",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_police(&self) -> Result<IterablePoliceAttrs<'a>, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(BasicAttrs::Police(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"BasicAttrs",
"Police",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pcnt(&self) -> Result<TcBasicPcnt, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(BasicAttrs::Pcnt(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"BasicAttrs",
"Pcnt",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(BasicAttrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"BasicAttrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl<'a> ActAttrs<'a> {
pub fn new_array(buf: &[u8]) -> IterableArrayActAttrs<'_> {
IterableArrayActAttrs::with_loc(buf, buf.as_ptr() as usize)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableArrayActAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableArrayActAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableArrayActAttrs<'a> {
type Item = Result<IterableActAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
if self.buf.len() == self.pos {
return None;
}
while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
{
return Some(Ok(IterableActAttrs::with_loc(next, self.orig_loc)));
}
}
let pos = self.pos;
self.pos = self.buf.len();
Some(Err(ErrorContext::new(
"ActAttrs",
None,
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl BasicAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableBasicAttrs<'a> {
IterableBasicAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Classid",
2u16 => "Ematches",
3u16 => "Act",
4u16 => "Police",
5u16 => "Pcnt",
6u16 => "Pad",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableBasicAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableBasicAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableBasicAttrs<'a> {
type Item = Result<BasicAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => BasicAttrs::Classid({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
2u16 => BasicAttrs::Ematches({
let res = Some(IterableEmatchAttrs::with_loc(next, self.orig_loc));
let Some(val) = res else { break };
val
}),
3u16 => BasicAttrs::Act({
let res = Some(IterableArrayActAttrs::with_loc(next, self.orig_loc));
let Some(val) = res else { break };
val
}),
4u16 => BasicAttrs::Police({
let res = Some(IterablePoliceAttrs::with_loc(next, self.orig_loc));
let Some(val) = res else { break };
val
}),
5u16 => BasicAttrs::Pcnt({
let res = Some(TcBasicPcnt::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
6u16 => BasicAttrs::Pad({
let res = Some(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"BasicAttrs",
r#type.and_then(|t| BasicAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl std::fmt::Debug for IterableArrayActAttrs<'_> {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fmt.debug_list()
.entries(self.clone().map(FlattenErrorContext))
.finish()
}
}
impl<'a> std::fmt::Debug for IterableBasicAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("BasicAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
BasicAttrs::Classid(val) => fmt.field("Classid", &val),
BasicAttrs::Ematches(val) => fmt.field("Ematches", &val),
BasicAttrs::Act(val) => fmt.field("Act", &val),
BasicAttrs::Police(val) => fmt.field("Police", &val),
BasicAttrs::Pcnt(val) => fmt.field("Pcnt", &val),
BasicAttrs::Pad(val) => fmt.field("Pad", &val),
};
}
fmt.finish()
}
}
impl IterableBasicAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("BasicAttrs", offset));
return (
stack,
missing_type.and_then(|t| BasicAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
let mut missing = None;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
BasicAttrs::Classid(val) => {
if last_off == offset {
stack.push(("Classid", last_off));
break;
}
}
BasicAttrs::Ematches(val) => {
(stack, missing) = val.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
BasicAttrs::Act(val) => {
for entry in val {
let Ok(attr) = entry else { break };
(stack, missing) = attr.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
if !stack.is_empty() {
stack.push(("Act", last_off));
break;
}
}
BasicAttrs::Police(val) => {
(stack, missing) = val.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
BasicAttrs::Pcnt(val) => {
if last_off == offset {
stack.push(("Pcnt", last_off));
break;
}
}
BasicAttrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("BasicAttrs", cur));
}
(stack, missing)
}
}
#[derive(Clone)]
pub enum BpfAttrs<'a> {
Act(IterableArrayActAttrs<'a>),
Police(IterablePoliceAttrs<'a>),
Classid(u32),
OpsLen(u16),
Ops(&'a [u8]),
Fd(u32),
Name(&'a CStr),
Flags(u32),
FlagsGen(u32),
Tag(&'a [u8]),
Id(u32),
}
impl<'a> IterableBpfAttrs<'a> {
pub fn get_act(
&self,
) -> Result<ArrayIterable<IterableArrayActAttrs<'a>, IterableActAttrs<'a>>, ErrorContext> {
for attr in self.clone() {
if let Ok(BpfAttrs::Act(val)) = attr {
return Ok(ArrayIterable::new(val));
}
}
Err(ErrorContext::new_missing(
"BpfAttrs",
"Act",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_police(&self) -> Result<IterablePoliceAttrs<'a>, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(BpfAttrs::Police(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"BpfAttrs",
"Police",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_classid(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(BpfAttrs::Classid(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"BpfAttrs",
"Classid",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_ops_len(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(BpfAttrs::OpsLen(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"BpfAttrs",
"OpsLen",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_ops(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(BpfAttrs::Ops(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"BpfAttrs",
"Ops",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_fd(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(BpfAttrs::Fd(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"BpfAttrs",
"Fd",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_name(&self) -> Result<&'a CStr, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(BpfAttrs::Name(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"BpfAttrs",
"Name",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_flags(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(BpfAttrs::Flags(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"BpfAttrs",
"Flags",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_flags_gen(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(BpfAttrs::FlagsGen(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"BpfAttrs",
"FlagsGen",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_tag(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(BpfAttrs::Tag(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"BpfAttrs",
"Tag",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_id(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(BpfAttrs::Id(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"BpfAttrs",
"Id",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl BpfAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableBpfAttrs<'a> {
IterableBpfAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Act",
2u16 => "Police",
3u16 => "Classid",
4u16 => "OpsLen",
5u16 => "Ops",
6u16 => "Fd",
7u16 => "Name",
8u16 => "Flags",
9u16 => "FlagsGen",
10u16 => "Tag",
11u16 => "Id",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableBpfAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableBpfAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableBpfAttrs<'a> {
type Item = Result<BpfAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => BpfAttrs::Act({
let res = Some(IterableArrayActAttrs::with_loc(next, self.orig_loc));
let Some(val) = res else { break };
val
}),
2u16 => BpfAttrs::Police({
let res = Some(IterablePoliceAttrs::with_loc(next, self.orig_loc));
let Some(val) = res else { break };
val
}),
3u16 => BpfAttrs::Classid({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
4u16 => BpfAttrs::OpsLen({
let res = parse_u16(next);
let Some(val) = res else { break };
val
}),
5u16 => BpfAttrs::Ops({
let res = Some(next);
let Some(val) = res else { break };
val
}),
6u16 => BpfAttrs::Fd({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
7u16 => BpfAttrs::Name({
let res = CStr::from_bytes_with_nul(next).ok();
let Some(val) = res else { break };
val
}),
8u16 => BpfAttrs::Flags({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
9u16 => BpfAttrs::FlagsGen({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
10u16 => BpfAttrs::Tag({
let res = Some(next);
let Some(val) = res else { break };
val
}),
11u16 => BpfAttrs::Id({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"BpfAttrs",
r#type.and_then(|t| BpfAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableBpfAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("BpfAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
BpfAttrs::Act(val) => fmt.field("Act", &val),
BpfAttrs::Police(val) => fmt.field("Police", &val),
BpfAttrs::Classid(val) => fmt.field("Classid", &val),
BpfAttrs::OpsLen(val) => fmt.field("OpsLen", &val),
BpfAttrs::Ops(val) => fmt.field("Ops", &val),
BpfAttrs::Fd(val) => fmt.field("Fd", &val),
BpfAttrs::Name(val) => fmt.field("Name", &val),
BpfAttrs::Flags(val) => fmt.field("Flags", &val),
BpfAttrs::FlagsGen(val) => fmt.field("FlagsGen", &val),
BpfAttrs::Tag(val) => fmt.field("Tag", &val),
BpfAttrs::Id(val) => fmt.field("Id", &val),
};
}
fmt.finish()
}
}
impl IterableBpfAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("BpfAttrs", offset));
return (
stack,
missing_type.and_then(|t| BpfAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
let mut missing = None;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
BpfAttrs::Act(val) => {
for entry in val {
let Ok(attr) = entry else { break };
(stack, missing) = attr.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
if !stack.is_empty() {
stack.push(("Act", last_off));
break;
}
}
BpfAttrs::Police(val) => {
(stack, missing) = val.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
BpfAttrs::Classid(val) => {
if last_off == offset {
stack.push(("Classid", last_off));
break;
}
}
BpfAttrs::OpsLen(val) => {
if last_off == offset {
stack.push(("OpsLen", last_off));
break;
}
}
BpfAttrs::Ops(val) => {
if last_off == offset {
stack.push(("Ops", last_off));
break;
}
}
BpfAttrs::Fd(val) => {
if last_off == offset {
stack.push(("Fd", last_off));
break;
}
}
BpfAttrs::Name(val) => {
if last_off == offset {
stack.push(("Name", last_off));
break;
}
}
BpfAttrs::Flags(val) => {
if last_off == offset {
stack.push(("Flags", last_off));
break;
}
}
BpfAttrs::FlagsGen(val) => {
if last_off == offset {
stack.push(("FlagsGen", last_off));
break;
}
}
BpfAttrs::Tag(val) => {
if last_off == offset {
stack.push(("Tag", last_off));
break;
}
}
BpfAttrs::Id(val) => {
if last_off == offset {
stack.push(("Id", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("BpfAttrs", cur));
}
(stack, missing)
}
}
#[derive(Clone)]
pub enum CakeAttrs<'a> {
Pad(&'a [u8]),
BaseRate64(u64),
DiffservMode(u32),
Atm(u32),
FlowMode(u32),
Overhead(u32),
Rtt(u32),
Target(u32),
Autorate(u32),
Memory(u32),
Nat(u32),
Raw(u32),
Wash(u32),
Mpu(u32),
Ingress(u32),
AckFilter(u32),
SplitGso(u32),
Fwmark(u32),
}
impl<'a> IterableCakeAttrs<'a> {
pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeAttrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeAttrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_base_rate64(&self) -> Result<u64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeAttrs::BaseRate64(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeAttrs",
"BaseRate64",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_diffserv_mode(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeAttrs::DiffservMode(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeAttrs",
"DiffservMode",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_atm(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeAttrs::Atm(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeAttrs",
"Atm",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_flow_mode(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeAttrs::FlowMode(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeAttrs",
"FlowMode",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_overhead(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeAttrs::Overhead(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeAttrs",
"Overhead",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_rtt(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeAttrs::Rtt(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeAttrs",
"Rtt",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_target(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeAttrs::Target(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeAttrs",
"Target",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_autorate(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeAttrs::Autorate(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeAttrs",
"Autorate",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_memory(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeAttrs::Memory(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeAttrs",
"Memory",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_nat(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeAttrs::Nat(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeAttrs",
"Nat",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_raw(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeAttrs::Raw(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeAttrs",
"Raw",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_wash(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeAttrs::Wash(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeAttrs",
"Wash",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_mpu(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeAttrs::Mpu(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeAttrs",
"Mpu",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_ingress(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeAttrs::Ingress(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeAttrs",
"Ingress",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_ack_filter(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeAttrs::AckFilter(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeAttrs",
"AckFilter",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_split_gso(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeAttrs::SplitGso(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeAttrs",
"SplitGso",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_fwmark(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeAttrs::Fwmark(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeAttrs",
"Fwmark",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl CakeAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableCakeAttrs<'a> {
IterableCakeAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Pad",
2u16 => "BaseRate64",
3u16 => "DiffservMode",
4u16 => "Atm",
5u16 => "FlowMode",
6u16 => "Overhead",
7u16 => "Rtt",
8u16 => "Target",
9u16 => "Autorate",
10u16 => "Memory",
11u16 => "Nat",
12u16 => "Raw",
13u16 => "Wash",
14u16 => "Mpu",
15u16 => "Ingress",
16u16 => "AckFilter",
17u16 => "SplitGso",
18u16 => "Fwmark",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableCakeAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableCakeAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableCakeAttrs<'a> {
type Item = Result<CakeAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => CakeAttrs::Pad({
let res = Some(next);
let Some(val) = res else { break };
val
}),
2u16 => CakeAttrs::BaseRate64({
let res = parse_u64(next);
let Some(val) = res else { break };
val
}),
3u16 => CakeAttrs::DiffservMode({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
4u16 => CakeAttrs::Atm({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
5u16 => CakeAttrs::FlowMode({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
6u16 => CakeAttrs::Overhead({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
7u16 => CakeAttrs::Rtt({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
8u16 => CakeAttrs::Target({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
9u16 => CakeAttrs::Autorate({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
10u16 => CakeAttrs::Memory({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
11u16 => CakeAttrs::Nat({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
12u16 => CakeAttrs::Raw({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
13u16 => CakeAttrs::Wash({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
14u16 => CakeAttrs::Mpu({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
15u16 => CakeAttrs::Ingress({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
16u16 => CakeAttrs::AckFilter({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
17u16 => CakeAttrs::SplitGso({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
18u16 => CakeAttrs::Fwmark({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"CakeAttrs",
r#type.and_then(|t| CakeAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableCakeAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("CakeAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
CakeAttrs::Pad(val) => fmt.field("Pad", &val),
CakeAttrs::BaseRate64(val) => fmt.field("BaseRate64", &val),
CakeAttrs::DiffservMode(val) => fmt.field("DiffservMode", &val),
CakeAttrs::Atm(val) => fmt.field("Atm", &val),
CakeAttrs::FlowMode(val) => fmt.field("FlowMode", &val),
CakeAttrs::Overhead(val) => fmt.field("Overhead", &val),
CakeAttrs::Rtt(val) => fmt.field("Rtt", &val),
CakeAttrs::Target(val) => fmt.field("Target", &val),
CakeAttrs::Autorate(val) => fmt.field("Autorate", &val),
CakeAttrs::Memory(val) => fmt.field("Memory", &val),
CakeAttrs::Nat(val) => fmt.field("Nat", &val),
CakeAttrs::Raw(val) => fmt.field("Raw", &val),
CakeAttrs::Wash(val) => fmt.field("Wash", &val),
CakeAttrs::Mpu(val) => fmt.field("Mpu", &val),
CakeAttrs::Ingress(val) => fmt.field("Ingress", &val),
CakeAttrs::AckFilter(val) => fmt.field("AckFilter", &val),
CakeAttrs::SplitGso(val) => fmt.field("SplitGso", &val),
CakeAttrs::Fwmark(val) => fmt.field("Fwmark", &val),
};
}
fmt.finish()
}
}
impl IterableCakeAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("CakeAttrs", offset));
return (
stack,
missing_type.and_then(|t| CakeAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
CakeAttrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
CakeAttrs::BaseRate64(val) => {
if last_off == offset {
stack.push(("BaseRate64", last_off));
break;
}
}
CakeAttrs::DiffservMode(val) => {
if last_off == offset {
stack.push(("DiffservMode", last_off));
break;
}
}
CakeAttrs::Atm(val) => {
if last_off == offset {
stack.push(("Atm", last_off));
break;
}
}
CakeAttrs::FlowMode(val) => {
if last_off == offset {
stack.push(("FlowMode", last_off));
break;
}
}
CakeAttrs::Overhead(val) => {
if last_off == offset {
stack.push(("Overhead", last_off));
break;
}
}
CakeAttrs::Rtt(val) => {
if last_off == offset {
stack.push(("Rtt", last_off));
break;
}
}
CakeAttrs::Target(val) => {
if last_off == offset {
stack.push(("Target", last_off));
break;
}
}
CakeAttrs::Autorate(val) => {
if last_off == offset {
stack.push(("Autorate", last_off));
break;
}
}
CakeAttrs::Memory(val) => {
if last_off == offset {
stack.push(("Memory", last_off));
break;
}
}
CakeAttrs::Nat(val) => {
if last_off == offset {
stack.push(("Nat", last_off));
break;
}
}
CakeAttrs::Raw(val) => {
if last_off == offset {
stack.push(("Raw", last_off));
break;
}
}
CakeAttrs::Wash(val) => {
if last_off == offset {
stack.push(("Wash", last_off));
break;
}
}
CakeAttrs::Mpu(val) => {
if last_off == offset {
stack.push(("Mpu", last_off));
break;
}
}
CakeAttrs::Ingress(val) => {
if last_off == offset {
stack.push(("Ingress", last_off));
break;
}
}
CakeAttrs::AckFilter(val) => {
if last_off == offset {
stack.push(("AckFilter", last_off));
break;
}
}
CakeAttrs::SplitGso(val) => {
if last_off == offset {
stack.push(("SplitGso", last_off));
break;
}
}
CakeAttrs::Fwmark(val) => {
if last_off == offset {
stack.push(("Fwmark", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("CakeAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum CakeStatsAttrs<'a> {
Pad(&'a [u8]),
CapacityEstimate64(u64),
MemoryLimit(u32),
MemoryUsed(u32),
AvgNetoff(u32),
MinNetlen(u32),
MaxNetlen(u32),
MinAdjlen(u32),
MaxAdjlen(u32),
TinStats(IterableArrayCakeTinStatsAttrs<'a>),
Deficit(i32),
CobaltCount(u32),
Dropping(u32),
DropNextUs(i32),
PDrop(u32),
BlueTimerUs(i32),
ActiveQueues(u32),
}
impl<'a> IterableCakeStatsAttrs<'a> {
pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeStatsAttrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeStatsAttrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_capacity_estimate64(&self) -> Result<u64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeStatsAttrs::CapacityEstimate64(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeStatsAttrs",
"CapacityEstimate64",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_memory_limit(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeStatsAttrs::MemoryLimit(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeStatsAttrs",
"MemoryLimit",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_memory_used(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeStatsAttrs::MemoryUsed(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeStatsAttrs",
"MemoryUsed",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_avg_netoff(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeStatsAttrs::AvgNetoff(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeStatsAttrs",
"AvgNetoff",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_min_netlen(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeStatsAttrs::MinNetlen(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeStatsAttrs",
"MinNetlen",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_max_netlen(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeStatsAttrs::MaxNetlen(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeStatsAttrs",
"MaxNetlen",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_min_adjlen(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeStatsAttrs::MinAdjlen(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeStatsAttrs",
"MinAdjlen",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_max_adjlen(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeStatsAttrs::MaxAdjlen(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeStatsAttrs",
"MaxAdjlen",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_tin_stats(
&self,
) -> Result<
ArrayIterable<IterableArrayCakeTinStatsAttrs<'a>, IterableCakeTinStatsAttrs<'a>>,
ErrorContext,
> {
for attr in self.clone() {
if let Ok(CakeStatsAttrs::TinStats(val)) = attr {
return Ok(ArrayIterable::new(val));
}
}
Err(ErrorContext::new_missing(
"CakeStatsAttrs",
"TinStats",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_deficit(&self) -> Result<i32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeStatsAttrs::Deficit(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeStatsAttrs",
"Deficit",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_cobalt_count(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeStatsAttrs::CobaltCount(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeStatsAttrs",
"CobaltCount",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_dropping(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeStatsAttrs::Dropping(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeStatsAttrs",
"Dropping",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_drop_next_us(&self) -> Result<i32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeStatsAttrs::DropNextUs(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeStatsAttrs",
"DropNextUs",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_p_drop(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeStatsAttrs::PDrop(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeStatsAttrs",
"PDrop",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_blue_timer_us(&self) -> Result<i32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeStatsAttrs::BlueTimerUs(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeStatsAttrs",
"BlueTimerUs",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_active_queues(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeStatsAttrs::ActiveQueues(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeStatsAttrs",
"ActiveQueues",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl<'a> CakeTinStatsAttrs<'a> {
pub fn new_array(buf: &[u8]) -> IterableArrayCakeTinStatsAttrs<'_> {
IterableArrayCakeTinStatsAttrs::with_loc(buf, buf.as_ptr() as usize)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableArrayCakeTinStatsAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableArrayCakeTinStatsAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableArrayCakeTinStatsAttrs<'a> {
type Item = Result<IterableCakeTinStatsAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
if self.buf.len() == self.pos {
return None;
}
while let Some((header, next)) = chop_header(self.buf, &mut self.pos) {
{
return Some(Ok(IterableCakeTinStatsAttrs::with_loc(next, self.orig_loc)));
}
}
let pos = self.pos;
self.pos = self.buf.len();
Some(Err(ErrorContext::new(
"CakeTinStatsAttrs",
None,
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl CakeStatsAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableCakeStatsAttrs<'a> {
IterableCakeStatsAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Pad",
2u16 => "CapacityEstimate64",
3u16 => "MemoryLimit",
4u16 => "MemoryUsed",
5u16 => "AvgNetoff",
6u16 => "MinNetlen",
7u16 => "MaxNetlen",
8u16 => "MinAdjlen",
9u16 => "MaxAdjlen",
10u16 => "TinStats",
11u16 => "Deficit",
12u16 => "CobaltCount",
13u16 => "Dropping",
14u16 => "DropNextUs",
15u16 => "PDrop",
16u16 => "BlueTimerUs",
17u16 => "ActiveQueues",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableCakeStatsAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableCakeStatsAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableCakeStatsAttrs<'a> {
type Item = Result<CakeStatsAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => CakeStatsAttrs::Pad({
let res = Some(next);
let Some(val) = res else { break };
val
}),
2u16 => CakeStatsAttrs::CapacityEstimate64({
let res = parse_u64(next);
let Some(val) = res else { break };
val
}),
3u16 => CakeStatsAttrs::MemoryLimit({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
4u16 => CakeStatsAttrs::MemoryUsed({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
5u16 => CakeStatsAttrs::AvgNetoff({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
6u16 => CakeStatsAttrs::MinNetlen({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
7u16 => CakeStatsAttrs::MaxNetlen({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
8u16 => CakeStatsAttrs::MinAdjlen({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
9u16 => CakeStatsAttrs::MaxAdjlen({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
10u16 => CakeStatsAttrs::TinStats({
let res = Some(IterableArrayCakeTinStatsAttrs::with_loc(
next,
self.orig_loc,
));
let Some(val) = res else { break };
val
}),
11u16 => CakeStatsAttrs::Deficit({
let res = parse_i32(next);
let Some(val) = res else { break };
val
}),
12u16 => CakeStatsAttrs::CobaltCount({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
13u16 => CakeStatsAttrs::Dropping({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
14u16 => CakeStatsAttrs::DropNextUs({
let res = parse_i32(next);
let Some(val) = res else { break };
val
}),
15u16 => CakeStatsAttrs::PDrop({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
16u16 => CakeStatsAttrs::BlueTimerUs({
let res = parse_i32(next);
let Some(val) = res else { break };
val
}),
17u16 => CakeStatsAttrs::ActiveQueues({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"CakeStatsAttrs",
r#type.and_then(|t| CakeStatsAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl std::fmt::Debug for IterableArrayCakeTinStatsAttrs<'_> {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
fmt.debug_list()
.entries(self.clone().map(FlattenErrorContext))
.finish()
}
}
impl<'a> std::fmt::Debug for IterableCakeStatsAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("CakeStatsAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
CakeStatsAttrs::Pad(val) => fmt.field("Pad", &val),
CakeStatsAttrs::CapacityEstimate64(val) => fmt.field("CapacityEstimate64", &val),
CakeStatsAttrs::MemoryLimit(val) => fmt.field("MemoryLimit", &val),
CakeStatsAttrs::MemoryUsed(val) => fmt.field("MemoryUsed", &val),
CakeStatsAttrs::AvgNetoff(val) => fmt.field("AvgNetoff", &val),
CakeStatsAttrs::MinNetlen(val) => fmt.field("MinNetlen", &val),
CakeStatsAttrs::MaxNetlen(val) => fmt.field("MaxNetlen", &val),
CakeStatsAttrs::MinAdjlen(val) => fmt.field("MinAdjlen", &val),
CakeStatsAttrs::MaxAdjlen(val) => fmt.field("MaxAdjlen", &val),
CakeStatsAttrs::TinStats(val) => fmt.field("TinStats", &val),
CakeStatsAttrs::Deficit(val) => fmt.field("Deficit", &val),
CakeStatsAttrs::CobaltCount(val) => fmt.field("CobaltCount", &val),
CakeStatsAttrs::Dropping(val) => fmt.field("Dropping", &val),
CakeStatsAttrs::DropNextUs(val) => fmt.field("DropNextUs", &val),
CakeStatsAttrs::PDrop(val) => fmt.field("PDrop", &val),
CakeStatsAttrs::BlueTimerUs(val) => fmt.field("BlueTimerUs", &val),
CakeStatsAttrs::ActiveQueues(val) => fmt.field("ActiveQueues", &val),
};
}
fmt.finish()
}
}
impl IterableCakeStatsAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("CakeStatsAttrs", offset));
return (
stack,
missing_type.and_then(|t| CakeStatsAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
let mut missing = None;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
CakeStatsAttrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
CakeStatsAttrs::CapacityEstimate64(val) => {
if last_off == offset {
stack.push(("CapacityEstimate64", last_off));
break;
}
}
CakeStatsAttrs::MemoryLimit(val) => {
if last_off == offset {
stack.push(("MemoryLimit", last_off));
break;
}
}
CakeStatsAttrs::MemoryUsed(val) => {
if last_off == offset {
stack.push(("MemoryUsed", last_off));
break;
}
}
CakeStatsAttrs::AvgNetoff(val) => {
if last_off == offset {
stack.push(("AvgNetoff", last_off));
break;
}
}
CakeStatsAttrs::MinNetlen(val) => {
if last_off == offset {
stack.push(("MinNetlen", last_off));
break;
}
}
CakeStatsAttrs::MaxNetlen(val) => {
if last_off == offset {
stack.push(("MaxNetlen", last_off));
break;
}
}
CakeStatsAttrs::MinAdjlen(val) => {
if last_off == offset {
stack.push(("MinAdjlen", last_off));
break;
}
}
CakeStatsAttrs::MaxAdjlen(val) => {
if last_off == offset {
stack.push(("MaxAdjlen", last_off));
break;
}
}
CakeStatsAttrs::TinStats(val) => {
for entry in val {
let Ok(attr) = entry else { break };
(stack, missing) = attr.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
if !stack.is_empty() {
stack.push(("TinStats", last_off));
break;
}
}
CakeStatsAttrs::Deficit(val) => {
if last_off == offset {
stack.push(("Deficit", last_off));
break;
}
}
CakeStatsAttrs::CobaltCount(val) => {
if last_off == offset {
stack.push(("CobaltCount", last_off));
break;
}
}
CakeStatsAttrs::Dropping(val) => {
if last_off == offset {
stack.push(("Dropping", last_off));
break;
}
}
CakeStatsAttrs::DropNextUs(val) => {
if last_off == offset {
stack.push(("DropNextUs", last_off));
break;
}
}
CakeStatsAttrs::PDrop(val) => {
if last_off == offset {
stack.push(("PDrop", last_off));
break;
}
}
CakeStatsAttrs::BlueTimerUs(val) => {
if last_off == offset {
stack.push(("BlueTimerUs", last_off));
break;
}
}
CakeStatsAttrs::ActiveQueues(val) => {
if last_off == offset {
stack.push(("ActiveQueues", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("CakeStatsAttrs", cur));
}
(stack, missing)
}
}
#[derive(Clone)]
pub enum CakeTinStatsAttrs<'a> {
Pad(&'a [u8]),
SentPackets(u32),
SentBytes64(u64),
DroppedPackets(u32),
DroppedBytes64(u64),
AcksDroppedPackets(u32),
AcksDroppedBytes64(u64),
EcnMarkedPackets(u32),
EcnMarkedBytes64(u64),
BacklogPackets(u32),
BacklogBytes(u32),
ThresholdRate64(u64),
TargetUs(u32),
IntervalUs(u32),
WayIndirectHits(u32),
WayMisses(u32),
WayCollisions(u32),
PeakDelayUs(u32),
AvgDelayUs(u32),
BaseDelayUs(u32),
SparseFlows(u32),
BulkFlows(u32),
UnresponsiveFlows(u32),
MaxSkblen(u32),
FlowQuantum(u32),
}
impl<'a> IterableCakeTinStatsAttrs<'a> {
pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeTinStatsAttrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeTinStatsAttrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_sent_packets(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeTinStatsAttrs::SentPackets(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeTinStatsAttrs",
"SentPackets",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_sent_bytes64(&self) -> Result<u64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeTinStatsAttrs::SentBytes64(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeTinStatsAttrs",
"SentBytes64",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_dropped_packets(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeTinStatsAttrs::DroppedPackets(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeTinStatsAttrs",
"DroppedPackets",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_dropped_bytes64(&self) -> Result<u64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeTinStatsAttrs::DroppedBytes64(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeTinStatsAttrs",
"DroppedBytes64",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_acks_dropped_packets(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeTinStatsAttrs::AcksDroppedPackets(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeTinStatsAttrs",
"AcksDroppedPackets",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_acks_dropped_bytes64(&self) -> Result<u64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeTinStatsAttrs::AcksDroppedBytes64(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeTinStatsAttrs",
"AcksDroppedBytes64",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_ecn_marked_packets(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeTinStatsAttrs::EcnMarkedPackets(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeTinStatsAttrs",
"EcnMarkedPackets",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_ecn_marked_bytes64(&self) -> Result<u64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeTinStatsAttrs::EcnMarkedBytes64(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeTinStatsAttrs",
"EcnMarkedBytes64",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_backlog_packets(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeTinStatsAttrs::BacklogPackets(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeTinStatsAttrs",
"BacklogPackets",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_backlog_bytes(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeTinStatsAttrs::BacklogBytes(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeTinStatsAttrs",
"BacklogBytes",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_threshold_rate64(&self) -> Result<u64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeTinStatsAttrs::ThresholdRate64(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeTinStatsAttrs",
"ThresholdRate64",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_target_us(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeTinStatsAttrs::TargetUs(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeTinStatsAttrs",
"TargetUs",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_interval_us(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeTinStatsAttrs::IntervalUs(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeTinStatsAttrs",
"IntervalUs",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_way_indirect_hits(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeTinStatsAttrs::WayIndirectHits(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeTinStatsAttrs",
"WayIndirectHits",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_way_misses(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeTinStatsAttrs::WayMisses(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeTinStatsAttrs",
"WayMisses",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_way_collisions(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeTinStatsAttrs::WayCollisions(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeTinStatsAttrs",
"WayCollisions",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_peak_delay_us(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeTinStatsAttrs::PeakDelayUs(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeTinStatsAttrs",
"PeakDelayUs",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_avg_delay_us(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeTinStatsAttrs::AvgDelayUs(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeTinStatsAttrs",
"AvgDelayUs",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_base_delay_us(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeTinStatsAttrs::BaseDelayUs(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeTinStatsAttrs",
"BaseDelayUs",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_sparse_flows(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeTinStatsAttrs::SparseFlows(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeTinStatsAttrs",
"SparseFlows",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_bulk_flows(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeTinStatsAttrs::BulkFlows(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeTinStatsAttrs",
"BulkFlows",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_unresponsive_flows(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeTinStatsAttrs::UnresponsiveFlows(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeTinStatsAttrs",
"UnresponsiveFlows",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_max_skblen(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeTinStatsAttrs::MaxSkblen(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeTinStatsAttrs",
"MaxSkblen",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_flow_quantum(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CakeTinStatsAttrs::FlowQuantum(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CakeTinStatsAttrs",
"FlowQuantum",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl CakeTinStatsAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableCakeTinStatsAttrs<'a> {
IterableCakeTinStatsAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Pad",
2u16 => "SentPackets",
3u16 => "SentBytes64",
4u16 => "DroppedPackets",
5u16 => "DroppedBytes64",
6u16 => "AcksDroppedPackets",
7u16 => "AcksDroppedBytes64",
8u16 => "EcnMarkedPackets",
9u16 => "EcnMarkedBytes64",
10u16 => "BacklogPackets",
11u16 => "BacklogBytes",
12u16 => "ThresholdRate64",
13u16 => "TargetUs",
14u16 => "IntervalUs",
15u16 => "WayIndirectHits",
16u16 => "WayMisses",
17u16 => "WayCollisions",
18u16 => "PeakDelayUs",
19u16 => "AvgDelayUs",
20u16 => "BaseDelayUs",
21u16 => "SparseFlows",
22u16 => "BulkFlows",
23u16 => "UnresponsiveFlows",
24u16 => "MaxSkblen",
25u16 => "FlowQuantum",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableCakeTinStatsAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableCakeTinStatsAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableCakeTinStatsAttrs<'a> {
type Item = Result<CakeTinStatsAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => CakeTinStatsAttrs::Pad({
let res = Some(next);
let Some(val) = res else { break };
val
}),
2u16 => CakeTinStatsAttrs::SentPackets({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
3u16 => CakeTinStatsAttrs::SentBytes64({
let res = parse_u64(next);
let Some(val) = res else { break };
val
}),
4u16 => CakeTinStatsAttrs::DroppedPackets({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
5u16 => CakeTinStatsAttrs::DroppedBytes64({
let res = parse_u64(next);
let Some(val) = res else { break };
val
}),
6u16 => CakeTinStatsAttrs::AcksDroppedPackets({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
7u16 => CakeTinStatsAttrs::AcksDroppedBytes64({
let res = parse_u64(next);
let Some(val) = res else { break };
val
}),
8u16 => CakeTinStatsAttrs::EcnMarkedPackets({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
9u16 => CakeTinStatsAttrs::EcnMarkedBytes64({
let res = parse_u64(next);
let Some(val) = res else { break };
val
}),
10u16 => CakeTinStatsAttrs::BacklogPackets({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
11u16 => CakeTinStatsAttrs::BacklogBytes({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
12u16 => CakeTinStatsAttrs::ThresholdRate64({
let res = parse_u64(next);
let Some(val) = res else { break };
val
}),
13u16 => CakeTinStatsAttrs::TargetUs({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
14u16 => CakeTinStatsAttrs::IntervalUs({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
15u16 => CakeTinStatsAttrs::WayIndirectHits({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
16u16 => CakeTinStatsAttrs::WayMisses({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
17u16 => CakeTinStatsAttrs::WayCollisions({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
18u16 => CakeTinStatsAttrs::PeakDelayUs({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
19u16 => CakeTinStatsAttrs::AvgDelayUs({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
20u16 => CakeTinStatsAttrs::BaseDelayUs({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
21u16 => CakeTinStatsAttrs::SparseFlows({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
22u16 => CakeTinStatsAttrs::BulkFlows({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
23u16 => CakeTinStatsAttrs::UnresponsiveFlows({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
24u16 => CakeTinStatsAttrs::MaxSkblen({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
25u16 => CakeTinStatsAttrs::FlowQuantum({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"CakeTinStatsAttrs",
r#type.and_then(|t| CakeTinStatsAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableCakeTinStatsAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("CakeTinStatsAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
CakeTinStatsAttrs::Pad(val) => fmt.field("Pad", &val),
CakeTinStatsAttrs::SentPackets(val) => fmt.field("SentPackets", &val),
CakeTinStatsAttrs::SentBytes64(val) => fmt.field("SentBytes64", &val),
CakeTinStatsAttrs::DroppedPackets(val) => fmt.field("DroppedPackets", &val),
CakeTinStatsAttrs::DroppedBytes64(val) => fmt.field("DroppedBytes64", &val),
CakeTinStatsAttrs::AcksDroppedPackets(val) => fmt.field("AcksDroppedPackets", &val),
CakeTinStatsAttrs::AcksDroppedBytes64(val) => fmt.field("AcksDroppedBytes64", &val),
CakeTinStatsAttrs::EcnMarkedPackets(val) => fmt.field("EcnMarkedPackets", &val),
CakeTinStatsAttrs::EcnMarkedBytes64(val) => fmt.field("EcnMarkedBytes64", &val),
CakeTinStatsAttrs::BacklogPackets(val) => fmt.field("BacklogPackets", &val),
CakeTinStatsAttrs::BacklogBytes(val) => fmt.field("BacklogBytes", &val),
CakeTinStatsAttrs::ThresholdRate64(val) => fmt.field("ThresholdRate64", &val),
CakeTinStatsAttrs::TargetUs(val) => fmt.field("TargetUs", &val),
CakeTinStatsAttrs::IntervalUs(val) => fmt.field("IntervalUs", &val),
CakeTinStatsAttrs::WayIndirectHits(val) => fmt.field("WayIndirectHits", &val),
CakeTinStatsAttrs::WayMisses(val) => fmt.field("WayMisses", &val),
CakeTinStatsAttrs::WayCollisions(val) => fmt.field("WayCollisions", &val),
CakeTinStatsAttrs::PeakDelayUs(val) => fmt.field("PeakDelayUs", &val),
CakeTinStatsAttrs::AvgDelayUs(val) => fmt.field("AvgDelayUs", &val),
CakeTinStatsAttrs::BaseDelayUs(val) => fmt.field("BaseDelayUs", &val),
CakeTinStatsAttrs::SparseFlows(val) => fmt.field("SparseFlows", &val),
CakeTinStatsAttrs::BulkFlows(val) => fmt.field("BulkFlows", &val),
CakeTinStatsAttrs::UnresponsiveFlows(val) => fmt.field("UnresponsiveFlows", &val),
CakeTinStatsAttrs::MaxSkblen(val) => fmt.field("MaxSkblen", &val),
CakeTinStatsAttrs::FlowQuantum(val) => fmt.field("FlowQuantum", &val),
};
}
fmt.finish()
}
}
impl IterableCakeTinStatsAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("CakeTinStatsAttrs", offset));
return (
stack,
missing_type.and_then(|t| CakeTinStatsAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
CakeTinStatsAttrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
CakeTinStatsAttrs::SentPackets(val) => {
if last_off == offset {
stack.push(("SentPackets", last_off));
break;
}
}
CakeTinStatsAttrs::SentBytes64(val) => {
if last_off == offset {
stack.push(("SentBytes64", last_off));
break;
}
}
CakeTinStatsAttrs::DroppedPackets(val) => {
if last_off == offset {
stack.push(("DroppedPackets", last_off));
break;
}
}
CakeTinStatsAttrs::DroppedBytes64(val) => {
if last_off == offset {
stack.push(("DroppedBytes64", last_off));
break;
}
}
CakeTinStatsAttrs::AcksDroppedPackets(val) => {
if last_off == offset {
stack.push(("AcksDroppedPackets", last_off));
break;
}
}
CakeTinStatsAttrs::AcksDroppedBytes64(val) => {
if last_off == offset {
stack.push(("AcksDroppedBytes64", last_off));
break;
}
}
CakeTinStatsAttrs::EcnMarkedPackets(val) => {
if last_off == offset {
stack.push(("EcnMarkedPackets", last_off));
break;
}
}
CakeTinStatsAttrs::EcnMarkedBytes64(val) => {
if last_off == offset {
stack.push(("EcnMarkedBytes64", last_off));
break;
}
}
CakeTinStatsAttrs::BacklogPackets(val) => {
if last_off == offset {
stack.push(("BacklogPackets", last_off));
break;
}
}
CakeTinStatsAttrs::BacklogBytes(val) => {
if last_off == offset {
stack.push(("BacklogBytes", last_off));
break;
}
}
CakeTinStatsAttrs::ThresholdRate64(val) => {
if last_off == offset {
stack.push(("ThresholdRate64", last_off));
break;
}
}
CakeTinStatsAttrs::TargetUs(val) => {
if last_off == offset {
stack.push(("TargetUs", last_off));
break;
}
}
CakeTinStatsAttrs::IntervalUs(val) => {
if last_off == offset {
stack.push(("IntervalUs", last_off));
break;
}
}
CakeTinStatsAttrs::WayIndirectHits(val) => {
if last_off == offset {
stack.push(("WayIndirectHits", last_off));
break;
}
}
CakeTinStatsAttrs::WayMisses(val) => {
if last_off == offset {
stack.push(("WayMisses", last_off));
break;
}
}
CakeTinStatsAttrs::WayCollisions(val) => {
if last_off == offset {
stack.push(("WayCollisions", last_off));
break;
}
}
CakeTinStatsAttrs::PeakDelayUs(val) => {
if last_off == offset {
stack.push(("PeakDelayUs", last_off));
break;
}
}
CakeTinStatsAttrs::AvgDelayUs(val) => {
if last_off == offset {
stack.push(("AvgDelayUs", last_off));
break;
}
}
CakeTinStatsAttrs::BaseDelayUs(val) => {
if last_off == offset {
stack.push(("BaseDelayUs", last_off));
break;
}
}
CakeTinStatsAttrs::SparseFlows(val) => {
if last_off == offset {
stack.push(("SparseFlows", last_off));
break;
}
}
CakeTinStatsAttrs::BulkFlows(val) => {
if last_off == offset {
stack.push(("BulkFlows", last_off));
break;
}
}
CakeTinStatsAttrs::UnresponsiveFlows(val) => {
if last_off == offset {
stack.push(("UnresponsiveFlows", last_off));
break;
}
}
CakeTinStatsAttrs::MaxSkblen(val) => {
if last_off == offset {
stack.push(("MaxSkblen", last_off));
break;
}
}
CakeTinStatsAttrs::FlowQuantum(val) => {
if last_off == offset {
stack.push(("FlowQuantum", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("CakeTinStatsAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum CbsAttrs {
Parms(TcCbsQopt),
}
impl<'a> IterableCbsAttrs<'a> {
pub fn get_parms(&self) -> Result<TcCbsQopt, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CbsAttrs::Parms(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CbsAttrs",
"Parms",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl CbsAttrs {
pub fn new<'a>(buf: &'a [u8]) -> IterableCbsAttrs<'a> {
IterableCbsAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Parms",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableCbsAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableCbsAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableCbsAttrs<'a> {
type Item = Result<CbsAttrs, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => CbsAttrs::Parms({
let res = Some(TcCbsQopt::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"CbsAttrs",
r#type.and_then(|t| CbsAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl std::fmt::Debug for IterableCbsAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("CbsAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
CbsAttrs::Parms(val) => fmt.field("Parms", &val),
};
}
fmt.finish()
}
}
impl IterableCbsAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("CbsAttrs", offset));
return (
stack,
missing_type.and_then(|t| CbsAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
CbsAttrs::Parms(val) => {
if last_off == offset {
stack.push(("Parms", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("CbsAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum CgroupAttrs<'a> {
Act(IterableArrayActAttrs<'a>),
Police(IterablePoliceAttrs<'a>),
Ematches(&'a [u8]),
}
impl<'a> IterableCgroupAttrs<'a> {
pub fn get_act(
&self,
) -> Result<ArrayIterable<IterableArrayActAttrs<'a>, IterableActAttrs<'a>>, ErrorContext> {
for attr in self.clone() {
if let Ok(CgroupAttrs::Act(val)) = attr {
return Ok(ArrayIterable::new(val));
}
}
Err(ErrorContext::new_missing(
"CgroupAttrs",
"Act",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_police(&self) -> Result<IterablePoliceAttrs<'a>, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CgroupAttrs::Police(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CgroupAttrs",
"Police",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_ematches(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CgroupAttrs::Ematches(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CgroupAttrs",
"Ematches",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl CgroupAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableCgroupAttrs<'a> {
IterableCgroupAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Act",
2u16 => "Police",
3u16 => "Ematches",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableCgroupAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableCgroupAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableCgroupAttrs<'a> {
type Item = Result<CgroupAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => CgroupAttrs::Act({
let res = Some(IterableArrayActAttrs::with_loc(next, self.orig_loc));
let Some(val) = res else { break };
val
}),
2u16 => CgroupAttrs::Police({
let res = Some(IterablePoliceAttrs::with_loc(next, self.orig_loc));
let Some(val) = res else { break };
val
}),
3u16 => CgroupAttrs::Ematches({
let res = Some(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"CgroupAttrs",
r#type.and_then(|t| CgroupAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableCgroupAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("CgroupAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
CgroupAttrs::Act(val) => fmt.field("Act", &val),
CgroupAttrs::Police(val) => fmt.field("Police", &val),
CgroupAttrs::Ematches(val) => fmt.field("Ematches", &val),
};
}
fmt.finish()
}
}
impl IterableCgroupAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("CgroupAttrs", offset));
return (
stack,
missing_type.and_then(|t| CgroupAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
let mut missing = None;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
CgroupAttrs::Act(val) => {
for entry in val {
let Ok(attr) = entry else { break };
(stack, missing) = attr.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
if !stack.is_empty() {
stack.push(("Act", last_off));
break;
}
}
CgroupAttrs::Police(val) => {
(stack, missing) = val.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
CgroupAttrs::Ematches(val) => {
if last_off == offset {
stack.push(("Ematches", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("CgroupAttrs", cur));
}
(stack, missing)
}
}
#[derive(Clone)]
pub enum ChokeAttrs<'a> {
Parms(TcRedQopt),
Stab(&'a [u8]),
MaxP(u32),
}
impl<'a> IterableChokeAttrs<'a> {
pub fn get_parms(&self) -> Result<TcRedQopt, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ChokeAttrs::Parms(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ChokeAttrs",
"Parms",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_stab(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ChokeAttrs::Stab(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ChokeAttrs",
"Stab",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_max_p(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ChokeAttrs::MaxP(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ChokeAttrs",
"MaxP",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl ChokeAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableChokeAttrs<'a> {
IterableChokeAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Parms",
2u16 => "Stab",
3u16 => "MaxP",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableChokeAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableChokeAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableChokeAttrs<'a> {
type Item = Result<ChokeAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => ChokeAttrs::Parms({
let res = Some(TcRedQopt::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
2u16 => ChokeAttrs::Stab({
let res = Some(next);
let Some(val) = res else { break };
val
}),
3u16 => ChokeAttrs::MaxP({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"ChokeAttrs",
r#type.and_then(|t| ChokeAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableChokeAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("ChokeAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
ChokeAttrs::Parms(val) => fmt.field("Parms", &val),
ChokeAttrs::Stab(val) => fmt.field("Stab", &val),
ChokeAttrs::MaxP(val) => fmt.field("MaxP", &val),
};
}
fmt.finish()
}
}
impl IterableChokeAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("ChokeAttrs", offset));
return (
stack,
missing_type.and_then(|t| ChokeAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
ChokeAttrs::Parms(val) => {
if last_off == offset {
stack.push(("Parms", last_off));
break;
}
}
ChokeAttrs::Stab(val) => {
if last_off == offset {
stack.push(("Stab", last_off));
break;
}
}
ChokeAttrs::MaxP(val) => {
if last_off == offset {
stack.push(("MaxP", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("ChokeAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum CodelAttrs {
Target(u32),
Limit(u32),
Interval(u32),
Ecn(u32),
CeThreshold(u32),
}
impl<'a> IterableCodelAttrs<'a> {
pub fn get_target(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CodelAttrs::Target(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CodelAttrs",
"Target",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_limit(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CodelAttrs::Limit(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CodelAttrs",
"Limit",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_interval(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CodelAttrs::Interval(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CodelAttrs",
"Interval",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_ecn(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CodelAttrs::Ecn(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CodelAttrs",
"Ecn",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_ce_threshold(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(CodelAttrs::CeThreshold(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"CodelAttrs",
"CeThreshold",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl CodelAttrs {
pub fn new<'a>(buf: &'a [u8]) -> IterableCodelAttrs<'a> {
IterableCodelAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Target",
2u16 => "Limit",
3u16 => "Interval",
4u16 => "Ecn",
5u16 => "CeThreshold",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableCodelAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableCodelAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableCodelAttrs<'a> {
type Item = Result<CodelAttrs, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => CodelAttrs::Target({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
2u16 => CodelAttrs::Limit({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
3u16 => CodelAttrs::Interval({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
4u16 => CodelAttrs::Ecn({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
5u16 => CodelAttrs::CeThreshold({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"CodelAttrs",
r#type.and_then(|t| CodelAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl std::fmt::Debug for IterableCodelAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("CodelAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
CodelAttrs::Target(val) => fmt.field("Target", &val),
CodelAttrs::Limit(val) => fmt.field("Limit", &val),
CodelAttrs::Interval(val) => fmt.field("Interval", &val),
CodelAttrs::Ecn(val) => fmt.field("Ecn", &val),
CodelAttrs::CeThreshold(val) => fmt.field("CeThreshold", &val),
};
}
fmt.finish()
}
}
impl IterableCodelAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("CodelAttrs", offset));
return (
stack,
missing_type.and_then(|t| CodelAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
CodelAttrs::Target(val) => {
if last_off == offset {
stack.push(("Target", last_off));
break;
}
}
CodelAttrs::Limit(val) => {
if last_off == offset {
stack.push(("Limit", last_off));
break;
}
}
CodelAttrs::Interval(val) => {
if last_off == offset {
stack.push(("Interval", last_off));
break;
}
}
CodelAttrs::Ecn(val) => {
if last_off == offset {
stack.push(("Ecn", last_off));
break;
}
}
CodelAttrs::CeThreshold(val) => {
if last_off == offset {
stack.push(("CeThreshold", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("CodelAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum DrrAttrs {
Quantum(u32),
}
impl<'a> IterableDrrAttrs<'a> {
pub fn get_quantum(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(DrrAttrs::Quantum(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"DrrAttrs",
"Quantum",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl DrrAttrs {
pub fn new<'a>(buf: &'a [u8]) -> IterableDrrAttrs<'a> {
IterableDrrAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Quantum",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableDrrAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableDrrAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableDrrAttrs<'a> {
type Item = Result<DrrAttrs, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => DrrAttrs::Quantum({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"DrrAttrs",
r#type.and_then(|t| DrrAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl std::fmt::Debug for IterableDrrAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("DrrAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
DrrAttrs::Quantum(val) => fmt.field("Quantum", &val),
};
}
fmt.finish()
}
}
impl IterableDrrAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("DrrAttrs", offset));
return (
stack,
missing_type.and_then(|t| DrrAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
DrrAttrs::Quantum(val) => {
if last_off == offset {
stack.push(("Quantum", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("DrrAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum Dualpi2Attrs {
#[doc = "Limit of total number of packets in queue\n"]
Limit(u32),
#[doc = "Memory limit of total number of packets in queue\n"]
MemoryLimit(u32),
#[doc = "Classic target delay in microseconds\n"]
Target(u32),
#[doc = "Drop probability update interval time in microseconds\n"]
Tupdate(u32),
#[doc = "Integral gain factor in Hz for PI controller\n"]
Alpha(u32),
#[doc = "Proportional gain factor in Hz for PI controller\n"]
Beta(u32),
#[doc = "L4S step marking threshold in packets\n"]
StepThreshPkts(u32),
#[doc = "L4S Step marking threshold in microseconds\n"]
StepThreshUs(u32),
#[doc = "Packets enqueued to the L-queue can apply the step threshold when the\nqueue length of L-queue is larger than this value. (0 is recommended)\n"]
MinQlenStep(u32),
#[doc = "Probability coupling factor between Classic and L4S (2 is recommended)\n"]
Coupling(u8),
#[doc = "Control the overload strategy (drop to preserve latency or let the queue\noverflow)\n\nAssociated type: [`Dualpi2DropOverload`] (enum)"]
DropOverload(u8),
#[doc = "Decide where the Classic packets are PI-based dropped or marked\n\nAssociated type: [`Dualpi2DropEarly`] (enum)"]
DropEarly(u8),
#[doc = "Classic WRR weight in percentage (from 0 to 100)\n"]
CProtection(u8),
#[doc = "Configure the L-queue ECN classifier\n\nAssociated type: [`Dualpi2EcnMask`] (enum)"]
EcnMask(u8),
#[doc = "Split aggregated skb or not\n\nAssociated type: [`Dualpi2SplitGso`] (enum)"]
SplitGso(u8),
}
impl<'a> IterableDualpi2Attrs<'a> {
#[doc = "Limit of total number of packets in queue\n"]
pub fn get_limit(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(Dualpi2Attrs::Limit(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"Dualpi2Attrs",
"Limit",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "Memory limit of total number of packets in queue\n"]
pub fn get_memory_limit(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(Dualpi2Attrs::MemoryLimit(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"Dualpi2Attrs",
"MemoryLimit",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "Classic target delay in microseconds\n"]
pub fn get_target(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(Dualpi2Attrs::Target(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"Dualpi2Attrs",
"Target",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "Drop probability update interval time in microseconds\n"]
pub fn get_tupdate(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(Dualpi2Attrs::Tupdate(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"Dualpi2Attrs",
"Tupdate",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "Integral gain factor in Hz for PI controller\n"]
pub fn get_alpha(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(Dualpi2Attrs::Alpha(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"Dualpi2Attrs",
"Alpha",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "Proportional gain factor in Hz for PI controller\n"]
pub fn get_beta(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(Dualpi2Attrs::Beta(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"Dualpi2Attrs",
"Beta",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "L4S step marking threshold in packets\n"]
pub fn get_step_thresh_pkts(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(Dualpi2Attrs::StepThreshPkts(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"Dualpi2Attrs",
"StepThreshPkts",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "L4S Step marking threshold in microseconds\n"]
pub fn get_step_thresh_us(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(Dualpi2Attrs::StepThreshUs(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"Dualpi2Attrs",
"StepThreshUs",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "Packets enqueued to the L-queue can apply the step threshold when the\nqueue length of L-queue is larger than this value. (0 is recommended)\n"]
pub fn get_min_qlen_step(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(Dualpi2Attrs::MinQlenStep(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"Dualpi2Attrs",
"MinQlenStep",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "Probability coupling factor between Classic and L4S (2 is recommended)\n"]
pub fn get_coupling(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(Dualpi2Attrs::Coupling(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"Dualpi2Attrs",
"Coupling",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "Control the overload strategy (drop to preserve latency or let the queue\noverflow)\n\nAssociated type: [`Dualpi2DropOverload`] (enum)"]
pub fn get_drop_overload(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(Dualpi2Attrs::DropOverload(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"Dualpi2Attrs",
"DropOverload",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "Decide where the Classic packets are PI-based dropped or marked\n\nAssociated type: [`Dualpi2DropEarly`] (enum)"]
pub fn get_drop_early(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(Dualpi2Attrs::DropEarly(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"Dualpi2Attrs",
"DropEarly",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "Classic WRR weight in percentage (from 0 to 100)\n"]
pub fn get_c_protection(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(Dualpi2Attrs::CProtection(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"Dualpi2Attrs",
"CProtection",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "Configure the L-queue ECN classifier\n\nAssociated type: [`Dualpi2EcnMask`] (enum)"]
pub fn get_ecn_mask(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(Dualpi2Attrs::EcnMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"Dualpi2Attrs",
"EcnMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "Split aggregated skb or not\n\nAssociated type: [`Dualpi2SplitGso`] (enum)"]
pub fn get_split_gso(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(Dualpi2Attrs::SplitGso(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"Dualpi2Attrs",
"SplitGso",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl Dualpi2Attrs {
pub fn new<'a>(buf: &'a [u8]) -> IterableDualpi2Attrs<'a> {
IterableDualpi2Attrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Limit",
2u16 => "MemoryLimit",
3u16 => "Target",
4u16 => "Tupdate",
5u16 => "Alpha",
6u16 => "Beta",
7u16 => "StepThreshPkts",
8u16 => "StepThreshUs",
9u16 => "MinQlenStep",
10u16 => "Coupling",
11u16 => "DropOverload",
12u16 => "DropEarly",
13u16 => "CProtection",
14u16 => "EcnMask",
15u16 => "SplitGso",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableDualpi2Attrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableDualpi2Attrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableDualpi2Attrs<'a> {
type Item = Result<Dualpi2Attrs, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => Dualpi2Attrs::Limit({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
2u16 => Dualpi2Attrs::MemoryLimit({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
3u16 => Dualpi2Attrs::Target({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
4u16 => Dualpi2Attrs::Tupdate({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
5u16 => Dualpi2Attrs::Alpha({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
6u16 => Dualpi2Attrs::Beta({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
7u16 => Dualpi2Attrs::StepThreshPkts({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
8u16 => Dualpi2Attrs::StepThreshUs({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
9u16 => Dualpi2Attrs::MinQlenStep({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
10u16 => Dualpi2Attrs::Coupling({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
11u16 => Dualpi2Attrs::DropOverload({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
12u16 => Dualpi2Attrs::DropEarly({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
13u16 => Dualpi2Attrs::CProtection({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
14u16 => Dualpi2Attrs::EcnMask({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
15u16 => Dualpi2Attrs::SplitGso({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"Dualpi2Attrs",
r#type.and_then(|t| Dualpi2Attrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl std::fmt::Debug for IterableDualpi2Attrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("Dualpi2Attrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
Dualpi2Attrs::Limit(val) => fmt.field("Limit", &val),
Dualpi2Attrs::MemoryLimit(val) => fmt.field("MemoryLimit", &val),
Dualpi2Attrs::Target(val) => fmt.field("Target", &val),
Dualpi2Attrs::Tupdate(val) => fmt.field("Tupdate", &val),
Dualpi2Attrs::Alpha(val) => fmt.field("Alpha", &val),
Dualpi2Attrs::Beta(val) => fmt.field("Beta", &val),
Dualpi2Attrs::StepThreshPkts(val) => fmt.field("StepThreshPkts", &val),
Dualpi2Attrs::StepThreshUs(val) => fmt.field("StepThreshUs", &val),
Dualpi2Attrs::MinQlenStep(val) => fmt.field("MinQlenStep", &val),
Dualpi2Attrs::Coupling(val) => fmt.field("Coupling", &val),
Dualpi2Attrs::DropOverload(val) => fmt.field(
"DropOverload",
&FormatEnum(val.into(), Dualpi2DropOverload::from_value),
),
Dualpi2Attrs::DropEarly(val) => fmt.field(
"DropEarly",
&FormatEnum(val.into(), Dualpi2DropEarly::from_value),
),
Dualpi2Attrs::CProtection(val) => fmt.field("CProtection", &val),
Dualpi2Attrs::EcnMask(val) => fmt.field(
"EcnMask",
&FormatEnum(val.into(), Dualpi2EcnMask::from_value),
),
Dualpi2Attrs::SplitGso(val) => fmt.field(
"SplitGso",
&FormatEnum(val.into(), Dualpi2SplitGso::from_value),
),
};
}
fmt.finish()
}
}
impl IterableDualpi2Attrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("Dualpi2Attrs", offset));
return (
stack,
missing_type.and_then(|t| Dualpi2Attrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
Dualpi2Attrs::Limit(val) => {
if last_off == offset {
stack.push(("Limit", last_off));
break;
}
}
Dualpi2Attrs::MemoryLimit(val) => {
if last_off == offset {
stack.push(("MemoryLimit", last_off));
break;
}
}
Dualpi2Attrs::Target(val) => {
if last_off == offset {
stack.push(("Target", last_off));
break;
}
}
Dualpi2Attrs::Tupdate(val) => {
if last_off == offset {
stack.push(("Tupdate", last_off));
break;
}
}
Dualpi2Attrs::Alpha(val) => {
if last_off == offset {
stack.push(("Alpha", last_off));
break;
}
}
Dualpi2Attrs::Beta(val) => {
if last_off == offset {
stack.push(("Beta", last_off));
break;
}
}
Dualpi2Attrs::StepThreshPkts(val) => {
if last_off == offset {
stack.push(("StepThreshPkts", last_off));
break;
}
}
Dualpi2Attrs::StepThreshUs(val) => {
if last_off == offset {
stack.push(("StepThreshUs", last_off));
break;
}
}
Dualpi2Attrs::MinQlenStep(val) => {
if last_off == offset {
stack.push(("MinQlenStep", last_off));
break;
}
}
Dualpi2Attrs::Coupling(val) => {
if last_off == offset {
stack.push(("Coupling", last_off));
break;
}
}
Dualpi2Attrs::DropOverload(val) => {
if last_off == offset {
stack.push(("DropOverload", last_off));
break;
}
}
Dualpi2Attrs::DropEarly(val) => {
if last_off == offset {
stack.push(("DropEarly", last_off));
break;
}
}
Dualpi2Attrs::CProtection(val) => {
if last_off == offset {
stack.push(("CProtection", last_off));
break;
}
}
Dualpi2Attrs::EcnMask(val) => {
if last_off == offset {
stack.push(("EcnMask", last_off));
break;
}
}
Dualpi2Attrs::SplitGso(val) => {
if last_off == offset {
stack.push(("SplitGso", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("Dualpi2Attrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum EmatchAttrs<'a> {
TreeHdr(TcfEmatchTreeHdr),
TreeList(&'a [u8]),
}
impl<'a> IterableEmatchAttrs<'a> {
pub fn get_tree_hdr(&self) -> Result<TcfEmatchTreeHdr, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(EmatchAttrs::TreeHdr(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"EmatchAttrs",
"TreeHdr",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_tree_list(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(EmatchAttrs::TreeList(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"EmatchAttrs",
"TreeList",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl EmatchAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableEmatchAttrs<'a> {
IterableEmatchAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "TreeHdr",
2u16 => "TreeList",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableEmatchAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableEmatchAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableEmatchAttrs<'a> {
type Item = Result<EmatchAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => EmatchAttrs::TreeHdr({
let res = Some(TcfEmatchTreeHdr::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
2u16 => EmatchAttrs::TreeList({
let res = Some(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"EmatchAttrs",
r#type.and_then(|t| EmatchAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableEmatchAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("EmatchAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
EmatchAttrs::TreeHdr(val) => fmt.field("TreeHdr", &val),
EmatchAttrs::TreeList(val) => fmt.field("TreeList", &val),
};
}
fmt.finish()
}
}
impl IterableEmatchAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("EmatchAttrs", offset));
return (
stack,
missing_type.and_then(|t| EmatchAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
EmatchAttrs::TreeHdr(val) => {
if last_off == offset {
stack.push(("TreeHdr", last_off));
break;
}
}
EmatchAttrs::TreeList(val) => {
if last_off == offset {
stack.push(("TreeList", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("EmatchAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum FlowAttrs<'a> {
Keys(u32),
Mode(u32),
Baseclass(u32),
Rshift(u32),
Addend(u32),
Mask(u32),
Xor(u32),
Divisor(u32),
Act(&'a [u8]),
Police(IterablePoliceAttrs<'a>),
Ematches(&'a [u8]),
Perturb(u32),
}
impl<'a> IterableFlowAttrs<'a> {
pub fn get_keys(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowAttrs::Keys(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowAttrs",
"Keys",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_mode(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowAttrs::Mode(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowAttrs",
"Mode",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_baseclass(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowAttrs::Baseclass(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowAttrs",
"Baseclass",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_rshift(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowAttrs::Rshift(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowAttrs",
"Rshift",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_addend(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowAttrs::Addend(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowAttrs",
"Addend",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_mask(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowAttrs::Mask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowAttrs",
"Mask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_xor(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowAttrs::Xor(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowAttrs",
"Xor",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_divisor(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowAttrs::Divisor(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowAttrs",
"Divisor",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_act(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowAttrs::Act(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowAttrs",
"Act",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_police(&self) -> Result<IterablePoliceAttrs<'a>, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowAttrs::Police(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowAttrs",
"Police",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_ematches(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowAttrs::Ematches(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowAttrs",
"Ematches",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_perturb(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowAttrs::Perturb(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowAttrs",
"Perturb",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl FlowAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableFlowAttrs<'a> {
IterableFlowAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Keys",
2u16 => "Mode",
3u16 => "Baseclass",
4u16 => "Rshift",
5u16 => "Addend",
6u16 => "Mask",
7u16 => "Xor",
8u16 => "Divisor",
9u16 => "Act",
10u16 => "Police",
11u16 => "Ematches",
12u16 => "Perturb",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableFlowAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableFlowAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableFlowAttrs<'a> {
type Item = Result<FlowAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => FlowAttrs::Keys({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
2u16 => FlowAttrs::Mode({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
3u16 => FlowAttrs::Baseclass({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
4u16 => FlowAttrs::Rshift({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
5u16 => FlowAttrs::Addend({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
6u16 => FlowAttrs::Mask({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
7u16 => FlowAttrs::Xor({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
8u16 => FlowAttrs::Divisor({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
9u16 => FlowAttrs::Act({
let res = Some(next);
let Some(val) = res else { break };
val
}),
10u16 => FlowAttrs::Police({
let res = Some(IterablePoliceAttrs::with_loc(next, self.orig_loc));
let Some(val) = res else { break };
val
}),
11u16 => FlowAttrs::Ematches({
let res = Some(next);
let Some(val) = res else { break };
val
}),
12u16 => FlowAttrs::Perturb({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"FlowAttrs",
r#type.and_then(|t| FlowAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableFlowAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("FlowAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
FlowAttrs::Keys(val) => fmt.field("Keys", &val),
FlowAttrs::Mode(val) => fmt.field("Mode", &val),
FlowAttrs::Baseclass(val) => fmt.field("Baseclass", &val),
FlowAttrs::Rshift(val) => fmt.field("Rshift", &val),
FlowAttrs::Addend(val) => fmt.field("Addend", &val),
FlowAttrs::Mask(val) => fmt.field("Mask", &val),
FlowAttrs::Xor(val) => fmt.field("Xor", &val),
FlowAttrs::Divisor(val) => fmt.field("Divisor", &val),
FlowAttrs::Act(val) => fmt.field("Act", &val),
FlowAttrs::Police(val) => fmt.field("Police", &val),
FlowAttrs::Ematches(val) => fmt.field("Ematches", &val),
FlowAttrs::Perturb(val) => fmt.field("Perturb", &val),
};
}
fmt.finish()
}
}
impl IterableFlowAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("FlowAttrs", offset));
return (
stack,
missing_type.and_then(|t| FlowAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
let mut missing = None;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
FlowAttrs::Keys(val) => {
if last_off == offset {
stack.push(("Keys", last_off));
break;
}
}
FlowAttrs::Mode(val) => {
if last_off == offset {
stack.push(("Mode", last_off));
break;
}
}
FlowAttrs::Baseclass(val) => {
if last_off == offset {
stack.push(("Baseclass", last_off));
break;
}
}
FlowAttrs::Rshift(val) => {
if last_off == offset {
stack.push(("Rshift", last_off));
break;
}
}
FlowAttrs::Addend(val) => {
if last_off == offset {
stack.push(("Addend", last_off));
break;
}
}
FlowAttrs::Mask(val) => {
if last_off == offset {
stack.push(("Mask", last_off));
break;
}
}
FlowAttrs::Xor(val) => {
if last_off == offset {
stack.push(("Xor", last_off));
break;
}
}
FlowAttrs::Divisor(val) => {
if last_off == offset {
stack.push(("Divisor", last_off));
break;
}
}
FlowAttrs::Act(val) => {
if last_off == offset {
stack.push(("Act", last_off));
break;
}
}
FlowAttrs::Police(val) => {
(stack, missing) = val.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
FlowAttrs::Ematches(val) => {
if last_off == offset {
stack.push(("Ematches", last_off));
break;
}
}
FlowAttrs::Perturb(val) => {
if last_off == offset {
stack.push(("Perturb", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("FlowAttrs", cur));
}
(stack, missing)
}
}
#[derive(Clone)]
pub enum FlowerAttrs<'a> {
Classid(u32),
Indev(&'a CStr),
Act(IterableArrayActAttrs<'a>),
KeyEthDst(&'a [u8]),
KeyEthDstMask(&'a [u8]),
KeyEthSrc(&'a [u8]),
KeyEthSrcMask(&'a [u8]),
KeyEthType(u16),
KeyIpProto(u8),
KeyIpv4Src(std::net::Ipv4Addr),
KeyIpv4SrcMask(std::net::Ipv4Addr),
KeyIpv4Dst(std::net::Ipv4Addr),
KeyIpv4DstMask(std::net::Ipv4Addr),
KeyIpv6Src(&'a [u8]),
KeyIpv6SrcMask(&'a [u8]),
KeyIpv6Dst(&'a [u8]),
KeyIpv6DstMask(&'a [u8]),
KeyTcpSrc(u16),
KeyTcpDst(u16),
KeyUdpSrc(u16),
KeyUdpDst(u16),
#[doc = "Associated type: [`ClsFlags`] (1 bit per enumeration)"]
Flags(u32),
KeyVlanId(u16),
KeyVlanPrio(u8),
KeyVlanEthType(u16),
KeyEncKeyId(u32),
KeyEncIpv4Src(std::net::Ipv4Addr),
KeyEncIpv4SrcMask(std::net::Ipv4Addr),
KeyEncIpv4Dst(std::net::Ipv4Addr),
KeyEncIpv4DstMask(std::net::Ipv4Addr),
KeyEncIpv6Src(&'a [u8]),
KeyEncIpv6SrcMask(&'a [u8]),
KeyEncIpv6Dst(&'a [u8]),
KeyEncIpv6DstMask(&'a [u8]),
KeyTcpSrcMask(u16),
KeyTcpDstMask(u16),
KeyUdpSrcMask(u16),
KeyUdpDstMask(u16),
KeySctpSrcMask(u16),
KeySctpDstMask(u16),
KeySctpSrc(u16),
KeySctpDst(u16),
KeyEncUdpSrcPort(u16),
KeyEncUdpSrcPortMask(u16),
KeyEncUdpDstPort(u16),
KeyEncUdpDstPortMask(u16),
#[doc = "Associated type: [`FlowerKeyCtrlFlags`] (1 bit per enumeration)"]
KeyFlags(u32),
#[doc = "Associated type: [`FlowerKeyCtrlFlags`] (1 bit per enumeration)"]
KeyFlagsMask(u32),
KeyIcmpv4Code(u8),
KeyIcmpv4CodeMask(u8),
KeyIcmpv4Type(u8),
KeyIcmpv4TypeMask(u8),
KeyIcmpv6Code(u8),
KeyIcmpv6CodeMask(u8),
KeyIcmpv6Type(u8),
KeyIcmpv6TypeMask(u8),
KeyArpSip(u32),
KeyArpSipMask(u32),
KeyArpTip(u32),
KeyArpTipMask(u32),
KeyArpOp(u8),
KeyArpOpMask(u8),
KeyArpSha(&'a [u8]),
KeyArpShaMask(&'a [u8]),
KeyArpTha(&'a [u8]),
KeyArpThaMask(&'a [u8]),
KeyMplsTtl(u8),
KeyMplsBos(u8),
KeyMplsTc(u8),
KeyMplsLabel(u32),
KeyTcpFlags(u16),
KeyTcpFlagsMask(u16),
KeyIpTos(u8),
KeyIpTosMask(u8),
KeyIpTtl(u8),
KeyIpTtlMask(u8),
KeyCvlanId(u16),
KeyCvlanPrio(u8),
KeyCvlanEthType(u16),
KeyEncIpTos(u8),
KeyEncIpTosMask(u8),
KeyEncIpTtl(u8),
KeyEncIpTtlMask(u8),
KeyEncOpts(IterableFlowerKeyEncOptsAttrs<'a>),
KeyEncOptsMask(IterableFlowerKeyEncOptsAttrs<'a>),
InHwCount(u32),
KeyPortSrcMin(u16),
KeyPortSrcMax(u16),
KeyPortDstMin(u16),
KeyPortDstMax(u16),
KeyCtState(u16),
KeyCtStateMask(u16),
KeyCtZone(u16),
KeyCtZoneMask(u16),
KeyCtMark(u32),
KeyCtMarkMask(u32),
KeyCtLabels(&'a [u8]),
KeyCtLabelsMask(&'a [u8]),
KeyMplsOpts(IterableFlowerKeyMplsOptAttrs<'a>),
KeyHash(u32),
KeyHashMask(u32),
KeyNumOfVlans(u8),
KeyPppoeSid(u16),
KeyPppProto(u16),
KeyL2tpv3Sid(u32),
L2Miss(u8),
KeyCfm(IterableFlowerKeyCfmAttrs<'a>),
KeySpi(u32),
KeySpiMask(u32),
#[doc = "Associated type: [`FlowerKeyCtrlFlags`] (1 bit per enumeration)"]
KeyEncFlags(u32),
#[doc = "Associated type: [`FlowerKeyCtrlFlags`] (1 bit per enumeration)"]
KeyEncFlagsMask(u32),
}
impl<'a> IterableFlowerAttrs<'a> {
pub fn get_classid(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::Classid(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"Classid",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_indev(&self) -> Result<&'a CStr, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::Indev(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"Indev",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_act(
&self,
) -> Result<ArrayIterable<IterableArrayActAttrs<'a>, IterableActAttrs<'a>>, ErrorContext> {
for attr in self.clone() {
if let Ok(FlowerAttrs::Act(val)) = attr {
return Ok(ArrayIterable::new(val));
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"Act",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_eth_dst(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyEthDst(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyEthDst",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_eth_dst_mask(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyEthDstMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyEthDstMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_eth_src(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyEthSrc(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyEthSrc",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_eth_src_mask(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyEthSrcMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyEthSrcMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_eth_type(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyEthType(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyEthType",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_ip_proto(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyIpProto(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyIpProto",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_ipv4_src(&self) -> Result<std::net::Ipv4Addr, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyIpv4Src(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyIpv4Src",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_ipv4_src_mask(&self) -> Result<std::net::Ipv4Addr, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyIpv4SrcMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyIpv4SrcMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_ipv4_dst(&self) -> Result<std::net::Ipv4Addr, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyIpv4Dst(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyIpv4Dst",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_ipv4_dst_mask(&self) -> Result<std::net::Ipv4Addr, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyIpv4DstMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyIpv4DstMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_ipv6_src(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyIpv6Src(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyIpv6Src",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_ipv6_src_mask(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyIpv6SrcMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyIpv6SrcMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_ipv6_dst(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyIpv6Dst(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyIpv6Dst",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_ipv6_dst_mask(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyIpv6DstMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyIpv6DstMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_tcp_src(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyTcpSrc(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyTcpSrc",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_tcp_dst(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyTcpDst(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyTcpDst",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_udp_src(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyUdpSrc(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyUdpSrc",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_udp_dst(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyUdpDst(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyUdpDst",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "Associated type: [`ClsFlags`] (1 bit per enumeration)"]
pub fn get_flags(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::Flags(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"Flags",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_vlan_id(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyVlanId(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyVlanId",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_vlan_prio(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyVlanPrio(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyVlanPrio",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_vlan_eth_type(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyVlanEthType(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyVlanEthType",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_enc_key_id(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyEncKeyId(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyEncKeyId",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_enc_ipv4_src(&self) -> Result<std::net::Ipv4Addr, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyEncIpv4Src(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyEncIpv4Src",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_enc_ipv4_src_mask(&self) -> Result<std::net::Ipv4Addr, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyEncIpv4SrcMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyEncIpv4SrcMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_enc_ipv4_dst(&self) -> Result<std::net::Ipv4Addr, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyEncIpv4Dst(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyEncIpv4Dst",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_enc_ipv4_dst_mask(&self) -> Result<std::net::Ipv4Addr, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyEncIpv4DstMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyEncIpv4DstMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_enc_ipv6_src(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyEncIpv6Src(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyEncIpv6Src",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_enc_ipv6_src_mask(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyEncIpv6SrcMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyEncIpv6SrcMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_enc_ipv6_dst(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyEncIpv6Dst(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyEncIpv6Dst",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_enc_ipv6_dst_mask(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyEncIpv6DstMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyEncIpv6DstMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_tcp_src_mask(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyTcpSrcMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyTcpSrcMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_tcp_dst_mask(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyTcpDstMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyTcpDstMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_udp_src_mask(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyUdpSrcMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyUdpSrcMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_udp_dst_mask(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyUdpDstMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyUdpDstMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_sctp_src_mask(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeySctpSrcMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeySctpSrcMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_sctp_dst_mask(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeySctpDstMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeySctpDstMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_sctp_src(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeySctpSrc(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeySctpSrc",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_sctp_dst(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeySctpDst(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeySctpDst",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_enc_udp_src_port(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyEncUdpSrcPort(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyEncUdpSrcPort",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_enc_udp_src_port_mask(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyEncUdpSrcPortMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyEncUdpSrcPortMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_enc_udp_dst_port(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyEncUdpDstPort(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyEncUdpDstPort",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_enc_udp_dst_port_mask(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyEncUdpDstPortMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyEncUdpDstPortMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "Associated type: [`FlowerKeyCtrlFlags`] (1 bit per enumeration)"]
pub fn get_key_flags(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyFlags(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyFlags",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "Associated type: [`FlowerKeyCtrlFlags`] (1 bit per enumeration)"]
pub fn get_key_flags_mask(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyFlagsMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyFlagsMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_icmpv4_code(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyIcmpv4Code(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyIcmpv4Code",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_icmpv4_code_mask(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyIcmpv4CodeMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyIcmpv4CodeMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_icmpv4_type(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyIcmpv4Type(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyIcmpv4Type",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_icmpv4_type_mask(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyIcmpv4TypeMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyIcmpv4TypeMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_icmpv6_code(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyIcmpv6Code(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyIcmpv6Code",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_icmpv6_code_mask(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyIcmpv6CodeMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyIcmpv6CodeMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_icmpv6_type(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyIcmpv6Type(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyIcmpv6Type",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_icmpv6_type_mask(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyIcmpv6TypeMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyIcmpv6TypeMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_arp_sip(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyArpSip(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyArpSip",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_arp_sip_mask(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyArpSipMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyArpSipMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_arp_tip(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyArpTip(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyArpTip",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_arp_tip_mask(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyArpTipMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyArpTipMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_arp_op(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyArpOp(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyArpOp",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_arp_op_mask(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyArpOpMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyArpOpMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_arp_sha(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyArpSha(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyArpSha",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_arp_sha_mask(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyArpShaMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyArpShaMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_arp_tha(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyArpTha(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyArpTha",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_arp_tha_mask(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyArpThaMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyArpThaMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_mpls_ttl(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyMplsTtl(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyMplsTtl",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_mpls_bos(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyMplsBos(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyMplsBos",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_mpls_tc(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyMplsTc(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyMplsTc",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_mpls_label(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyMplsLabel(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyMplsLabel",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_tcp_flags(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyTcpFlags(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyTcpFlags",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_tcp_flags_mask(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyTcpFlagsMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyTcpFlagsMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_ip_tos(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyIpTos(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyIpTos",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_ip_tos_mask(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyIpTosMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyIpTosMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_ip_ttl(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyIpTtl(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyIpTtl",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_ip_ttl_mask(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyIpTtlMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyIpTtlMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_cvlan_id(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyCvlanId(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyCvlanId",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_cvlan_prio(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyCvlanPrio(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyCvlanPrio",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_cvlan_eth_type(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyCvlanEthType(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyCvlanEthType",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_enc_ip_tos(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyEncIpTos(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyEncIpTos",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_enc_ip_tos_mask(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyEncIpTosMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyEncIpTosMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_enc_ip_ttl(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyEncIpTtl(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyEncIpTtl",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_enc_ip_ttl_mask(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyEncIpTtlMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyEncIpTtlMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_enc_opts(&self) -> Result<IterableFlowerKeyEncOptsAttrs<'a>, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyEncOpts(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyEncOpts",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_enc_opts_mask(&self) -> Result<IterableFlowerKeyEncOptsAttrs<'a>, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyEncOptsMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyEncOptsMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_in_hw_count(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::InHwCount(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"InHwCount",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_port_src_min(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyPortSrcMin(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyPortSrcMin",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_port_src_max(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyPortSrcMax(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyPortSrcMax",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_port_dst_min(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyPortDstMin(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyPortDstMin",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_port_dst_max(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyPortDstMax(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyPortDstMax",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_ct_state(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyCtState(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyCtState",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_ct_state_mask(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyCtStateMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyCtStateMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_ct_zone(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyCtZone(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyCtZone",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_ct_zone_mask(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyCtZoneMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyCtZoneMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_ct_mark(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyCtMark(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyCtMark",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_ct_mark_mask(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyCtMarkMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyCtMarkMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_ct_labels(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyCtLabels(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyCtLabels",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_ct_labels_mask(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyCtLabelsMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyCtLabelsMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_mpls_opts(&self) -> Result<IterableFlowerKeyMplsOptAttrs<'a>, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyMplsOpts(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyMplsOpts",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_hash(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyHash(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyHash",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_hash_mask(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyHashMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyHashMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_num_of_vlans(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyNumOfVlans(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyNumOfVlans",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_pppoe_sid(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyPppoeSid(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyPppoeSid",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_ppp_proto(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyPppProto(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyPppProto",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_l2tpv3_sid(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyL2tpv3Sid(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyL2tpv3Sid",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_l2_miss(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::L2Miss(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"L2Miss",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_cfm(&self) -> Result<IterableFlowerKeyCfmAttrs<'a>, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyCfm(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyCfm",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_spi(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeySpi(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeySpi",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_key_spi_mask(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeySpiMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeySpiMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "Associated type: [`FlowerKeyCtrlFlags`] (1 bit per enumeration)"]
pub fn get_key_enc_flags(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyEncFlags(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyEncFlags",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "Associated type: [`FlowerKeyCtrlFlags`] (1 bit per enumeration)"]
pub fn get_key_enc_flags_mask(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerAttrs::KeyEncFlagsMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerAttrs",
"KeyEncFlagsMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl FlowerAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableFlowerAttrs<'a> {
IterableFlowerAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Classid",
2u16 => "Indev",
3u16 => "Act",
4u16 => "KeyEthDst",
5u16 => "KeyEthDstMask",
6u16 => "KeyEthSrc",
7u16 => "KeyEthSrcMask",
8u16 => "KeyEthType",
9u16 => "KeyIpProto",
10u16 => "KeyIpv4Src",
11u16 => "KeyIpv4SrcMask",
12u16 => "KeyIpv4Dst",
13u16 => "KeyIpv4DstMask",
14u16 => "KeyIpv6Src",
15u16 => "KeyIpv6SrcMask",
16u16 => "KeyIpv6Dst",
17u16 => "KeyIpv6DstMask",
18u16 => "KeyTcpSrc",
19u16 => "KeyTcpDst",
20u16 => "KeyUdpSrc",
21u16 => "KeyUdpDst",
22u16 => "Flags",
23u16 => "KeyVlanId",
24u16 => "KeyVlanPrio",
25u16 => "KeyVlanEthType",
26u16 => "KeyEncKeyId",
27u16 => "KeyEncIpv4Src",
28u16 => "KeyEncIpv4SrcMask",
29u16 => "KeyEncIpv4Dst",
30u16 => "KeyEncIpv4DstMask",
31u16 => "KeyEncIpv6Src",
32u16 => "KeyEncIpv6SrcMask",
33u16 => "KeyEncIpv6Dst",
34u16 => "KeyEncIpv6DstMask",
35u16 => "KeyTcpSrcMask",
36u16 => "KeyTcpDstMask",
37u16 => "KeyUdpSrcMask",
38u16 => "KeyUdpDstMask",
39u16 => "KeySctpSrcMask",
40u16 => "KeySctpDstMask",
41u16 => "KeySctpSrc",
42u16 => "KeySctpDst",
43u16 => "KeyEncUdpSrcPort",
44u16 => "KeyEncUdpSrcPortMask",
45u16 => "KeyEncUdpDstPort",
46u16 => "KeyEncUdpDstPortMask",
47u16 => "KeyFlags",
48u16 => "KeyFlagsMask",
49u16 => "KeyIcmpv4Code",
50u16 => "KeyIcmpv4CodeMask",
51u16 => "KeyIcmpv4Type",
52u16 => "KeyIcmpv4TypeMask",
53u16 => "KeyIcmpv6Code",
54u16 => "KeyIcmpv6CodeMask",
55u16 => "KeyIcmpv6Type",
56u16 => "KeyIcmpv6TypeMask",
57u16 => "KeyArpSip",
58u16 => "KeyArpSipMask",
59u16 => "KeyArpTip",
60u16 => "KeyArpTipMask",
61u16 => "KeyArpOp",
62u16 => "KeyArpOpMask",
63u16 => "KeyArpSha",
64u16 => "KeyArpShaMask",
65u16 => "KeyArpTha",
66u16 => "KeyArpThaMask",
67u16 => "KeyMplsTtl",
68u16 => "KeyMplsBos",
69u16 => "KeyMplsTc",
70u16 => "KeyMplsLabel",
71u16 => "KeyTcpFlags",
72u16 => "KeyTcpFlagsMask",
73u16 => "KeyIpTos",
74u16 => "KeyIpTosMask",
75u16 => "KeyIpTtl",
76u16 => "KeyIpTtlMask",
77u16 => "KeyCvlanId",
78u16 => "KeyCvlanPrio",
79u16 => "KeyCvlanEthType",
80u16 => "KeyEncIpTos",
81u16 => "KeyEncIpTosMask",
82u16 => "KeyEncIpTtl",
83u16 => "KeyEncIpTtlMask",
84u16 => "KeyEncOpts",
85u16 => "KeyEncOptsMask",
86u16 => "InHwCount",
87u16 => "KeyPortSrcMin",
88u16 => "KeyPortSrcMax",
89u16 => "KeyPortDstMin",
90u16 => "KeyPortDstMax",
91u16 => "KeyCtState",
92u16 => "KeyCtStateMask",
93u16 => "KeyCtZone",
94u16 => "KeyCtZoneMask",
95u16 => "KeyCtMark",
96u16 => "KeyCtMarkMask",
97u16 => "KeyCtLabels",
98u16 => "KeyCtLabelsMask",
99u16 => "KeyMplsOpts",
100u16 => "KeyHash",
101u16 => "KeyHashMask",
102u16 => "KeyNumOfVlans",
103u16 => "KeyPppoeSid",
104u16 => "KeyPppProto",
105u16 => "KeyL2tpv3Sid",
106u16 => "L2Miss",
107u16 => "KeyCfm",
108u16 => "KeySpi",
109u16 => "KeySpiMask",
110u16 => "KeyEncFlags",
111u16 => "KeyEncFlagsMask",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableFlowerAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableFlowerAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableFlowerAttrs<'a> {
type Item = Result<FlowerAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => FlowerAttrs::Classid({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
2u16 => FlowerAttrs::Indev({
let res = CStr::from_bytes_with_nul(next).ok();
let Some(val) = res else { break };
val
}),
3u16 => FlowerAttrs::Act({
let res = Some(IterableArrayActAttrs::with_loc(next, self.orig_loc));
let Some(val) = res else { break };
val
}),
4u16 => FlowerAttrs::KeyEthDst({
let res = Some(next);
let Some(val) = res else { break };
val
}),
5u16 => FlowerAttrs::KeyEthDstMask({
let res = Some(next);
let Some(val) = res else { break };
val
}),
6u16 => FlowerAttrs::KeyEthSrc({
let res = Some(next);
let Some(val) = res else { break };
val
}),
7u16 => FlowerAttrs::KeyEthSrcMask({
let res = Some(next);
let Some(val) = res else { break };
val
}),
8u16 => FlowerAttrs::KeyEthType({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
9u16 => FlowerAttrs::KeyIpProto({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
10u16 => FlowerAttrs::KeyIpv4Src({
let res = parse_be_u32(next).map(Ipv4Addr::from_bits);
let Some(val) = res else { break };
val
}),
11u16 => FlowerAttrs::KeyIpv4SrcMask({
let res = parse_be_u32(next).map(Ipv4Addr::from_bits);
let Some(val) = res else { break };
val
}),
12u16 => FlowerAttrs::KeyIpv4Dst({
let res = parse_be_u32(next).map(Ipv4Addr::from_bits);
let Some(val) = res else { break };
val
}),
13u16 => FlowerAttrs::KeyIpv4DstMask({
let res = parse_be_u32(next).map(Ipv4Addr::from_bits);
let Some(val) = res else { break };
val
}),
14u16 => FlowerAttrs::KeyIpv6Src({
let res = Some(next);
let Some(val) = res else { break };
val
}),
15u16 => FlowerAttrs::KeyIpv6SrcMask({
let res = Some(next);
let Some(val) = res else { break };
val
}),
16u16 => FlowerAttrs::KeyIpv6Dst({
let res = Some(next);
let Some(val) = res else { break };
val
}),
17u16 => FlowerAttrs::KeyIpv6DstMask({
let res = Some(next);
let Some(val) = res else { break };
val
}),
18u16 => FlowerAttrs::KeyTcpSrc({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
19u16 => FlowerAttrs::KeyTcpDst({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
20u16 => FlowerAttrs::KeyUdpSrc({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
21u16 => FlowerAttrs::KeyUdpDst({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
22u16 => FlowerAttrs::Flags({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
23u16 => FlowerAttrs::KeyVlanId({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
24u16 => FlowerAttrs::KeyVlanPrio({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
25u16 => FlowerAttrs::KeyVlanEthType({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
26u16 => FlowerAttrs::KeyEncKeyId({
let res = parse_be_u32(next);
let Some(val) = res else { break };
val
}),
27u16 => FlowerAttrs::KeyEncIpv4Src({
let res = parse_be_u32(next).map(Ipv4Addr::from_bits);
let Some(val) = res else { break };
val
}),
28u16 => FlowerAttrs::KeyEncIpv4SrcMask({
let res = parse_be_u32(next).map(Ipv4Addr::from_bits);
let Some(val) = res else { break };
val
}),
29u16 => FlowerAttrs::KeyEncIpv4Dst({
let res = parse_be_u32(next).map(Ipv4Addr::from_bits);
let Some(val) = res else { break };
val
}),
30u16 => FlowerAttrs::KeyEncIpv4DstMask({
let res = parse_be_u32(next).map(Ipv4Addr::from_bits);
let Some(val) = res else { break };
val
}),
31u16 => FlowerAttrs::KeyEncIpv6Src({
let res = Some(next);
let Some(val) = res else { break };
val
}),
32u16 => FlowerAttrs::KeyEncIpv6SrcMask({
let res = Some(next);
let Some(val) = res else { break };
val
}),
33u16 => FlowerAttrs::KeyEncIpv6Dst({
let res = Some(next);
let Some(val) = res else { break };
val
}),
34u16 => FlowerAttrs::KeyEncIpv6DstMask({
let res = Some(next);
let Some(val) = res else { break };
val
}),
35u16 => FlowerAttrs::KeyTcpSrcMask({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
36u16 => FlowerAttrs::KeyTcpDstMask({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
37u16 => FlowerAttrs::KeyUdpSrcMask({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
38u16 => FlowerAttrs::KeyUdpDstMask({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
39u16 => FlowerAttrs::KeySctpSrcMask({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
40u16 => FlowerAttrs::KeySctpDstMask({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
41u16 => FlowerAttrs::KeySctpSrc({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
42u16 => FlowerAttrs::KeySctpDst({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
43u16 => FlowerAttrs::KeyEncUdpSrcPort({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
44u16 => FlowerAttrs::KeyEncUdpSrcPortMask({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
45u16 => FlowerAttrs::KeyEncUdpDstPort({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
46u16 => FlowerAttrs::KeyEncUdpDstPortMask({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
47u16 => FlowerAttrs::KeyFlags({
let res = parse_be_u32(next);
let Some(val) = res else { break };
val
}),
48u16 => FlowerAttrs::KeyFlagsMask({
let res = parse_be_u32(next);
let Some(val) = res else { break };
val
}),
49u16 => FlowerAttrs::KeyIcmpv4Code({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
50u16 => FlowerAttrs::KeyIcmpv4CodeMask({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
51u16 => FlowerAttrs::KeyIcmpv4Type({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
52u16 => FlowerAttrs::KeyIcmpv4TypeMask({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
53u16 => FlowerAttrs::KeyIcmpv6Code({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
54u16 => FlowerAttrs::KeyIcmpv6CodeMask({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
55u16 => FlowerAttrs::KeyIcmpv6Type({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
56u16 => FlowerAttrs::KeyIcmpv6TypeMask({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
57u16 => FlowerAttrs::KeyArpSip({
let res = parse_be_u32(next);
let Some(val) = res else { break };
val
}),
58u16 => FlowerAttrs::KeyArpSipMask({
let res = parse_be_u32(next);
let Some(val) = res else { break };
val
}),
59u16 => FlowerAttrs::KeyArpTip({
let res = parse_be_u32(next);
let Some(val) = res else { break };
val
}),
60u16 => FlowerAttrs::KeyArpTipMask({
let res = parse_be_u32(next);
let Some(val) = res else { break };
val
}),
61u16 => FlowerAttrs::KeyArpOp({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
62u16 => FlowerAttrs::KeyArpOpMask({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
63u16 => FlowerAttrs::KeyArpSha({
let res = Some(next);
let Some(val) = res else { break };
val
}),
64u16 => FlowerAttrs::KeyArpShaMask({
let res = Some(next);
let Some(val) = res else { break };
val
}),
65u16 => FlowerAttrs::KeyArpTha({
let res = Some(next);
let Some(val) = res else { break };
val
}),
66u16 => FlowerAttrs::KeyArpThaMask({
let res = Some(next);
let Some(val) = res else { break };
val
}),
67u16 => FlowerAttrs::KeyMplsTtl({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
68u16 => FlowerAttrs::KeyMplsBos({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
69u16 => FlowerAttrs::KeyMplsTc({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
70u16 => FlowerAttrs::KeyMplsLabel({
let res = parse_be_u32(next);
let Some(val) = res else { break };
val
}),
71u16 => FlowerAttrs::KeyTcpFlags({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
72u16 => FlowerAttrs::KeyTcpFlagsMask({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
73u16 => FlowerAttrs::KeyIpTos({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
74u16 => FlowerAttrs::KeyIpTosMask({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
75u16 => FlowerAttrs::KeyIpTtl({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
76u16 => FlowerAttrs::KeyIpTtlMask({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
77u16 => FlowerAttrs::KeyCvlanId({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
78u16 => FlowerAttrs::KeyCvlanPrio({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
79u16 => FlowerAttrs::KeyCvlanEthType({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
80u16 => FlowerAttrs::KeyEncIpTos({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
81u16 => FlowerAttrs::KeyEncIpTosMask({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
82u16 => FlowerAttrs::KeyEncIpTtl({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
83u16 => FlowerAttrs::KeyEncIpTtlMask({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
84u16 => FlowerAttrs::KeyEncOpts({
let res = Some(IterableFlowerKeyEncOptsAttrs::with_loc(next, self.orig_loc));
let Some(val) = res else { break };
val
}),
85u16 => FlowerAttrs::KeyEncOptsMask({
let res = Some(IterableFlowerKeyEncOptsAttrs::with_loc(next, self.orig_loc));
let Some(val) = res else { break };
val
}),
86u16 => FlowerAttrs::InHwCount({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
87u16 => FlowerAttrs::KeyPortSrcMin({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
88u16 => FlowerAttrs::KeyPortSrcMax({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
89u16 => FlowerAttrs::KeyPortDstMin({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
90u16 => FlowerAttrs::KeyPortDstMax({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
91u16 => FlowerAttrs::KeyCtState({
let res = parse_u16(next);
let Some(val) = res else { break };
val
}),
92u16 => FlowerAttrs::KeyCtStateMask({
let res = parse_u16(next);
let Some(val) = res else { break };
val
}),
93u16 => FlowerAttrs::KeyCtZone({
let res = parse_u16(next);
let Some(val) = res else { break };
val
}),
94u16 => FlowerAttrs::KeyCtZoneMask({
let res = parse_u16(next);
let Some(val) = res else { break };
val
}),
95u16 => FlowerAttrs::KeyCtMark({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
96u16 => FlowerAttrs::KeyCtMarkMask({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
97u16 => FlowerAttrs::KeyCtLabels({
let res = Some(next);
let Some(val) = res else { break };
val
}),
98u16 => FlowerAttrs::KeyCtLabelsMask({
let res = Some(next);
let Some(val) = res else { break };
val
}),
99u16 => FlowerAttrs::KeyMplsOpts({
let res = Some(IterableFlowerKeyMplsOptAttrs::with_loc(next, self.orig_loc));
let Some(val) = res else { break };
val
}),
100u16 => FlowerAttrs::KeyHash({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
101u16 => FlowerAttrs::KeyHashMask({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
102u16 => FlowerAttrs::KeyNumOfVlans({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
103u16 => FlowerAttrs::KeyPppoeSid({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
104u16 => FlowerAttrs::KeyPppProto({
let res = parse_be_u16(next);
let Some(val) = res else { break };
val
}),
105u16 => FlowerAttrs::KeyL2tpv3Sid({
let res = parse_be_u32(next);
let Some(val) = res else { break };
val
}),
106u16 => FlowerAttrs::L2Miss({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
107u16 => FlowerAttrs::KeyCfm({
let res = Some(IterableFlowerKeyCfmAttrs::with_loc(next, self.orig_loc));
let Some(val) = res else { break };
val
}),
108u16 => FlowerAttrs::KeySpi({
let res = parse_be_u32(next);
let Some(val) = res else { break };
val
}),
109u16 => FlowerAttrs::KeySpiMask({
let res = parse_be_u32(next);
let Some(val) = res else { break };
val
}),
110u16 => FlowerAttrs::KeyEncFlags({
let res = parse_be_u32(next);
let Some(val) = res else { break };
val
}),
111u16 => FlowerAttrs::KeyEncFlagsMask({
let res = parse_be_u32(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"FlowerAttrs",
r#type.and_then(|t| FlowerAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableFlowerAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("FlowerAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
FlowerAttrs::Classid(val) => fmt.field("Classid", &val),
FlowerAttrs::Indev(val) => fmt.field("Indev", &val),
FlowerAttrs::Act(val) => fmt.field("Act", &val),
FlowerAttrs::KeyEthDst(val) => fmt.field("KeyEthDst", &FormatMac(val)),
FlowerAttrs::KeyEthDstMask(val) => fmt.field("KeyEthDstMask", &FormatMac(val)),
FlowerAttrs::KeyEthSrc(val) => fmt.field("KeyEthSrc", &FormatMac(val)),
FlowerAttrs::KeyEthSrcMask(val) => fmt.field("KeyEthSrcMask", &FormatMac(val)),
FlowerAttrs::KeyEthType(val) => fmt.field("KeyEthType", &val),
FlowerAttrs::KeyIpProto(val) => fmt.field("KeyIpProto", &val),
FlowerAttrs::KeyIpv4Src(val) => fmt.field("KeyIpv4Src", &val),
FlowerAttrs::KeyIpv4SrcMask(val) => fmt.field("KeyIpv4SrcMask", &val),
FlowerAttrs::KeyIpv4Dst(val) => fmt.field("KeyIpv4Dst", &val),
FlowerAttrs::KeyIpv4DstMask(val) => fmt.field("KeyIpv4DstMask", &val),
FlowerAttrs::KeyIpv6Src(val) => fmt.field("KeyIpv6Src", &val),
FlowerAttrs::KeyIpv6SrcMask(val) => fmt.field("KeyIpv6SrcMask", &val),
FlowerAttrs::KeyIpv6Dst(val) => fmt.field("KeyIpv6Dst", &val),
FlowerAttrs::KeyIpv6DstMask(val) => fmt.field("KeyIpv6DstMask", &val),
FlowerAttrs::KeyTcpSrc(val) => fmt.field("KeyTcpSrc", &val),
FlowerAttrs::KeyTcpDst(val) => fmt.field("KeyTcpDst", &val),
FlowerAttrs::KeyUdpSrc(val) => fmt.field("KeyUdpSrc", &val),
FlowerAttrs::KeyUdpDst(val) => fmt.field("KeyUdpDst", &val),
FlowerAttrs::Flags(val) => {
fmt.field("Flags", &FormatFlags(val.into(), ClsFlags::from_value))
}
FlowerAttrs::KeyVlanId(val) => fmt.field("KeyVlanId", &val),
FlowerAttrs::KeyVlanPrio(val) => fmt.field("KeyVlanPrio", &val),
FlowerAttrs::KeyVlanEthType(val) => fmt.field("KeyVlanEthType", &val),
FlowerAttrs::KeyEncKeyId(val) => fmt.field("KeyEncKeyId", &val),
FlowerAttrs::KeyEncIpv4Src(val) => fmt.field("KeyEncIpv4Src", &val),
FlowerAttrs::KeyEncIpv4SrcMask(val) => fmt.field("KeyEncIpv4SrcMask", &val),
FlowerAttrs::KeyEncIpv4Dst(val) => fmt.field("KeyEncIpv4Dst", &val),
FlowerAttrs::KeyEncIpv4DstMask(val) => fmt.field("KeyEncIpv4DstMask", &val),
FlowerAttrs::KeyEncIpv6Src(val) => fmt.field("KeyEncIpv6Src", &val),
FlowerAttrs::KeyEncIpv6SrcMask(val) => fmt.field("KeyEncIpv6SrcMask", &val),
FlowerAttrs::KeyEncIpv6Dst(val) => fmt.field("KeyEncIpv6Dst", &val),
FlowerAttrs::KeyEncIpv6DstMask(val) => fmt.field("KeyEncIpv6DstMask", &val),
FlowerAttrs::KeyTcpSrcMask(val) => fmt.field("KeyTcpSrcMask", &val),
FlowerAttrs::KeyTcpDstMask(val) => fmt.field("KeyTcpDstMask", &val),
FlowerAttrs::KeyUdpSrcMask(val) => fmt.field("KeyUdpSrcMask", &val),
FlowerAttrs::KeyUdpDstMask(val) => fmt.field("KeyUdpDstMask", &val),
FlowerAttrs::KeySctpSrcMask(val) => fmt.field("KeySctpSrcMask", &val),
FlowerAttrs::KeySctpDstMask(val) => fmt.field("KeySctpDstMask", &val),
FlowerAttrs::KeySctpSrc(val) => fmt.field("KeySctpSrc", &val),
FlowerAttrs::KeySctpDst(val) => fmt.field("KeySctpDst", &val),
FlowerAttrs::KeyEncUdpSrcPort(val) => fmt.field("KeyEncUdpSrcPort", &val),
FlowerAttrs::KeyEncUdpSrcPortMask(val) => fmt.field("KeyEncUdpSrcPortMask", &val),
FlowerAttrs::KeyEncUdpDstPort(val) => fmt.field("KeyEncUdpDstPort", &val),
FlowerAttrs::KeyEncUdpDstPortMask(val) => fmt.field("KeyEncUdpDstPortMask", &val),
FlowerAttrs::KeyFlags(val) => fmt.field(
"KeyFlags",
&FormatFlags(val.into(), FlowerKeyCtrlFlags::from_value),
),
FlowerAttrs::KeyFlagsMask(val) => fmt.field(
"KeyFlagsMask",
&FormatFlags(val.into(), FlowerKeyCtrlFlags::from_value),
),
FlowerAttrs::KeyIcmpv4Code(val) => fmt.field("KeyIcmpv4Code", &val),
FlowerAttrs::KeyIcmpv4CodeMask(val) => fmt.field("KeyIcmpv4CodeMask", &val),
FlowerAttrs::KeyIcmpv4Type(val) => fmt.field("KeyIcmpv4Type", &val),
FlowerAttrs::KeyIcmpv4TypeMask(val) => fmt.field("KeyIcmpv4TypeMask", &val),
FlowerAttrs::KeyIcmpv6Code(val) => fmt.field("KeyIcmpv6Code", &val),
FlowerAttrs::KeyIcmpv6CodeMask(val) => fmt.field("KeyIcmpv6CodeMask", &val),
FlowerAttrs::KeyIcmpv6Type(val) => fmt.field("KeyIcmpv6Type", &val),
FlowerAttrs::KeyIcmpv6TypeMask(val) => fmt.field("KeyIcmpv6TypeMask", &val),
FlowerAttrs::KeyArpSip(val) => fmt.field("KeyArpSip", &val),
FlowerAttrs::KeyArpSipMask(val) => fmt.field("KeyArpSipMask", &val),
FlowerAttrs::KeyArpTip(val) => fmt.field("KeyArpTip", &val),
FlowerAttrs::KeyArpTipMask(val) => fmt.field("KeyArpTipMask", &val),
FlowerAttrs::KeyArpOp(val) => fmt.field("KeyArpOp", &val),
FlowerAttrs::KeyArpOpMask(val) => fmt.field("KeyArpOpMask", &val),
FlowerAttrs::KeyArpSha(val) => fmt.field("KeyArpSha", &FormatMac(val)),
FlowerAttrs::KeyArpShaMask(val) => fmt.field("KeyArpShaMask", &FormatMac(val)),
FlowerAttrs::KeyArpTha(val) => fmt.field("KeyArpTha", &FormatMac(val)),
FlowerAttrs::KeyArpThaMask(val) => fmt.field("KeyArpThaMask", &FormatMac(val)),
FlowerAttrs::KeyMplsTtl(val) => fmt.field("KeyMplsTtl", &val),
FlowerAttrs::KeyMplsBos(val) => fmt.field("KeyMplsBos", &val),
FlowerAttrs::KeyMplsTc(val) => fmt.field("KeyMplsTc", &val),
FlowerAttrs::KeyMplsLabel(val) => fmt.field("KeyMplsLabel", &val),
FlowerAttrs::KeyTcpFlags(val) => fmt.field("KeyTcpFlags", &val),
FlowerAttrs::KeyTcpFlagsMask(val) => fmt.field("KeyTcpFlagsMask", &val),
FlowerAttrs::KeyIpTos(val) => fmt.field("KeyIpTos", &val),
FlowerAttrs::KeyIpTosMask(val) => fmt.field("KeyIpTosMask", &val),
FlowerAttrs::KeyIpTtl(val) => fmt.field("KeyIpTtl", &val),
FlowerAttrs::KeyIpTtlMask(val) => fmt.field("KeyIpTtlMask", &val),
FlowerAttrs::KeyCvlanId(val) => fmt.field("KeyCvlanId", &val),
FlowerAttrs::KeyCvlanPrio(val) => fmt.field("KeyCvlanPrio", &val),
FlowerAttrs::KeyCvlanEthType(val) => fmt.field("KeyCvlanEthType", &val),
FlowerAttrs::KeyEncIpTos(val) => fmt.field("KeyEncIpTos", &val),
FlowerAttrs::KeyEncIpTosMask(val) => fmt.field("KeyEncIpTosMask", &val),
FlowerAttrs::KeyEncIpTtl(val) => fmt.field("KeyEncIpTtl", &val),
FlowerAttrs::KeyEncIpTtlMask(val) => fmt.field("KeyEncIpTtlMask", &val),
FlowerAttrs::KeyEncOpts(val) => fmt.field("KeyEncOpts", &val),
FlowerAttrs::KeyEncOptsMask(val) => fmt.field("KeyEncOptsMask", &val),
FlowerAttrs::InHwCount(val) => fmt.field("InHwCount", &val),
FlowerAttrs::KeyPortSrcMin(val) => fmt.field("KeyPortSrcMin", &val),
FlowerAttrs::KeyPortSrcMax(val) => fmt.field("KeyPortSrcMax", &val),
FlowerAttrs::KeyPortDstMin(val) => fmt.field("KeyPortDstMin", &val),
FlowerAttrs::KeyPortDstMax(val) => fmt.field("KeyPortDstMax", &val),
FlowerAttrs::KeyCtState(val) => fmt.field("KeyCtState", &val),
FlowerAttrs::KeyCtStateMask(val) => fmt.field("KeyCtStateMask", &val),
FlowerAttrs::KeyCtZone(val) => fmt.field("KeyCtZone", &val),
FlowerAttrs::KeyCtZoneMask(val) => fmt.field("KeyCtZoneMask", &val),
FlowerAttrs::KeyCtMark(val) => fmt.field("KeyCtMark", &val),
FlowerAttrs::KeyCtMarkMask(val) => fmt.field("KeyCtMarkMask", &val),
FlowerAttrs::KeyCtLabels(val) => fmt.field("KeyCtLabels", &val),
FlowerAttrs::KeyCtLabelsMask(val) => fmt.field("KeyCtLabelsMask", &val),
FlowerAttrs::KeyMplsOpts(val) => fmt.field("KeyMplsOpts", &val),
FlowerAttrs::KeyHash(val) => fmt.field("KeyHash", &val),
FlowerAttrs::KeyHashMask(val) => fmt.field("KeyHashMask", &val),
FlowerAttrs::KeyNumOfVlans(val) => fmt.field("KeyNumOfVlans", &val),
FlowerAttrs::KeyPppoeSid(val) => fmt.field("KeyPppoeSid", &val),
FlowerAttrs::KeyPppProto(val) => fmt.field("KeyPppProto", &val),
FlowerAttrs::KeyL2tpv3Sid(val) => fmt.field("KeyL2tpv3Sid", &val),
FlowerAttrs::L2Miss(val) => fmt.field("L2Miss", &val),
FlowerAttrs::KeyCfm(val) => fmt.field("KeyCfm", &val),
FlowerAttrs::KeySpi(val) => fmt.field("KeySpi", &val),
FlowerAttrs::KeySpiMask(val) => fmt.field("KeySpiMask", &val),
FlowerAttrs::KeyEncFlags(val) => fmt.field(
"KeyEncFlags",
&FormatFlags(val.into(), FlowerKeyCtrlFlags::from_value),
),
FlowerAttrs::KeyEncFlagsMask(val) => fmt.field(
"KeyEncFlagsMask",
&FormatFlags(val.into(), FlowerKeyCtrlFlags::from_value),
),
};
}
fmt.finish()
}
}
impl IterableFlowerAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("FlowerAttrs", offset));
return (
stack,
missing_type.and_then(|t| FlowerAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
let mut missing = None;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
FlowerAttrs::Classid(val) => {
if last_off == offset {
stack.push(("Classid", last_off));
break;
}
}
FlowerAttrs::Indev(val) => {
if last_off == offset {
stack.push(("Indev", last_off));
break;
}
}
FlowerAttrs::Act(val) => {
for entry in val {
let Ok(attr) = entry else { break };
(stack, missing) = attr.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
if !stack.is_empty() {
stack.push(("Act", last_off));
break;
}
}
FlowerAttrs::KeyEthDst(val) => {
if last_off == offset {
stack.push(("KeyEthDst", last_off));
break;
}
}
FlowerAttrs::KeyEthDstMask(val) => {
if last_off == offset {
stack.push(("KeyEthDstMask", last_off));
break;
}
}
FlowerAttrs::KeyEthSrc(val) => {
if last_off == offset {
stack.push(("KeyEthSrc", last_off));
break;
}
}
FlowerAttrs::KeyEthSrcMask(val) => {
if last_off == offset {
stack.push(("KeyEthSrcMask", last_off));
break;
}
}
FlowerAttrs::KeyEthType(val) => {
if last_off == offset {
stack.push(("KeyEthType", last_off));
break;
}
}
FlowerAttrs::KeyIpProto(val) => {
if last_off == offset {
stack.push(("KeyIpProto", last_off));
break;
}
}
FlowerAttrs::KeyIpv4Src(val) => {
if last_off == offset {
stack.push(("KeyIpv4Src", last_off));
break;
}
}
FlowerAttrs::KeyIpv4SrcMask(val) => {
if last_off == offset {
stack.push(("KeyIpv4SrcMask", last_off));
break;
}
}
FlowerAttrs::KeyIpv4Dst(val) => {
if last_off == offset {
stack.push(("KeyIpv4Dst", last_off));
break;
}
}
FlowerAttrs::KeyIpv4DstMask(val) => {
if last_off == offset {
stack.push(("KeyIpv4DstMask", last_off));
break;
}
}
FlowerAttrs::KeyIpv6Src(val) => {
if last_off == offset {
stack.push(("KeyIpv6Src", last_off));
break;
}
}
FlowerAttrs::KeyIpv6SrcMask(val) => {
if last_off == offset {
stack.push(("KeyIpv6SrcMask", last_off));
break;
}
}
FlowerAttrs::KeyIpv6Dst(val) => {
if last_off == offset {
stack.push(("KeyIpv6Dst", last_off));
break;
}
}
FlowerAttrs::KeyIpv6DstMask(val) => {
if last_off == offset {
stack.push(("KeyIpv6DstMask", last_off));
break;
}
}
FlowerAttrs::KeyTcpSrc(val) => {
if last_off == offset {
stack.push(("KeyTcpSrc", last_off));
break;
}
}
FlowerAttrs::KeyTcpDst(val) => {
if last_off == offset {
stack.push(("KeyTcpDst", last_off));
break;
}
}
FlowerAttrs::KeyUdpSrc(val) => {
if last_off == offset {
stack.push(("KeyUdpSrc", last_off));
break;
}
}
FlowerAttrs::KeyUdpDst(val) => {
if last_off == offset {
stack.push(("KeyUdpDst", last_off));
break;
}
}
FlowerAttrs::Flags(val) => {
if last_off == offset {
stack.push(("Flags", last_off));
break;
}
}
FlowerAttrs::KeyVlanId(val) => {
if last_off == offset {
stack.push(("KeyVlanId", last_off));
break;
}
}
FlowerAttrs::KeyVlanPrio(val) => {
if last_off == offset {
stack.push(("KeyVlanPrio", last_off));
break;
}
}
FlowerAttrs::KeyVlanEthType(val) => {
if last_off == offset {
stack.push(("KeyVlanEthType", last_off));
break;
}
}
FlowerAttrs::KeyEncKeyId(val) => {
if last_off == offset {
stack.push(("KeyEncKeyId", last_off));
break;
}
}
FlowerAttrs::KeyEncIpv4Src(val) => {
if last_off == offset {
stack.push(("KeyEncIpv4Src", last_off));
break;
}
}
FlowerAttrs::KeyEncIpv4SrcMask(val) => {
if last_off == offset {
stack.push(("KeyEncIpv4SrcMask", last_off));
break;
}
}
FlowerAttrs::KeyEncIpv4Dst(val) => {
if last_off == offset {
stack.push(("KeyEncIpv4Dst", last_off));
break;
}
}
FlowerAttrs::KeyEncIpv4DstMask(val) => {
if last_off == offset {
stack.push(("KeyEncIpv4DstMask", last_off));
break;
}
}
FlowerAttrs::KeyEncIpv6Src(val) => {
if last_off == offset {
stack.push(("KeyEncIpv6Src", last_off));
break;
}
}
FlowerAttrs::KeyEncIpv6SrcMask(val) => {
if last_off == offset {
stack.push(("KeyEncIpv6SrcMask", last_off));
break;
}
}
FlowerAttrs::KeyEncIpv6Dst(val) => {
if last_off == offset {
stack.push(("KeyEncIpv6Dst", last_off));
break;
}
}
FlowerAttrs::KeyEncIpv6DstMask(val) => {
if last_off == offset {
stack.push(("KeyEncIpv6DstMask", last_off));
break;
}
}
FlowerAttrs::KeyTcpSrcMask(val) => {
if last_off == offset {
stack.push(("KeyTcpSrcMask", last_off));
break;
}
}
FlowerAttrs::KeyTcpDstMask(val) => {
if last_off == offset {
stack.push(("KeyTcpDstMask", last_off));
break;
}
}
FlowerAttrs::KeyUdpSrcMask(val) => {
if last_off == offset {
stack.push(("KeyUdpSrcMask", last_off));
break;
}
}
FlowerAttrs::KeyUdpDstMask(val) => {
if last_off == offset {
stack.push(("KeyUdpDstMask", last_off));
break;
}
}
FlowerAttrs::KeySctpSrcMask(val) => {
if last_off == offset {
stack.push(("KeySctpSrcMask", last_off));
break;
}
}
FlowerAttrs::KeySctpDstMask(val) => {
if last_off == offset {
stack.push(("KeySctpDstMask", last_off));
break;
}
}
FlowerAttrs::KeySctpSrc(val) => {
if last_off == offset {
stack.push(("KeySctpSrc", last_off));
break;
}
}
FlowerAttrs::KeySctpDst(val) => {
if last_off == offset {
stack.push(("KeySctpDst", last_off));
break;
}
}
FlowerAttrs::KeyEncUdpSrcPort(val) => {
if last_off == offset {
stack.push(("KeyEncUdpSrcPort", last_off));
break;
}
}
FlowerAttrs::KeyEncUdpSrcPortMask(val) => {
if last_off == offset {
stack.push(("KeyEncUdpSrcPortMask", last_off));
break;
}
}
FlowerAttrs::KeyEncUdpDstPort(val) => {
if last_off == offset {
stack.push(("KeyEncUdpDstPort", last_off));
break;
}
}
FlowerAttrs::KeyEncUdpDstPortMask(val) => {
if last_off == offset {
stack.push(("KeyEncUdpDstPortMask", last_off));
break;
}
}
FlowerAttrs::KeyFlags(val) => {
if last_off == offset {
stack.push(("KeyFlags", last_off));
break;
}
}
FlowerAttrs::KeyFlagsMask(val) => {
if last_off == offset {
stack.push(("KeyFlagsMask", last_off));
break;
}
}
FlowerAttrs::KeyIcmpv4Code(val) => {
if last_off == offset {
stack.push(("KeyIcmpv4Code", last_off));
break;
}
}
FlowerAttrs::KeyIcmpv4CodeMask(val) => {
if last_off == offset {
stack.push(("KeyIcmpv4CodeMask", last_off));
break;
}
}
FlowerAttrs::KeyIcmpv4Type(val) => {
if last_off == offset {
stack.push(("KeyIcmpv4Type", last_off));
break;
}
}
FlowerAttrs::KeyIcmpv4TypeMask(val) => {
if last_off == offset {
stack.push(("KeyIcmpv4TypeMask", last_off));
break;
}
}
FlowerAttrs::KeyIcmpv6Code(val) => {
if last_off == offset {
stack.push(("KeyIcmpv6Code", last_off));
break;
}
}
FlowerAttrs::KeyIcmpv6CodeMask(val) => {
if last_off == offset {
stack.push(("KeyIcmpv6CodeMask", last_off));
break;
}
}
FlowerAttrs::KeyIcmpv6Type(val) => {
if last_off == offset {
stack.push(("KeyIcmpv6Type", last_off));
break;
}
}
FlowerAttrs::KeyIcmpv6TypeMask(val) => {
if last_off == offset {
stack.push(("KeyIcmpv6TypeMask", last_off));
break;
}
}
FlowerAttrs::KeyArpSip(val) => {
if last_off == offset {
stack.push(("KeyArpSip", last_off));
break;
}
}
FlowerAttrs::KeyArpSipMask(val) => {
if last_off == offset {
stack.push(("KeyArpSipMask", last_off));
break;
}
}
FlowerAttrs::KeyArpTip(val) => {
if last_off == offset {
stack.push(("KeyArpTip", last_off));
break;
}
}
FlowerAttrs::KeyArpTipMask(val) => {
if last_off == offset {
stack.push(("KeyArpTipMask", last_off));
break;
}
}
FlowerAttrs::KeyArpOp(val) => {
if last_off == offset {
stack.push(("KeyArpOp", last_off));
break;
}
}
FlowerAttrs::KeyArpOpMask(val) => {
if last_off == offset {
stack.push(("KeyArpOpMask", last_off));
break;
}
}
FlowerAttrs::KeyArpSha(val) => {
if last_off == offset {
stack.push(("KeyArpSha", last_off));
break;
}
}
FlowerAttrs::KeyArpShaMask(val) => {
if last_off == offset {
stack.push(("KeyArpShaMask", last_off));
break;
}
}
FlowerAttrs::KeyArpTha(val) => {
if last_off == offset {
stack.push(("KeyArpTha", last_off));
break;
}
}
FlowerAttrs::KeyArpThaMask(val) => {
if last_off == offset {
stack.push(("KeyArpThaMask", last_off));
break;
}
}
FlowerAttrs::KeyMplsTtl(val) => {
if last_off == offset {
stack.push(("KeyMplsTtl", last_off));
break;
}
}
FlowerAttrs::KeyMplsBos(val) => {
if last_off == offset {
stack.push(("KeyMplsBos", last_off));
break;
}
}
FlowerAttrs::KeyMplsTc(val) => {
if last_off == offset {
stack.push(("KeyMplsTc", last_off));
break;
}
}
FlowerAttrs::KeyMplsLabel(val) => {
if last_off == offset {
stack.push(("KeyMplsLabel", last_off));
break;
}
}
FlowerAttrs::KeyTcpFlags(val) => {
if last_off == offset {
stack.push(("KeyTcpFlags", last_off));
break;
}
}
FlowerAttrs::KeyTcpFlagsMask(val) => {
if last_off == offset {
stack.push(("KeyTcpFlagsMask", last_off));
break;
}
}
FlowerAttrs::KeyIpTos(val) => {
if last_off == offset {
stack.push(("KeyIpTos", last_off));
break;
}
}
FlowerAttrs::KeyIpTosMask(val) => {
if last_off == offset {
stack.push(("KeyIpTosMask", last_off));
break;
}
}
FlowerAttrs::KeyIpTtl(val) => {
if last_off == offset {
stack.push(("KeyIpTtl", last_off));
break;
}
}
FlowerAttrs::KeyIpTtlMask(val) => {
if last_off == offset {
stack.push(("KeyIpTtlMask", last_off));
break;
}
}
FlowerAttrs::KeyCvlanId(val) => {
if last_off == offset {
stack.push(("KeyCvlanId", last_off));
break;
}
}
FlowerAttrs::KeyCvlanPrio(val) => {
if last_off == offset {
stack.push(("KeyCvlanPrio", last_off));
break;
}
}
FlowerAttrs::KeyCvlanEthType(val) => {
if last_off == offset {
stack.push(("KeyCvlanEthType", last_off));
break;
}
}
FlowerAttrs::KeyEncIpTos(val) => {
if last_off == offset {
stack.push(("KeyEncIpTos", last_off));
break;
}
}
FlowerAttrs::KeyEncIpTosMask(val) => {
if last_off == offset {
stack.push(("KeyEncIpTosMask", last_off));
break;
}
}
FlowerAttrs::KeyEncIpTtl(val) => {
if last_off == offset {
stack.push(("KeyEncIpTtl", last_off));
break;
}
}
FlowerAttrs::KeyEncIpTtlMask(val) => {
if last_off == offset {
stack.push(("KeyEncIpTtlMask", last_off));
break;
}
}
FlowerAttrs::KeyEncOpts(val) => {
(stack, missing) = val.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
FlowerAttrs::KeyEncOptsMask(val) => {
(stack, missing) = val.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
FlowerAttrs::InHwCount(val) => {
if last_off == offset {
stack.push(("InHwCount", last_off));
break;
}
}
FlowerAttrs::KeyPortSrcMin(val) => {
if last_off == offset {
stack.push(("KeyPortSrcMin", last_off));
break;
}
}
FlowerAttrs::KeyPortSrcMax(val) => {
if last_off == offset {
stack.push(("KeyPortSrcMax", last_off));
break;
}
}
FlowerAttrs::KeyPortDstMin(val) => {
if last_off == offset {
stack.push(("KeyPortDstMin", last_off));
break;
}
}
FlowerAttrs::KeyPortDstMax(val) => {
if last_off == offset {
stack.push(("KeyPortDstMax", last_off));
break;
}
}
FlowerAttrs::KeyCtState(val) => {
if last_off == offset {
stack.push(("KeyCtState", last_off));
break;
}
}
FlowerAttrs::KeyCtStateMask(val) => {
if last_off == offset {
stack.push(("KeyCtStateMask", last_off));
break;
}
}
FlowerAttrs::KeyCtZone(val) => {
if last_off == offset {
stack.push(("KeyCtZone", last_off));
break;
}
}
FlowerAttrs::KeyCtZoneMask(val) => {
if last_off == offset {
stack.push(("KeyCtZoneMask", last_off));
break;
}
}
FlowerAttrs::KeyCtMark(val) => {
if last_off == offset {
stack.push(("KeyCtMark", last_off));
break;
}
}
FlowerAttrs::KeyCtMarkMask(val) => {
if last_off == offset {
stack.push(("KeyCtMarkMask", last_off));
break;
}
}
FlowerAttrs::KeyCtLabels(val) => {
if last_off == offset {
stack.push(("KeyCtLabels", last_off));
break;
}
}
FlowerAttrs::KeyCtLabelsMask(val) => {
if last_off == offset {
stack.push(("KeyCtLabelsMask", last_off));
break;
}
}
FlowerAttrs::KeyMplsOpts(val) => {
(stack, missing) = val.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
FlowerAttrs::KeyHash(val) => {
if last_off == offset {
stack.push(("KeyHash", last_off));
break;
}
}
FlowerAttrs::KeyHashMask(val) => {
if last_off == offset {
stack.push(("KeyHashMask", last_off));
break;
}
}
FlowerAttrs::KeyNumOfVlans(val) => {
if last_off == offset {
stack.push(("KeyNumOfVlans", last_off));
break;
}
}
FlowerAttrs::KeyPppoeSid(val) => {
if last_off == offset {
stack.push(("KeyPppoeSid", last_off));
break;
}
}
FlowerAttrs::KeyPppProto(val) => {
if last_off == offset {
stack.push(("KeyPppProto", last_off));
break;
}
}
FlowerAttrs::KeyL2tpv3Sid(val) => {
if last_off == offset {
stack.push(("KeyL2tpv3Sid", last_off));
break;
}
}
FlowerAttrs::L2Miss(val) => {
if last_off == offset {
stack.push(("L2Miss", last_off));
break;
}
}
FlowerAttrs::KeyCfm(val) => {
(stack, missing) = val.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
FlowerAttrs::KeySpi(val) => {
if last_off == offset {
stack.push(("KeySpi", last_off));
break;
}
}
FlowerAttrs::KeySpiMask(val) => {
if last_off == offset {
stack.push(("KeySpiMask", last_off));
break;
}
}
FlowerAttrs::KeyEncFlags(val) => {
if last_off == offset {
stack.push(("KeyEncFlags", last_off));
break;
}
}
FlowerAttrs::KeyEncFlagsMask(val) => {
if last_off == offset {
stack.push(("KeyEncFlagsMask", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("FlowerAttrs", cur));
}
(stack, missing)
}
}
#[derive(Clone)]
pub enum FlowerKeyEncOptsAttrs<'a> {
Geneve(IterableFlowerKeyEncOptGeneveAttrs<'a>),
Vxlan(IterableFlowerKeyEncOptVxlanAttrs<'a>),
Erspan(IterableFlowerKeyEncOptErspanAttrs<'a>),
Gtp(IterableFlowerKeyEncOptGtpAttrs<'a>),
}
impl<'a> IterableFlowerKeyEncOptsAttrs<'a> {
pub fn get_geneve(&self) -> Result<IterableFlowerKeyEncOptGeneveAttrs<'a>, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerKeyEncOptsAttrs::Geneve(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerKeyEncOptsAttrs",
"Geneve",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_vxlan(&self) -> Result<IterableFlowerKeyEncOptVxlanAttrs<'a>, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerKeyEncOptsAttrs::Vxlan(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerKeyEncOptsAttrs",
"Vxlan",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_erspan(&self) -> Result<IterableFlowerKeyEncOptErspanAttrs<'a>, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerKeyEncOptsAttrs::Erspan(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerKeyEncOptsAttrs",
"Erspan",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_gtp(&self) -> Result<IterableFlowerKeyEncOptGtpAttrs<'a>, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerKeyEncOptsAttrs::Gtp(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerKeyEncOptsAttrs",
"Gtp",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl FlowerKeyEncOptsAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableFlowerKeyEncOptsAttrs<'a> {
IterableFlowerKeyEncOptsAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Geneve",
2u16 => "Vxlan",
3u16 => "Erspan",
4u16 => "Gtp",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableFlowerKeyEncOptsAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableFlowerKeyEncOptsAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableFlowerKeyEncOptsAttrs<'a> {
type Item = Result<FlowerKeyEncOptsAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => FlowerKeyEncOptsAttrs::Geneve({
let res = Some(IterableFlowerKeyEncOptGeneveAttrs::with_loc(
next,
self.orig_loc,
));
let Some(val) = res else { break };
val
}),
2u16 => FlowerKeyEncOptsAttrs::Vxlan({
let res = Some(IterableFlowerKeyEncOptVxlanAttrs::with_loc(
next,
self.orig_loc,
));
let Some(val) = res else { break };
val
}),
3u16 => FlowerKeyEncOptsAttrs::Erspan({
let res = Some(IterableFlowerKeyEncOptErspanAttrs::with_loc(
next,
self.orig_loc,
));
let Some(val) = res else { break };
val
}),
4u16 => FlowerKeyEncOptsAttrs::Gtp({
let res = Some(IterableFlowerKeyEncOptGtpAttrs::with_loc(
next,
self.orig_loc,
));
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"FlowerKeyEncOptsAttrs",
r#type.and_then(|t| FlowerKeyEncOptsAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableFlowerKeyEncOptsAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("FlowerKeyEncOptsAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
FlowerKeyEncOptsAttrs::Geneve(val) => fmt.field("Geneve", &val),
FlowerKeyEncOptsAttrs::Vxlan(val) => fmt.field("Vxlan", &val),
FlowerKeyEncOptsAttrs::Erspan(val) => fmt.field("Erspan", &val),
FlowerKeyEncOptsAttrs::Gtp(val) => fmt.field("Gtp", &val),
};
}
fmt.finish()
}
}
impl IterableFlowerKeyEncOptsAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("FlowerKeyEncOptsAttrs", offset));
return (
stack,
missing_type.and_then(|t| FlowerKeyEncOptsAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
let mut missing = None;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
FlowerKeyEncOptsAttrs::Geneve(val) => {
(stack, missing) = val.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
FlowerKeyEncOptsAttrs::Vxlan(val) => {
(stack, missing) = val.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
FlowerKeyEncOptsAttrs::Erspan(val) => {
(stack, missing) = val.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
FlowerKeyEncOptsAttrs::Gtp(val) => {
(stack, missing) = val.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("FlowerKeyEncOptsAttrs", cur));
}
(stack, missing)
}
}
#[derive(Clone)]
pub enum FlowerKeyEncOptGeneveAttrs<'a> {
Class(u16),
Type(u8),
Data(&'a [u8]),
}
impl<'a> IterableFlowerKeyEncOptGeneveAttrs<'a> {
pub fn get_class(&self) -> Result<u16, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerKeyEncOptGeneveAttrs::Class(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerKeyEncOptGeneveAttrs",
"Class",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_type(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerKeyEncOptGeneveAttrs::Type(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerKeyEncOptGeneveAttrs",
"Type",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_data(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerKeyEncOptGeneveAttrs::Data(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerKeyEncOptGeneveAttrs",
"Data",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl FlowerKeyEncOptGeneveAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableFlowerKeyEncOptGeneveAttrs<'a> {
IterableFlowerKeyEncOptGeneveAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Class",
2u16 => "Type",
3u16 => "Data",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableFlowerKeyEncOptGeneveAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableFlowerKeyEncOptGeneveAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableFlowerKeyEncOptGeneveAttrs<'a> {
type Item = Result<FlowerKeyEncOptGeneveAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => FlowerKeyEncOptGeneveAttrs::Class({
let res = parse_u16(next);
let Some(val) = res else { break };
val
}),
2u16 => FlowerKeyEncOptGeneveAttrs::Type({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
3u16 => FlowerKeyEncOptGeneveAttrs::Data({
let res = Some(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"FlowerKeyEncOptGeneveAttrs",
r#type.and_then(|t| FlowerKeyEncOptGeneveAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableFlowerKeyEncOptGeneveAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("FlowerKeyEncOptGeneveAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
FlowerKeyEncOptGeneveAttrs::Class(val) => fmt.field("Class", &val),
FlowerKeyEncOptGeneveAttrs::Type(val) => fmt.field("Type", &val),
FlowerKeyEncOptGeneveAttrs::Data(val) => fmt.field("Data", &val),
};
}
fmt.finish()
}
}
impl IterableFlowerKeyEncOptGeneveAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("FlowerKeyEncOptGeneveAttrs", offset));
return (
stack,
missing_type.and_then(|t| FlowerKeyEncOptGeneveAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
FlowerKeyEncOptGeneveAttrs::Class(val) => {
if last_off == offset {
stack.push(("Class", last_off));
break;
}
}
FlowerKeyEncOptGeneveAttrs::Type(val) => {
if last_off == offset {
stack.push(("Type", last_off));
break;
}
}
FlowerKeyEncOptGeneveAttrs::Data(val) => {
if last_off == offset {
stack.push(("Data", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("FlowerKeyEncOptGeneveAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum FlowerKeyEncOptVxlanAttrs {
Gbp(u32),
}
impl<'a> IterableFlowerKeyEncOptVxlanAttrs<'a> {
pub fn get_gbp(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerKeyEncOptVxlanAttrs::Gbp(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerKeyEncOptVxlanAttrs",
"Gbp",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl FlowerKeyEncOptVxlanAttrs {
pub fn new<'a>(buf: &'a [u8]) -> IterableFlowerKeyEncOptVxlanAttrs<'a> {
IterableFlowerKeyEncOptVxlanAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Gbp",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableFlowerKeyEncOptVxlanAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableFlowerKeyEncOptVxlanAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableFlowerKeyEncOptVxlanAttrs<'a> {
type Item = Result<FlowerKeyEncOptVxlanAttrs, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => FlowerKeyEncOptVxlanAttrs::Gbp({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"FlowerKeyEncOptVxlanAttrs",
r#type.and_then(|t| FlowerKeyEncOptVxlanAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl std::fmt::Debug for IterableFlowerKeyEncOptVxlanAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("FlowerKeyEncOptVxlanAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
FlowerKeyEncOptVxlanAttrs::Gbp(val) => fmt.field("Gbp", &val),
};
}
fmt.finish()
}
}
impl IterableFlowerKeyEncOptVxlanAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("FlowerKeyEncOptVxlanAttrs", offset));
return (
stack,
missing_type.and_then(|t| FlowerKeyEncOptVxlanAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
FlowerKeyEncOptVxlanAttrs::Gbp(val) => {
if last_off == offset {
stack.push(("Gbp", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("FlowerKeyEncOptVxlanAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum FlowerKeyEncOptErspanAttrs {
Ver(u8),
Index(u32),
Dir(u8),
Hwid(u8),
}
impl<'a> IterableFlowerKeyEncOptErspanAttrs<'a> {
pub fn get_ver(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerKeyEncOptErspanAttrs::Ver(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerKeyEncOptErspanAttrs",
"Ver",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_index(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerKeyEncOptErspanAttrs::Index(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerKeyEncOptErspanAttrs",
"Index",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_dir(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerKeyEncOptErspanAttrs::Dir(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerKeyEncOptErspanAttrs",
"Dir",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_hwid(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerKeyEncOptErspanAttrs::Hwid(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerKeyEncOptErspanAttrs",
"Hwid",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl FlowerKeyEncOptErspanAttrs {
pub fn new<'a>(buf: &'a [u8]) -> IterableFlowerKeyEncOptErspanAttrs<'a> {
IterableFlowerKeyEncOptErspanAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Ver",
2u16 => "Index",
3u16 => "Dir",
4u16 => "Hwid",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableFlowerKeyEncOptErspanAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableFlowerKeyEncOptErspanAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableFlowerKeyEncOptErspanAttrs<'a> {
type Item = Result<FlowerKeyEncOptErspanAttrs, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => FlowerKeyEncOptErspanAttrs::Ver({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
2u16 => FlowerKeyEncOptErspanAttrs::Index({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
3u16 => FlowerKeyEncOptErspanAttrs::Dir({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
4u16 => FlowerKeyEncOptErspanAttrs::Hwid({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"FlowerKeyEncOptErspanAttrs",
r#type.and_then(|t| FlowerKeyEncOptErspanAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl std::fmt::Debug for IterableFlowerKeyEncOptErspanAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("FlowerKeyEncOptErspanAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
FlowerKeyEncOptErspanAttrs::Ver(val) => fmt.field("Ver", &val),
FlowerKeyEncOptErspanAttrs::Index(val) => fmt.field("Index", &val),
FlowerKeyEncOptErspanAttrs::Dir(val) => fmt.field("Dir", &val),
FlowerKeyEncOptErspanAttrs::Hwid(val) => fmt.field("Hwid", &val),
};
}
fmt.finish()
}
}
impl IterableFlowerKeyEncOptErspanAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("FlowerKeyEncOptErspanAttrs", offset));
return (
stack,
missing_type.and_then(|t| FlowerKeyEncOptErspanAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
FlowerKeyEncOptErspanAttrs::Ver(val) => {
if last_off == offset {
stack.push(("Ver", last_off));
break;
}
}
FlowerKeyEncOptErspanAttrs::Index(val) => {
if last_off == offset {
stack.push(("Index", last_off));
break;
}
}
FlowerKeyEncOptErspanAttrs::Dir(val) => {
if last_off == offset {
stack.push(("Dir", last_off));
break;
}
}
FlowerKeyEncOptErspanAttrs::Hwid(val) => {
if last_off == offset {
stack.push(("Hwid", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("FlowerKeyEncOptErspanAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum FlowerKeyEncOptGtpAttrs {
PduType(u8),
Qfi(u8),
}
impl<'a> IterableFlowerKeyEncOptGtpAttrs<'a> {
pub fn get_pdu_type(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerKeyEncOptGtpAttrs::PduType(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerKeyEncOptGtpAttrs",
"PduType",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_qfi(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerKeyEncOptGtpAttrs::Qfi(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerKeyEncOptGtpAttrs",
"Qfi",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl FlowerKeyEncOptGtpAttrs {
pub fn new<'a>(buf: &'a [u8]) -> IterableFlowerKeyEncOptGtpAttrs<'a> {
IterableFlowerKeyEncOptGtpAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "PduType",
2u16 => "Qfi",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableFlowerKeyEncOptGtpAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableFlowerKeyEncOptGtpAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableFlowerKeyEncOptGtpAttrs<'a> {
type Item = Result<FlowerKeyEncOptGtpAttrs, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => FlowerKeyEncOptGtpAttrs::PduType({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
2u16 => FlowerKeyEncOptGtpAttrs::Qfi({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"FlowerKeyEncOptGtpAttrs",
r#type.and_then(|t| FlowerKeyEncOptGtpAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl std::fmt::Debug for IterableFlowerKeyEncOptGtpAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("FlowerKeyEncOptGtpAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
FlowerKeyEncOptGtpAttrs::PduType(val) => fmt.field("PduType", &val),
FlowerKeyEncOptGtpAttrs::Qfi(val) => fmt.field("Qfi", &val),
};
}
fmt.finish()
}
}
impl IterableFlowerKeyEncOptGtpAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("FlowerKeyEncOptGtpAttrs", offset));
return (
stack,
missing_type.and_then(|t| FlowerKeyEncOptGtpAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
FlowerKeyEncOptGtpAttrs::PduType(val) => {
if last_off == offset {
stack.push(("PduType", last_off));
break;
}
}
FlowerKeyEncOptGtpAttrs::Qfi(val) => {
if last_off == offset {
stack.push(("Qfi", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("FlowerKeyEncOptGtpAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum FlowerKeyMplsOptAttrs {
LseDepth(u8),
LseTtl(u8),
LseBos(u8),
LseTc(u8),
LseLabel(u32),
}
impl<'a> IterableFlowerKeyMplsOptAttrs<'a> {
pub fn get_lse_depth(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerKeyMplsOptAttrs::LseDepth(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerKeyMplsOptAttrs",
"LseDepth",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_lse_ttl(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerKeyMplsOptAttrs::LseTtl(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerKeyMplsOptAttrs",
"LseTtl",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_lse_bos(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerKeyMplsOptAttrs::LseBos(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerKeyMplsOptAttrs",
"LseBos",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_lse_tc(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerKeyMplsOptAttrs::LseTc(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerKeyMplsOptAttrs",
"LseTc",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_lse_label(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerKeyMplsOptAttrs::LseLabel(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerKeyMplsOptAttrs",
"LseLabel",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl FlowerKeyMplsOptAttrs {
pub fn new<'a>(buf: &'a [u8]) -> IterableFlowerKeyMplsOptAttrs<'a> {
IterableFlowerKeyMplsOptAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "LseDepth",
2u16 => "LseTtl",
3u16 => "LseBos",
4u16 => "LseTc",
5u16 => "LseLabel",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableFlowerKeyMplsOptAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableFlowerKeyMplsOptAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableFlowerKeyMplsOptAttrs<'a> {
type Item = Result<FlowerKeyMplsOptAttrs, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => FlowerKeyMplsOptAttrs::LseDepth({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
2u16 => FlowerKeyMplsOptAttrs::LseTtl({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
3u16 => FlowerKeyMplsOptAttrs::LseBos({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
4u16 => FlowerKeyMplsOptAttrs::LseTc({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
5u16 => FlowerKeyMplsOptAttrs::LseLabel({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"FlowerKeyMplsOptAttrs",
r#type.and_then(|t| FlowerKeyMplsOptAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl std::fmt::Debug for IterableFlowerKeyMplsOptAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("FlowerKeyMplsOptAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
FlowerKeyMplsOptAttrs::LseDepth(val) => fmt.field("LseDepth", &val),
FlowerKeyMplsOptAttrs::LseTtl(val) => fmt.field("LseTtl", &val),
FlowerKeyMplsOptAttrs::LseBos(val) => fmt.field("LseBos", &val),
FlowerKeyMplsOptAttrs::LseTc(val) => fmt.field("LseTc", &val),
FlowerKeyMplsOptAttrs::LseLabel(val) => fmt.field("LseLabel", &val),
};
}
fmt.finish()
}
}
impl IterableFlowerKeyMplsOptAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("FlowerKeyMplsOptAttrs", offset));
return (
stack,
missing_type.and_then(|t| FlowerKeyMplsOptAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
FlowerKeyMplsOptAttrs::LseDepth(val) => {
if last_off == offset {
stack.push(("LseDepth", last_off));
break;
}
}
FlowerKeyMplsOptAttrs::LseTtl(val) => {
if last_off == offset {
stack.push(("LseTtl", last_off));
break;
}
}
FlowerKeyMplsOptAttrs::LseBos(val) => {
if last_off == offset {
stack.push(("LseBos", last_off));
break;
}
}
FlowerKeyMplsOptAttrs::LseTc(val) => {
if last_off == offset {
stack.push(("LseTc", last_off));
break;
}
}
FlowerKeyMplsOptAttrs::LseLabel(val) => {
if last_off == offset {
stack.push(("LseLabel", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("FlowerKeyMplsOptAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum FlowerKeyCfmAttrs {
MdLevel(u8),
Opcode(u8),
}
impl<'a> IterableFlowerKeyCfmAttrs<'a> {
pub fn get_md_level(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerKeyCfmAttrs::MdLevel(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerKeyCfmAttrs",
"MdLevel",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_opcode(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FlowerKeyCfmAttrs::Opcode(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FlowerKeyCfmAttrs",
"Opcode",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl FlowerKeyCfmAttrs {
pub fn new<'a>(buf: &'a [u8]) -> IterableFlowerKeyCfmAttrs<'a> {
IterableFlowerKeyCfmAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "MdLevel",
2u16 => "Opcode",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableFlowerKeyCfmAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableFlowerKeyCfmAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableFlowerKeyCfmAttrs<'a> {
type Item = Result<FlowerKeyCfmAttrs, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => FlowerKeyCfmAttrs::MdLevel({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
2u16 => FlowerKeyCfmAttrs::Opcode({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"FlowerKeyCfmAttrs",
r#type.and_then(|t| FlowerKeyCfmAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl std::fmt::Debug for IterableFlowerKeyCfmAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("FlowerKeyCfmAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
FlowerKeyCfmAttrs::MdLevel(val) => fmt.field("MdLevel", &val),
FlowerKeyCfmAttrs::Opcode(val) => fmt.field("Opcode", &val),
};
}
fmt.finish()
}
}
impl IterableFlowerKeyCfmAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("FlowerKeyCfmAttrs", offset));
return (
stack,
missing_type.and_then(|t| FlowerKeyCfmAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
FlowerKeyCfmAttrs::MdLevel(val) => {
if last_off == offset {
stack.push(("MdLevel", last_off));
break;
}
}
FlowerKeyCfmAttrs::Opcode(val) => {
if last_off == offset {
stack.push(("Opcode", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("FlowerKeyCfmAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum FwAttrs<'a> {
Classid(u32),
Police(IterablePoliceAttrs<'a>),
Indev(&'a CStr),
Act(IterableArrayActAttrs<'a>),
Mask(u32),
}
impl<'a> IterableFwAttrs<'a> {
pub fn get_classid(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FwAttrs::Classid(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FwAttrs",
"Classid",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_police(&self) -> Result<IterablePoliceAttrs<'a>, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FwAttrs::Police(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FwAttrs",
"Police",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_indev(&self) -> Result<&'a CStr, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FwAttrs::Indev(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FwAttrs",
"Indev",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_act(
&self,
) -> Result<ArrayIterable<IterableArrayActAttrs<'a>, IterableActAttrs<'a>>, ErrorContext> {
for attr in self.clone() {
if let Ok(FwAttrs::Act(val)) = attr {
return Ok(ArrayIterable::new(val));
}
}
Err(ErrorContext::new_missing(
"FwAttrs",
"Act",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_mask(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FwAttrs::Mask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FwAttrs",
"Mask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl FwAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableFwAttrs<'a> {
IterableFwAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Classid",
2u16 => "Police",
3u16 => "Indev",
4u16 => "Act",
5u16 => "Mask",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableFwAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableFwAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableFwAttrs<'a> {
type Item = Result<FwAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => FwAttrs::Classid({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
2u16 => FwAttrs::Police({
let res = Some(IterablePoliceAttrs::with_loc(next, self.orig_loc));
let Some(val) = res else { break };
val
}),
3u16 => FwAttrs::Indev({
let res = CStr::from_bytes_with_nul(next).ok();
let Some(val) = res else { break };
val
}),
4u16 => FwAttrs::Act({
let res = Some(IterableArrayActAttrs::with_loc(next, self.orig_loc));
let Some(val) = res else { break };
val
}),
5u16 => FwAttrs::Mask({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"FwAttrs",
r#type.and_then(|t| FwAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableFwAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("FwAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
FwAttrs::Classid(val) => fmt.field("Classid", &val),
FwAttrs::Police(val) => fmt.field("Police", &val),
FwAttrs::Indev(val) => fmt.field("Indev", &val),
FwAttrs::Act(val) => fmt.field("Act", &val),
FwAttrs::Mask(val) => fmt.field("Mask", &val),
};
}
fmt.finish()
}
}
impl IterableFwAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("FwAttrs", offset));
return (stack, missing_type.and_then(|t| FwAttrs::attr_from_type(t)));
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
let mut missing = None;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
FwAttrs::Classid(val) => {
if last_off == offset {
stack.push(("Classid", last_off));
break;
}
}
FwAttrs::Police(val) => {
(stack, missing) = val.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
FwAttrs::Indev(val) => {
if last_off == offset {
stack.push(("Indev", last_off));
break;
}
}
FwAttrs::Act(val) => {
for entry in val {
let Ok(attr) = entry else { break };
(stack, missing) = attr.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
if !stack.is_empty() {
stack.push(("Act", last_off));
break;
}
}
FwAttrs::Mask(val) => {
if last_off == offset {
stack.push(("Mask", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("FwAttrs", cur));
}
(stack, missing)
}
}
#[derive(Clone)]
pub enum GredAttrs<'a> {
Parms(&'a [u8]),
Stab(&'a [u8]),
Dps(TcGredSopt),
MaxP(&'a [u8]),
Limit(u32),
VqList(IterableTcaGredVqListAttrs<'a>),
}
impl<'a> IterableGredAttrs<'a> {
pub fn get_parms(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(GredAttrs::Parms(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"GredAttrs",
"Parms",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_stab(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(GredAttrs::Stab(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"GredAttrs",
"Stab",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_dps(&self) -> Result<TcGredSopt, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(GredAttrs::Dps(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"GredAttrs",
"Dps",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_max_p(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(GredAttrs::MaxP(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"GredAttrs",
"MaxP",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_limit(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(GredAttrs::Limit(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"GredAttrs",
"Limit",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_vq_list(&self) -> Result<IterableTcaGredVqListAttrs<'a>, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(GredAttrs::VqList(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"GredAttrs",
"VqList",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl GredAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableGredAttrs<'a> {
IterableGredAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Parms",
2u16 => "Stab",
3u16 => "Dps",
4u16 => "MaxP",
5u16 => "Limit",
6u16 => "VqList",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableGredAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableGredAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableGredAttrs<'a> {
type Item = Result<GredAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => GredAttrs::Parms({
let res = Some(next);
let Some(val) = res else { break };
val
}),
2u16 => GredAttrs::Stab({
let res = Some(next);
let Some(val) = res else { break };
val
}),
3u16 => GredAttrs::Dps({
let res = Some(TcGredSopt::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
4u16 => GredAttrs::MaxP({
let res = Some(next);
let Some(val) = res else { break };
val
}),
5u16 => GredAttrs::Limit({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
6u16 => GredAttrs::VqList({
let res = Some(IterableTcaGredVqListAttrs::with_loc(next, self.orig_loc));
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"GredAttrs",
r#type.and_then(|t| GredAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableGredAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("GredAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
GredAttrs::Parms(val) => fmt.field("Parms", &val),
GredAttrs::Stab(val) => fmt.field("Stab", &val),
GredAttrs::Dps(val) => fmt.field("Dps", &val),
GredAttrs::MaxP(val) => fmt.field("MaxP", &val),
GredAttrs::Limit(val) => fmt.field("Limit", &val),
GredAttrs::VqList(val) => fmt.field("VqList", &val),
};
}
fmt.finish()
}
}
impl IterableGredAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("GredAttrs", offset));
return (
stack,
missing_type.and_then(|t| GredAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
let mut missing = None;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
GredAttrs::Parms(val) => {
if last_off == offset {
stack.push(("Parms", last_off));
break;
}
}
GredAttrs::Stab(val) => {
if last_off == offset {
stack.push(("Stab", last_off));
break;
}
}
GredAttrs::Dps(val) => {
if last_off == offset {
stack.push(("Dps", last_off));
break;
}
}
GredAttrs::MaxP(val) => {
if last_off == offset {
stack.push(("MaxP", last_off));
break;
}
}
GredAttrs::Limit(val) => {
if last_off == offset {
stack.push(("Limit", last_off));
break;
}
}
GredAttrs::VqList(val) => {
(stack, missing) = val.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("GredAttrs", cur));
}
(stack, missing)
}
}
#[derive(Clone)]
pub enum TcaGredVqListAttrs<'a> {
#[doc = "Attribute may repeat multiple times (treat it as array)"]
Entry(IterableTcaGredVqEntryAttrs<'a>),
}
impl<'a> IterableTcaGredVqListAttrs<'a> {
#[doc = "Attribute may repeat multiple times (treat it as array)"]
pub fn get_entry(
&self,
) -> MultiAttrIterable<Self, TcaGredVqListAttrs<'a>, IterableTcaGredVqEntryAttrs<'a>> {
MultiAttrIterable::new(self.clone(), |variant| {
if let TcaGredVqListAttrs::Entry(val) = variant {
Some(val)
} else {
None
}
})
}
}
impl TcaGredVqListAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableTcaGredVqListAttrs<'a> {
IterableTcaGredVqListAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Entry",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableTcaGredVqListAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableTcaGredVqListAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableTcaGredVqListAttrs<'a> {
type Item = Result<TcaGredVqListAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => TcaGredVqListAttrs::Entry({
let res = Some(IterableTcaGredVqEntryAttrs::with_loc(next, self.orig_loc));
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"TcaGredVqListAttrs",
r#type.and_then(|t| TcaGredVqListAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableTcaGredVqListAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("TcaGredVqListAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
TcaGredVqListAttrs::Entry(val) => fmt.field("Entry", &val),
};
}
fmt.finish()
}
}
impl IterableTcaGredVqListAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("TcaGredVqListAttrs", offset));
return (
stack,
missing_type.and_then(|t| TcaGredVqListAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
let mut missing = None;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
TcaGredVqListAttrs::Entry(val) => {
(stack, missing) = val.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("TcaGredVqListAttrs", cur));
}
(stack, missing)
}
}
#[derive(Clone)]
pub enum TcaGredVqEntryAttrs<'a> {
Pad(&'a [u8]),
Dp(u32),
StatBytes(u64),
StatPackets(u32),
StatBacklog(u32),
StatProbDrop(u32),
StatProbMark(u32),
StatForcedDrop(u32),
StatForcedMark(u32),
StatPdrop(u32),
StatOther(u32),
Flags(u32),
}
impl<'a> IterableTcaGredVqEntryAttrs<'a> {
pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TcaGredVqEntryAttrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TcaGredVqEntryAttrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_dp(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TcaGredVqEntryAttrs::Dp(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TcaGredVqEntryAttrs",
"Dp",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_stat_bytes(&self) -> Result<u64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TcaGredVqEntryAttrs::StatBytes(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TcaGredVqEntryAttrs",
"StatBytes",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_stat_packets(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TcaGredVqEntryAttrs::StatPackets(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TcaGredVqEntryAttrs",
"StatPackets",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_stat_backlog(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TcaGredVqEntryAttrs::StatBacklog(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TcaGredVqEntryAttrs",
"StatBacklog",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_stat_prob_drop(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TcaGredVqEntryAttrs::StatProbDrop(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TcaGredVqEntryAttrs",
"StatProbDrop",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_stat_prob_mark(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TcaGredVqEntryAttrs::StatProbMark(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TcaGredVqEntryAttrs",
"StatProbMark",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_stat_forced_drop(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TcaGredVqEntryAttrs::StatForcedDrop(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TcaGredVqEntryAttrs",
"StatForcedDrop",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_stat_forced_mark(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TcaGredVqEntryAttrs::StatForcedMark(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TcaGredVqEntryAttrs",
"StatForcedMark",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_stat_pdrop(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TcaGredVqEntryAttrs::StatPdrop(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TcaGredVqEntryAttrs",
"StatPdrop",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_stat_other(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TcaGredVqEntryAttrs::StatOther(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TcaGredVqEntryAttrs",
"StatOther",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_flags(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TcaGredVqEntryAttrs::Flags(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TcaGredVqEntryAttrs",
"Flags",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl TcaGredVqEntryAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableTcaGredVqEntryAttrs<'a> {
IterableTcaGredVqEntryAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Pad",
2u16 => "Dp",
3u16 => "StatBytes",
4u16 => "StatPackets",
5u16 => "StatBacklog",
6u16 => "StatProbDrop",
7u16 => "StatProbMark",
8u16 => "StatForcedDrop",
9u16 => "StatForcedMark",
10u16 => "StatPdrop",
11u16 => "StatOther",
12u16 => "Flags",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableTcaGredVqEntryAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableTcaGredVqEntryAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableTcaGredVqEntryAttrs<'a> {
type Item = Result<TcaGredVqEntryAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => TcaGredVqEntryAttrs::Pad({
let res = Some(next);
let Some(val) = res else { break };
val
}),
2u16 => TcaGredVqEntryAttrs::Dp({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
3u16 => TcaGredVqEntryAttrs::StatBytes({
let res = parse_u64(next);
let Some(val) = res else { break };
val
}),
4u16 => TcaGredVqEntryAttrs::StatPackets({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
5u16 => TcaGredVqEntryAttrs::StatBacklog({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
6u16 => TcaGredVqEntryAttrs::StatProbDrop({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
7u16 => TcaGredVqEntryAttrs::StatProbMark({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
8u16 => TcaGredVqEntryAttrs::StatForcedDrop({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
9u16 => TcaGredVqEntryAttrs::StatForcedMark({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
10u16 => TcaGredVqEntryAttrs::StatPdrop({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
11u16 => TcaGredVqEntryAttrs::StatOther({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
12u16 => TcaGredVqEntryAttrs::Flags({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"TcaGredVqEntryAttrs",
r#type.and_then(|t| TcaGredVqEntryAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableTcaGredVqEntryAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("TcaGredVqEntryAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
TcaGredVqEntryAttrs::Pad(val) => fmt.field("Pad", &val),
TcaGredVqEntryAttrs::Dp(val) => fmt.field("Dp", &val),
TcaGredVqEntryAttrs::StatBytes(val) => fmt.field("StatBytes", &val),
TcaGredVqEntryAttrs::StatPackets(val) => fmt.field("StatPackets", &val),
TcaGredVqEntryAttrs::StatBacklog(val) => fmt.field("StatBacklog", &val),
TcaGredVqEntryAttrs::StatProbDrop(val) => fmt.field("StatProbDrop", &val),
TcaGredVqEntryAttrs::StatProbMark(val) => fmt.field("StatProbMark", &val),
TcaGredVqEntryAttrs::StatForcedDrop(val) => fmt.field("StatForcedDrop", &val),
TcaGredVqEntryAttrs::StatForcedMark(val) => fmt.field("StatForcedMark", &val),
TcaGredVqEntryAttrs::StatPdrop(val) => fmt.field("StatPdrop", &val),
TcaGredVqEntryAttrs::StatOther(val) => fmt.field("StatOther", &val),
TcaGredVqEntryAttrs::Flags(val) => fmt.field("Flags", &val),
};
}
fmt.finish()
}
}
impl IterableTcaGredVqEntryAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("TcaGredVqEntryAttrs", offset));
return (
stack,
missing_type.and_then(|t| TcaGredVqEntryAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
TcaGredVqEntryAttrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
TcaGredVqEntryAttrs::Dp(val) => {
if last_off == offset {
stack.push(("Dp", last_off));
break;
}
}
TcaGredVqEntryAttrs::StatBytes(val) => {
if last_off == offset {
stack.push(("StatBytes", last_off));
break;
}
}
TcaGredVqEntryAttrs::StatPackets(val) => {
if last_off == offset {
stack.push(("StatPackets", last_off));
break;
}
}
TcaGredVqEntryAttrs::StatBacklog(val) => {
if last_off == offset {
stack.push(("StatBacklog", last_off));
break;
}
}
TcaGredVqEntryAttrs::StatProbDrop(val) => {
if last_off == offset {
stack.push(("StatProbDrop", last_off));
break;
}
}
TcaGredVqEntryAttrs::StatProbMark(val) => {
if last_off == offset {
stack.push(("StatProbMark", last_off));
break;
}
}
TcaGredVqEntryAttrs::StatForcedDrop(val) => {
if last_off == offset {
stack.push(("StatForcedDrop", last_off));
break;
}
}
TcaGredVqEntryAttrs::StatForcedMark(val) => {
if last_off == offset {
stack.push(("StatForcedMark", last_off));
break;
}
}
TcaGredVqEntryAttrs::StatPdrop(val) => {
if last_off == offset {
stack.push(("StatPdrop", last_off));
break;
}
}
TcaGredVqEntryAttrs::StatOther(val) => {
if last_off == offset {
stack.push(("StatOther", last_off));
break;
}
}
TcaGredVqEntryAttrs::Flags(val) => {
if last_off == offset {
stack.push(("Flags", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("TcaGredVqEntryAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum HfscAttrs<'a> {
Rsc(&'a [u8]),
Fsc(&'a [u8]),
Usc(&'a [u8]),
}
impl<'a> IterableHfscAttrs<'a> {
pub fn get_rsc(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(HfscAttrs::Rsc(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"HfscAttrs",
"Rsc",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_fsc(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(HfscAttrs::Fsc(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"HfscAttrs",
"Fsc",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_usc(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(HfscAttrs::Usc(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"HfscAttrs",
"Usc",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl HfscAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableHfscAttrs<'a> {
IterableHfscAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Rsc",
2u16 => "Fsc",
3u16 => "Usc",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableHfscAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableHfscAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableHfscAttrs<'a> {
type Item = Result<HfscAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => HfscAttrs::Rsc({
let res = Some(next);
let Some(val) = res else { break };
val
}),
2u16 => HfscAttrs::Fsc({
let res = Some(next);
let Some(val) = res else { break };
val
}),
3u16 => HfscAttrs::Usc({
let res = Some(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"HfscAttrs",
r#type.and_then(|t| HfscAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableHfscAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("HfscAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
HfscAttrs::Rsc(val) => fmt.field("Rsc", &val),
HfscAttrs::Fsc(val) => fmt.field("Fsc", &val),
HfscAttrs::Usc(val) => fmt.field("Usc", &val),
};
}
fmt.finish()
}
}
impl IterableHfscAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("HfscAttrs", offset));
return (
stack,
missing_type.and_then(|t| HfscAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
HfscAttrs::Rsc(val) => {
if last_off == offset {
stack.push(("Rsc", last_off));
break;
}
}
HfscAttrs::Fsc(val) => {
if last_off == offset {
stack.push(("Fsc", last_off));
break;
}
}
HfscAttrs::Usc(val) => {
if last_off == offset {
stack.push(("Usc", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("HfscAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum HhfAttrs {
BacklogLimit(u32),
Quantum(u32),
HhFlowsLimit(u32),
ResetTimeout(u32),
AdmitBytes(u32),
EvictTimeout(u32),
NonHhWeight(u32),
}
impl<'a> IterableHhfAttrs<'a> {
pub fn get_backlog_limit(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(HhfAttrs::BacklogLimit(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"HhfAttrs",
"BacklogLimit",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_quantum(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(HhfAttrs::Quantum(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"HhfAttrs",
"Quantum",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_hh_flows_limit(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(HhfAttrs::HhFlowsLimit(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"HhfAttrs",
"HhFlowsLimit",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_reset_timeout(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(HhfAttrs::ResetTimeout(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"HhfAttrs",
"ResetTimeout",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_admit_bytes(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(HhfAttrs::AdmitBytes(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"HhfAttrs",
"AdmitBytes",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_evict_timeout(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(HhfAttrs::EvictTimeout(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"HhfAttrs",
"EvictTimeout",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_non_hh_weight(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(HhfAttrs::NonHhWeight(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"HhfAttrs",
"NonHhWeight",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl HhfAttrs {
pub fn new<'a>(buf: &'a [u8]) -> IterableHhfAttrs<'a> {
IterableHhfAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "BacklogLimit",
2u16 => "Quantum",
3u16 => "HhFlowsLimit",
4u16 => "ResetTimeout",
5u16 => "AdmitBytes",
6u16 => "EvictTimeout",
7u16 => "NonHhWeight",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableHhfAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableHhfAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableHhfAttrs<'a> {
type Item = Result<HhfAttrs, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => HhfAttrs::BacklogLimit({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
2u16 => HhfAttrs::Quantum({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
3u16 => HhfAttrs::HhFlowsLimit({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
4u16 => HhfAttrs::ResetTimeout({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
5u16 => HhfAttrs::AdmitBytes({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
6u16 => HhfAttrs::EvictTimeout({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
7u16 => HhfAttrs::NonHhWeight({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"HhfAttrs",
r#type.and_then(|t| HhfAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl std::fmt::Debug for IterableHhfAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("HhfAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
HhfAttrs::BacklogLimit(val) => fmt.field("BacklogLimit", &val),
HhfAttrs::Quantum(val) => fmt.field("Quantum", &val),
HhfAttrs::HhFlowsLimit(val) => fmt.field("HhFlowsLimit", &val),
HhfAttrs::ResetTimeout(val) => fmt.field("ResetTimeout", &val),
HhfAttrs::AdmitBytes(val) => fmt.field("AdmitBytes", &val),
HhfAttrs::EvictTimeout(val) => fmt.field("EvictTimeout", &val),
HhfAttrs::NonHhWeight(val) => fmt.field("NonHhWeight", &val),
};
}
fmt.finish()
}
}
impl IterableHhfAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("HhfAttrs", offset));
return (
stack,
missing_type.and_then(|t| HhfAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
HhfAttrs::BacklogLimit(val) => {
if last_off == offset {
stack.push(("BacklogLimit", last_off));
break;
}
}
HhfAttrs::Quantum(val) => {
if last_off == offset {
stack.push(("Quantum", last_off));
break;
}
}
HhfAttrs::HhFlowsLimit(val) => {
if last_off == offset {
stack.push(("HhFlowsLimit", last_off));
break;
}
}
HhfAttrs::ResetTimeout(val) => {
if last_off == offset {
stack.push(("ResetTimeout", last_off));
break;
}
}
HhfAttrs::AdmitBytes(val) => {
if last_off == offset {
stack.push(("AdmitBytes", last_off));
break;
}
}
HhfAttrs::EvictTimeout(val) => {
if last_off == offset {
stack.push(("EvictTimeout", last_off));
break;
}
}
HhfAttrs::NonHhWeight(val) => {
if last_off == offset {
stack.push(("NonHhWeight", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("HhfAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum HtbAttrs<'a> {
Parms(TcHtbOpt),
Init(TcHtbGlob),
Ctab(&'a [u8]),
Rtab(&'a [u8]),
DirectQlen(u32),
Rate64(u64),
Ceil64(u64),
Pad(&'a [u8]),
Offload(()),
}
impl<'a> IterableHtbAttrs<'a> {
pub fn get_parms(&self) -> Result<TcHtbOpt, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(HtbAttrs::Parms(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"HtbAttrs",
"Parms",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_init(&self) -> Result<TcHtbGlob, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(HtbAttrs::Init(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"HtbAttrs",
"Init",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_ctab(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(HtbAttrs::Ctab(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"HtbAttrs",
"Ctab",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_rtab(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(HtbAttrs::Rtab(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"HtbAttrs",
"Rtab",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_direct_qlen(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(HtbAttrs::DirectQlen(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"HtbAttrs",
"DirectQlen",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_rate64(&self) -> Result<u64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(HtbAttrs::Rate64(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"HtbAttrs",
"Rate64",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_ceil64(&self) -> Result<u64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(HtbAttrs::Ceil64(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"HtbAttrs",
"Ceil64",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(HtbAttrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"HtbAttrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_offload(&self) -> Result<(), ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(HtbAttrs::Offload(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"HtbAttrs",
"Offload",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl HtbAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableHtbAttrs<'a> {
IterableHtbAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Parms",
2u16 => "Init",
3u16 => "Ctab",
4u16 => "Rtab",
5u16 => "DirectQlen",
6u16 => "Rate64",
7u16 => "Ceil64",
8u16 => "Pad",
9u16 => "Offload",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableHtbAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableHtbAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableHtbAttrs<'a> {
type Item = Result<HtbAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => HtbAttrs::Parms({
let res = Some(TcHtbOpt::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
2u16 => HtbAttrs::Init({
let res = Some(TcHtbGlob::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
3u16 => HtbAttrs::Ctab({
let res = Some(next);
let Some(val) = res else { break };
val
}),
4u16 => HtbAttrs::Rtab({
let res = Some(next);
let Some(val) = res else { break };
val
}),
5u16 => HtbAttrs::DirectQlen({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
6u16 => HtbAttrs::Rate64({
let res = parse_u64(next);
let Some(val) = res else { break };
val
}),
7u16 => HtbAttrs::Ceil64({
let res = parse_u64(next);
let Some(val) = res else { break };
val
}),
8u16 => HtbAttrs::Pad({
let res = Some(next);
let Some(val) = res else { break };
val
}),
9u16 => HtbAttrs::Offload(()),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"HtbAttrs",
r#type.and_then(|t| HtbAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableHtbAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("HtbAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
HtbAttrs::Parms(val) => fmt.field("Parms", &val),
HtbAttrs::Init(val) => fmt.field("Init", &val),
HtbAttrs::Ctab(val) => fmt.field("Ctab", &val),
HtbAttrs::Rtab(val) => fmt.field("Rtab", &val),
HtbAttrs::DirectQlen(val) => fmt.field("DirectQlen", &val),
HtbAttrs::Rate64(val) => fmt.field("Rate64", &val),
HtbAttrs::Ceil64(val) => fmt.field("Ceil64", &val),
HtbAttrs::Pad(val) => fmt.field("Pad", &val),
HtbAttrs::Offload(val) => fmt.field("Offload", &val),
};
}
fmt.finish()
}
}
impl IterableHtbAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("HtbAttrs", offset));
return (
stack,
missing_type.and_then(|t| HtbAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
HtbAttrs::Parms(val) => {
if last_off == offset {
stack.push(("Parms", last_off));
break;
}
}
HtbAttrs::Init(val) => {
if last_off == offset {
stack.push(("Init", last_off));
break;
}
}
HtbAttrs::Ctab(val) => {
if last_off == offset {
stack.push(("Ctab", last_off));
break;
}
}
HtbAttrs::Rtab(val) => {
if last_off == offset {
stack.push(("Rtab", last_off));
break;
}
}
HtbAttrs::DirectQlen(val) => {
if last_off == offset {
stack.push(("DirectQlen", last_off));
break;
}
}
HtbAttrs::Rate64(val) => {
if last_off == offset {
stack.push(("Rate64", last_off));
break;
}
}
HtbAttrs::Ceil64(val) => {
if last_off == offset {
stack.push(("Ceil64", last_off));
break;
}
}
HtbAttrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
HtbAttrs::Offload(val) => {
if last_off == offset {
stack.push(("Offload", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("HtbAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum MatchallAttrs<'a> {
Classid(u32),
Act(IterableArrayActAttrs<'a>),
Flags(u32),
Pcnt(TcMatchallPcnt),
Pad(&'a [u8]),
}
impl<'a> IterableMatchallAttrs<'a> {
pub fn get_classid(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(MatchallAttrs::Classid(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"MatchallAttrs",
"Classid",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_act(
&self,
) -> Result<ArrayIterable<IterableArrayActAttrs<'a>, IterableActAttrs<'a>>, ErrorContext> {
for attr in self.clone() {
if let Ok(MatchallAttrs::Act(val)) = attr {
return Ok(ArrayIterable::new(val));
}
}
Err(ErrorContext::new_missing(
"MatchallAttrs",
"Act",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_flags(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(MatchallAttrs::Flags(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"MatchallAttrs",
"Flags",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pcnt(&self) -> Result<TcMatchallPcnt, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(MatchallAttrs::Pcnt(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"MatchallAttrs",
"Pcnt",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(MatchallAttrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"MatchallAttrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl MatchallAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableMatchallAttrs<'a> {
IterableMatchallAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Classid",
2u16 => "Act",
3u16 => "Flags",
4u16 => "Pcnt",
5u16 => "Pad",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableMatchallAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableMatchallAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableMatchallAttrs<'a> {
type Item = Result<MatchallAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => MatchallAttrs::Classid({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
2u16 => MatchallAttrs::Act({
let res = Some(IterableArrayActAttrs::with_loc(next, self.orig_loc));
let Some(val) = res else { break };
val
}),
3u16 => MatchallAttrs::Flags({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
4u16 => MatchallAttrs::Pcnt({
let res = Some(TcMatchallPcnt::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
5u16 => MatchallAttrs::Pad({
let res = Some(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"MatchallAttrs",
r#type.and_then(|t| MatchallAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableMatchallAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("MatchallAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
MatchallAttrs::Classid(val) => fmt.field("Classid", &val),
MatchallAttrs::Act(val) => fmt.field("Act", &val),
MatchallAttrs::Flags(val) => fmt.field("Flags", &val),
MatchallAttrs::Pcnt(val) => fmt.field("Pcnt", &val),
MatchallAttrs::Pad(val) => fmt.field("Pad", &val),
};
}
fmt.finish()
}
}
impl IterableMatchallAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("MatchallAttrs", offset));
return (
stack,
missing_type.and_then(|t| MatchallAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
let mut missing = None;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
MatchallAttrs::Classid(val) => {
if last_off == offset {
stack.push(("Classid", last_off));
break;
}
}
MatchallAttrs::Act(val) => {
for entry in val {
let Ok(attr) = entry else { break };
(stack, missing) = attr.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
if !stack.is_empty() {
stack.push(("Act", last_off));
break;
}
}
MatchallAttrs::Flags(val) => {
if last_off == offset {
stack.push(("Flags", last_off));
break;
}
}
MatchallAttrs::Pcnt(val) => {
if last_off == offset {
stack.push(("Pcnt", last_off));
break;
}
}
MatchallAttrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("MatchallAttrs", cur));
}
(stack, missing)
}
}
#[derive(Clone)]
pub enum EtfAttrs {
Parms(TcEtfQopt),
}
impl<'a> IterableEtfAttrs<'a> {
pub fn get_parms(&self) -> Result<TcEtfQopt, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(EtfAttrs::Parms(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"EtfAttrs",
"Parms",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl EtfAttrs {
pub fn new<'a>(buf: &'a [u8]) -> IterableEtfAttrs<'a> {
IterableEtfAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Parms",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableEtfAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableEtfAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableEtfAttrs<'a> {
type Item = Result<EtfAttrs, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => EtfAttrs::Parms({
let res = Some(TcEtfQopt::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"EtfAttrs",
r#type.and_then(|t| EtfAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl std::fmt::Debug for IterableEtfAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("EtfAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
EtfAttrs::Parms(val) => fmt.field("Parms", &val),
};
}
fmt.finish()
}
}
impl IterableEtfAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("EtfAttrs", offset));
return (
stack,
missing_type.and_then(|t| EtfAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
EtfAttrs::Parms(val) => {
if last_off == offset {
stack.push(("Parms", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("EtfAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum EtsAttrs<'a> {
Nbands(u8),
Nstrict(u8),
Quanta(IterableEtsAttrs<'a>),
#[doc = "Attribute may repeat multiple times (treat it as array)"]
QuantaBand(u32),
Priomap(IterableEtsAttrs<'a>),
#[doc = "Attribute may repeat multiple times (treat it as array)"]
PriomapBand(u8),
}
impl<'a> IterableEtsAttrs<'a> {
pub fn get_nbands(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(EtsAttrs::Nbands(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"EtsAttrs",
"Nbands",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_nstrict(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(EtsAttrs::Nstrict(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"EtsAttrs",
"Nstrict",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_quanta(&self) -> Result<IterableEtsAttrs<'a>, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(EtsAttrs::Quanta(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"EtsAttrs",
"Quanta",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "Attribute may repeat multiple times (treat it as array)"]
pub fn get_quanta_band(&self) -> MultiAttrIterable<Self, EtsAttrs<'a>, u32> {
MultiAttrIterable::new(self.clone(), |variant| {
if let EtsAttrs::QuantaBand(val) = variant {
Some(val)
} else {
None
}
})
}
pub fn get_priomap(&self) -> Result<IterableEtsAttrs<'a>, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(EtsAttrs::Priomap(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"EtsAttrs",
"Priomap",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "Attribute may repeat multiple times (treat it as array)"]
pub fn get_priomap_band(&self) -> MultiAttrIterable<Self, EtsAttrs<'a>, u8> {
MultiAttrIterable::new(self.clone(), |variant| {
if let EtsAttrs::PriomapBand(val) = variant {
Some(val)
} else {
None
}
})
}
}
impl EtsAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableEtsAttrs<'a> {
IterableEtsAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Nbands",
2u16 => "Nstrict",
3u16 => "Quanta",
4u16 => "QuantaBand",
5u16 => "Priomap",
6u16 => "PriomapBand",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableEtsAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableEtsAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableEtsAttrs<'a> {
type Item = Result<EtsAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => EtsAttrs::Nbands({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
2u16 => EtsAttrs::Nstrict({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
3u16 => EtsAttrs::Quanta({
let res = Some(IterableEtsAttrs::with_loc(next, self.orig_loc));
let Some(val) = res else { break };
val
}),
4u16 => EtsAttrs::QuantaBand({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
5u16 => EtsAttrs::Priomap({
let res = Some(IterableEtsAttrs::with_loc(next, self.orig_loc));
let Some(val) = res else { break };
val
}),
6u16 => EtsAttrs::PriomapBand({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"EtsAttrs",
r#type.and_then(|t| EtsAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableEtsAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("EtsAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
EtsAttrs::Nbands(val) => fmt.field("Nbands", &val),
EtsAttrs::Nstrict(val) => fmt.field("Nstrict", &val),
EtsAttrs::Quanta(val) => fmt.field("Quanta", &val),
EtsAttrs::QuantaBand(val) => fmt.field("QuantaBand", &val),
EtsAttrs::Priomap(val) => fmt.field("Priomap", &val),
EtsAttrs::PriomapBand(val) => fmt.field("PriomapBand", &val),
};
}
fmt.finish()
}
}
impl IterableEtsAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("EtsAttrs", offset));
return (
stack,
missing_type.and_then(|t| EtsAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
let mut missing = None;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
EtsAttrs::Nbands(val) => {
if last_off == offset {
stack.push(("Nbands", last_off));
break;
}
}
EtsAttrs::Nstrict(val) => {
if last_off == offset {
stack.push(("Nstrict", last_off));
break;
}
}
EtsAttrs::Quanta(val) => {
(stack, missing) = val.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
EtsAttrs::QuantaBand(val) => {
if last_off == offset {
stack.push(("QuantaBand", last_off));
break;
}
}
EtsAttrs::Priomap(val) => {
(stack, missing) = val.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
EtsAttrs::PriomapBand(val) => {
if last_off == offset {
stack.push(("PriomapBand", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("EtsAttrs", cur));
}
(stack, missing)
}
}
#[derive(Clone)]
pub enum FqAttrs<'a> {
#[doc = "Limit of total number of packets in queue\n"]
Plimit(u32),
#[doc = "Limit of packets per flow\n"]
FlowPlimit(u32),
#[doc = "RR quantum\n"]
Quantum(u32),
#[doc = "RR quantum for new flow\n"]
InitialQuantum(u32),
#[doc = "Enable / disable rate limiting\n"]
RateEnable(u32),
#[doc = "Obsolete, do not use\n"]
FlowDefaultRate(u32),
#[doc = "Per flow max rate\n"]
FlowMaxRate(u32),
#[doc = "log2(number of buckets)\n"]
BucketsLog(u32),
#[doc = "Flow credit refill delay in usec\n"]
FlowRefillDelay(u32),
#[doc = "Mask applied to orphaned skb hashes\n"]
OrphanMask(u32),
#[doc = "Per packet delay under this rate\n"]
LowRateThreshold(u32),
#[doc = "DCTCP-like CE marking threshold\n"]
CeThreshold(u32),
TimerSlack(u32),
#[doc = "Time horizon in usec\n"]
Horizon(u32),
#[doc = "Drop packets beyond horizon, or cap their EDT\n"]
HorizonDrop(u8),
Priomap(TcPrioQopt),
#[doc = "Weights for each band\n"]
Weights(&'a [u8]),
}
impl<'a> IterableFqAttrs<'a> {
#[doc = "Limit of total number of packets in queue\n"]
pub fn get_plimit(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqAttrs::Plimit(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqAttrs",
"Plimit",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "Limit of packets per flow\n"]
pub fn get_flow_plimit(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqAttrs::FlowPlimit(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqAttrs",
"FlowPlimit",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "RR quantum\n"]
pub fn get_quantum(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqAttrs::Quantum(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqAttrs",
"Quantum",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "RR quantum for new flow\n"]
pub fn get_initial_quantum(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqAttrs::InitialQuantum(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqAttrs",
"InitialQuantum",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "Enable / disable rate limiting\n"]
pub fn get_rate_enable(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqAttrs::RateEnable(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqAttrs",
"RateEnable",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "Obsolete, do not use\n"]
pub fn get_flow_default_rate(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqAttrs::FlowDefaultRate(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqAttrs",
"FlowDefaultRate",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "Per flow max rate\n"]
pub fn get_flow_max_rate(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqAttrs::FlowMaxRate(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqAttrs",
"FlowMaxRate",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "log2(number of buckets)\n"]
pub fn get_buckets_log(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqAttrs::BucketsLog(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqAttrs",
"BucketsLog",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "Flow credit refill delay in usec\n"]
pub fn get_flow_refill_delay(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqAttrs::FlowRefillDelay(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqAttrs",
"FlowRefillDelay",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "Mask applied to orphaned skb hashes\n"]
pub fn get_orphan_mask(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqAttrs::OrphanMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqAttrs",
"OrphanMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "Per packet delay under this rate\n"]
pub fn get_low_rate_threshold(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqAttrs::LowRateThreshold(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqAttrs",
"LowRateThreshold",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "DCTCP-like CE marking threshold\n"]
pub fn get_ce_threshold(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqAttrs::CeThreshold(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqAttrs",
"CeThreshold",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_timer_slack(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqAttrs::TimerSlack(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqAttrs",
"TimerSlack",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "Time horizon in usec\n"]
pub fn get_horizon(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqAttrs::Horizon(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqAttrs",
"Horizon",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "Drop packets beyond horizon, or cap their EDT\n"]
pub fn get_horizon_drop(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqAttrs::HorizonDrop(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqAttrs",
"HorizonDrop",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_priomap(&self) -> Result<TcPrioQopt, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqAttrs::Priomap(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqAttrs",
"Priomap",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "Weights for each band\n"]
pub fn get_weights(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqAttrs::Weights(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqAttrs",
"Weights",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl FqAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableFqAttrs<'a> {
IterableFqAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Plimit",
2u16 => "FlowPlimit",
3u16 => "Quantum",
4u16 => "InitialQuantum",
5u16 => "RateEnable",
6u16 => "FlowDefaultRate",
7u16 => "FlowMaxRate",
8u16 => "BucketsLog",
9u16 => "FlowRefillDelay",
10u16 => "OrphanMask",
11u16 => "LowRateThreshold",
12u16 => "CeThreshold",
13u16 => "TimerSlack",
14u16 => "Horizon",
15u16 => "HorizonDrop",
16u16 => "Priomap",
17u16 => "Weights",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableFqAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableFqAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableFqAttrs<'a> {
type Item = Result<FqAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => FqAttrs::Plimit({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
2u16 => FqAttrs::FlowPlimit({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
3u16 => FqAttrs::Quantum({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
4u16 => FqAttrs::InitialQuantum({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
5u16 => FqAttrs::RateEnable({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
6u16 => FqAttrs::FlowDefaultRate({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
7u16 => FqAttrs::FlowMaxRate({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
8u16 => FqAttrs::BucketsLog({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
9u16 => FqAttrs::FlowRefillDelay({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
10u16 => FqAttrs::OrphanMask({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
11u16 => FqAttrs::LowRateThreshold({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
12u16 => FqAttrs::CeThreshold({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
13u16 => FqAttrs::TimerSlack({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
14u16 => FqAttrs::Horizon({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
15u16 => FqAttrs::HorizonDrop({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
16u16 => FqAttrs::Priomap({
let res = Some(TcPrioQopt::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
17u16 => FqAttrs::Weights({
let res = Some(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"FqAttrs",
r#type.and_then(|t| FqAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableFqAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("FqAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
FqAttrs::Plimit(val) => fmt.field("Plimit", &val),
FqAttrs::FlowPlimit(val) => fmt.field("FlowPlimit", &val),
FqAttrs::Quantum(val) => fmt.field("Quantum", &val),
FqAttrs::InitialQuantum(val) => fmt.field("InitialQuantum", &val),
FqAttrs::RateEnable(val) => fmt.field("RateEnable", &val),
FqAttrs::FlowDefaultRate(val) => fmt.field("FlowDefaultRate", &val),
FqAttrs::FlowMaxRate(val) => fmt.field("FlowMaxRate", &val),
FqAttrs::BucketsLog(val) => fmt.field("BucketsLog", &val),
FqAttrs::FlowRefillDelay(val) => fmt.field("FlowRefillDelay", &val),
FqAttrs::OrphanMask(val) => fmt.field("OrphanMask", &val),
FqAttrs::LowRateThreshold(val) => fmt.field("LowRateThreshold", &val),
FqAttrs::CeThreshold(val) => fmt.field("CeThreshold", &val),
FqAttrs::TimerSlack(val) => fmt.field("TimerSlack", &val),
FqAttrs::Horizon(val) => fmt.field("Horizon", &val),
FqAttrs::HorizonDrop(val) => fmt.field("HorizonDrop", &val),
FqAttrs::Priomap(val) => fmt.field("Priomap", &val),
FqAttrs::Weights(val) => fmt.field("Weights", &val),
};
}
fmt.finish()
}
}
impl IterableFqAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("FqAttrs", offset));
return (stack, missing_type.and_then(|t| FqAttrs::attr_from_type(t)));
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
FqAttrs::Plimit(val) => {
if last_off == offset {
stack.push(("Plimit", last_off));
break;
}
}
FqAttrs::FlowPlimit(val) => {
if last_off == offset {
stack.push(("FlowPlimit", last_off));
break;
}
}
FqAttrs::Quantum(val) => {
if last_off == offset {
stack.push(("Quantum", last_off));
break;
}
}
FqAttrs::InitialQuantum(val) => {
if last_off == offset {
stack.push(("InitialQuantum", last_off));
break;
}
}
FqAttrs::RateEnable(val) => {
if last_off == offset {
stack.push(("RateEnable", last_off));
break;
}
}
FqAttrs::FlowDefaultRate(val) => {
if last_off == offset {
stack.push(("FlowDefaultRate", last_off));
break;
}
}
FqAttrs::FlowMaxRate(val) => {
if last_off == offset {
stack.push(("FlowMaxRate", last_off));
break;
}
}
FqAttrs::BucketsLog(val) => {
if last_off == offset {
stack.push(("BucketsLog", last_off));
break;
}
}
FqAttrs::FlowRefillDelay(val) => {
if last_off == offset {
stack.push(("FlowRefillDelay", last_off));
break;
}
}
FqAttrs::OrphanMask(val) => {
if last_off == offset {
stack.push(("OrphanMask", last_off));
break;
}
}
FqAttrs::LowRateThreshold(val) => {
if last_off == offset {
stack.push(("LowRateThreshold", last_off));
break;
}
}
FqAttrs::CeThreshold(val) => {
if last_off == offset {
stack.push(("CeThreshold", last_off));
break;
}
}
FqAttrs::TimerSlack(val) => {
if last_off == offset {
stack.push(("TimerSlack", last_off));
break;
}
}
FqAttrs::Horizon(val) => {
if last_off == offset {
stack.push(("Horizon", last_off));
break;
}
}
FqAttrs::HorizonDrop(val) => {
if last_off == offset {
stack.push(("HorizonDrop", last_off));
break;
}
}
FqAttrs::Priomap(val) => {
if last_off == offset {
stack.push(("Priomap", last_off));
break;
}
}
FqAttrs::Weights(val) => {
if last_off == offset {
stack.push(("Weights", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("FqAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum FqCodelAttrs {
Target(u32),
Limit(u32),
Interval(u32),
Ecn(u32),
Flows(u32),
Quantum(u32),
CeThreshold(u32),
DropBatchSize(u32),
MemoryLimit(u32),
CeThresholdSelector(u8),
CeThresholdMask(u8),
}
impl<'a> IterableFqCodelAttrs<'a> {
pub fn get_target(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqCodelAttrs::Target(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqCodelAttrs",
"Target",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_limit(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqCodelAttrs::Limit(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqCodelAttrs",
"Limit",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_interval(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqCodelAttrs::Interval(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqCodelAttrs",
"Interval",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_ecn(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqCodelAttrs::Ecn(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqCodelAttrs",
"Ecn",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_flows(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqCodelAttrs::Flows(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqCodelAttrs",
"Flows",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_quantum(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqCodelAttrs::Quantum(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqCodelAttrs",
"Quantum",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_ce_threshold(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqCodelAttrs::CeThreshold(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqCodelAttrs",
"CeThreshold",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_drop_batch_size(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqCodelAttrs::DropBatchSize(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqCodelAttrs",
"DropBatchSize",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_memory_limit(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqCodelAttrs::MemoryLimit(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqCodelAttrs",
"MemoryLimit",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_ce_threshold_selector(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqCodelAttrs::CeThresholdSelector(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqCodelAttrs",
"CeThresholdSelector",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_ce_threshold_mask(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqCodelAttrs::CeThresholdMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqCodelAttrs",
"CeThresholdMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl FqCodelAttrs {
pub fn new<'a>(buf: &'a [u8]) -> IterableFqCodelAttrs<'a> {
IterableFqCodelAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Target",
2u16 => "Limit",
3u16 => "Interval",
4u16 => "Ecn",
5u16 => "Flows",
6u16 => "Quantum",
7u16 => "CeThreshold",
8u16 => "DropBatchSize",
9u16 => "MemoryLimit",
10u16 => "CeThresholdSelector",
11u16 => "CeThresholdMask",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableFqCodelAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableFqCodelAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableFqCodelAttrs<'a> {
type Item = Result<FqCodelAttrs, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => FqCodelAttrs::Target({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
2u16 => FqCodelAttrs::Limit({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
3u16 => FqCodelAttrs::Interval({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
4u16 => FqCodelAttrs::Ecn({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
5u16 => FqCodelAttrs::Flows({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
6u16 => FqCodelAttrs::Quantum({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
7u16 => FqCodelAttrs::CeThreshold({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
8u16 => FqCodelAttrs::DropBatchSize({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
9u16 => FqCodelAttrs::MemoryLimit({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
10u16 => FqCodelAttrs::CeThresholdSelector({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
11u16 => FqCodelAttrs::CeThresholdMask({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"FqCodelAttrs",
r#type.and_then(|t| FqCodelAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl std::fmt::Debug for IterableFqCodelAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("FqCodelAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
FqCodelAttrs::Target(val) => fmt.field("Target", &val),
FqCodelAttrs::Limit(val) => fmt.field("Limit", &val),
FqCodelAttrs::Interval(val) => fmt.field("Interval", &val),
FqCodelAttrs::Ecn(val) => fmt.field("Ecn", &val),
FqCodelAttrs::Flows(val) => fmt.field("Flows", &val),
FqCodelAttrs::Quantum(val) => fmt.field("Quantum", &val),
FqCodelAttrs::CeThreshold(val) => fmt.field("CeThreshold", &val),
FqCodelAttrs::DropBatchSize(val) => fmt.field("DropBatchSize", &val),
FqCodelAttrs::MemoryLimit(val) => fmt.field("MemoryLimit", &val),
FqCodelAttrs::CeThresholdSelector(val) => fmt.field("CeThresholdSelector", &val),
FqCodelAttrs::CeThresholdMask(val) => fmt.field("CeThresholdMask", &val),
};
}
fmt.finish()
}
}
impl IterableFqCodelAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("FqCodelAttrs", offset));
return (
stack,
missing_type.and_then(|t| FqCodelAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
FqCodelAttrs::Target(val) => {
if last_off == offset {
stack.push(("Target", last_off));
break;
}
}
FqCodelAttrs::Limit(val) => {
if last_off == offset {
stack.push(("Limit", last_off));
break;
}
}
FqCodelAttrs::Interval(val) => {
if last_off == offset {
stack.push(("Interval", last_off));
break;
}
}
FqCodelAttrs::Ecn(val) => {
if last_off == offset {
stack.push(("Ecn", last_off));
break;
}
}
FqCodelAttrs::Flows(val) => {
if last_off == offset {
stack.push(("Flows", last_off));
break;
}
}
FqCodelAttrs::Quantum(val) => {
if last_off == offset {
stack.push(("Quantum", last_off));
break;
}
}
FqCodelAttrs::CeThreshold(val) => {
if last_off == offset {
stack.push(("CeThreshold", last_off));
break;
}
}
FqCodelAttrs::DropBatchSize(val) => {
if last_off == offset {
stack.push(("DropBatchSize", last_off));
break;
}
}
FqCodelAttrs::MemoryLimit(val) => {
if last_off == offset {
stack.push(("MemoryLimit", last_off));
break;
}
}
FqCodelAttrs::CeThresholdSelector(val) => {
if last_off == offset {
stack.push(("CeThresholdSelector", last_off));
break;
}
}
FqCodelAttrs::CeThresholdMask(val) => {
if last_off == offset {
stack.push(("CeThresholdMask", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("FqCodelAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum FqPieAttrs {
Limit(u32),
Flows(u32),
Target(u32),
Tupdate(u32),
Alpha(u32),
Beta(u32),
Quantum(u32),
MemoryLimit(u32),
EcnProb(u32),
Ecn(u32),
Bytemode(u32),
DqRateEstimator(u32),
}
impl<'a> IterableFqPieAttrs<'a> {
pub fn get_limit(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqPieAttrs::Limit(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqPieAttrs",
"Limit",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_flows(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqPieAttrs::Flows(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqPieAttrs",
"Flows",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_target(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqPieAttrs::Target(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqPieAttrs",
"Target",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_tupdate(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqPieAttrs::Tupdate(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqPieAttrs",
"Tupdate",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_alpha(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqPieAttrs::Alpha(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqPieAttrs",
"Alpha",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_beta(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqPieAttrs::Beta(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqPieAttrs",
"Beta",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_quantum(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqPieAttrs::Quantum(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqPieAttrs",
"Quantum",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_memory_limit(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqPieAttrs::MemoryLimit(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqPieAttrs",
"MemoryLimit",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_ecn_prob(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqPieAttrs::EcnProb(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqPieAttrs",
"EcnProb",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_ecn(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqPieAttrs::Ecn(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqPieAttrs",
"Ecn",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_bytemode(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqPieAttrs::Bytemode(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqPieAttrs",
"Bytemode",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_dq_rate_estimator(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(FqPieAttrs::DqRateEstimator(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"FqPieAttrs",
"DqRateEstimator",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl FqPieAttrs {
pub fn new<'a>(buf: &'a [u8]) -> IterableFqPieAttrs<'a> {
IterableFqPieAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Limit",
2u16 => "Flows",
3u16 => "Target",
4u16 => "Tupdate",
5u16 => "Alpha",
6u16 => "Beta",
7u16 => "Quantum",
8u16 => "MemoryLimit",
9u16 => "EcnProb",
10u16 => "Ecn",
11u16 => "Bytemode",
12u16 => "DqRateEstimator",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableFqPieAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableFqPieAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableFqPieAttrs<'a> {
type Item = Result<FqPieAttrs, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => FqPieAttrs::Limit({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
2u16 => FqPieAttrs::Flows({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
3u16 => FqPieAttrs::Target({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
4u16 => FqPieAttrs::Tupdate({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
5u16 => FqPieAttrs::Alpha({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
6u16 => FqPieAttrs::Beta({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
7u16 => FqPieAttrs::Quantum({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
8u16 => FqPieAttrs::MemoryLimit({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
9u16 => FqPieAttrs::EcnProb({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
10u16 => FqPieAttrs::Ecn({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
11u16 => FqPieAttrs::Bytemode({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
12u16 => FqPieAttrs::DqRateEstimator({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"FqPieAttrs",
r#type.and_then(|t| FqPieAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl std::fmt::Debug for IterableFqPieAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("FqPieAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
FqPieAttrs::Limit(val) => fmt.field("Limit", &val),
FqPieAttrs::Flows(val) => fmt.field("Flows", &val),
FqPieAttrs::Target(val) => fmt.field("Target", &val),
FqPieAttrs::Tupdate(val) => fmt.field("Tupdate", &val),
FqPieAttrs::Alpha(val) => fmt.field("Alpha", &val),
FqPieAttrs::Beta(val) => fmt.field("Beta", &val),
FqPieAttrs::Quantum(val) => fmt.field("Quantum", &val),
FqPieAttrs::MemoryLimit(val) => fmt.field("MemoryLimit", &val),
FqPieAttrs::EcnProb(val) => fmt.field("EcnProb", &val),
FqPieAttrs::Ecn(val) => fmt.field("Ecn", &val),
FqPieAttrs::Bytemode(val) => fmt.field("Bytemode", &val),
FqPieAttrs::DqRateEstimator(val) => fmt.field("DqRateEstimator", &val),
};
}
fmt.finish()
}
}
impl IterableFqPieAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("FqPieAttrs", offset));
return (
stack,
missing_type.and_then(|t| FqPieAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
FqPieAttrs::Limit(val) => {
if last_off == offset {
stack.push(("Limit", last_off));
break;
}
}
FqPieAttrs::Flows(val) => {
if last_off == offset {
stack.push(("Flows", last_off));
break;
}
}
FqPieAttrs::Target(val) => {
if last_off == offset {
stack.push(("Target", last_off));
break;
}
}
FqPieAttrs::Tupdate(val) => {
if last_off == offset {
stack.push(("Tupdate", last_off));
break;
}
}
FqPieAttrs::Alpha(val) => {
if last_off == offset {
stack.push(("Alpha", last_off));
break;
}
}
FqPieAttrs::Beta(val) => {
if last_off == offset {
stack.push(("Beta", last_off));
break;
}
}
FqPieAttrs::Quantum(val) => {
if last_off == offset {
stack.push(("Quantum", last_off));
break;
}
}
FqPieAttrs::MemoryLimit(val) => {
if last_off == offset {
stack.push(("MemoryLimit", last_off));
break;
}
}
FqPieAttrs::EcnProb(val) => {
if last_off == offset {
stack.push(("EcnProb", last_off));
break;
}
}
FqPieAttrs::Ecn(val) => {
if last_off == offset {
stack.push(("Ecn", last_off));
break;
}
}
FqPieAttrs::Bytemode(val) => {
if last_off == offset {
stack.push(("Bytemode", last_off));
break;
}
}
FqPieAttrs::DqRateEstimator(val) => {
if last_off == offset {
stack.push(("DqRateEstimator", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("FqPieAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum NetemAttrs<'a> {
Corr(TcNetemCorr),
DelayDist(&'a [u8]),
Reorder(TcNetemReorder),
Corrupt(TcNetemCorrupt),
Loss(IterableNetemLossAttrs<'a>),
Rate(TcNetemRate),
Ecn(u32),
Rate64(u64),
Pad(u32),
Latency64(i64),
Jitter64(i64),
Slot(TcNetemSlot),
SlotDist(&'a [u8]),
PrngSeed(u64),
}
impl<'a> IterableNetemAttrs<'a> {
pub fn get_corr(&self) -> Result<TcNetemCorr, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(NetemAttrs::Corr(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"NetemAttrs",
"Corr",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_delay_dist(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(NetemAttrs::DelayDist(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"NetemAttrs",
"DelayDist",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_reorder(&self) -> Result<TcNetemReorder, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(NetemAttrs::Reorder(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"NetemAttrs",
"Reorder",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_corrupt(&self) -> Result<TcNetemCorrupt, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(NetemAttrs::Corrupt(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"NetemAttrs",
"Corrupt",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_loss(&self) -> Result<IterableNetemLossAttrs<'a>, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(NetemAttrs::Loss(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"NetemAttrs",
"Loss",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_rate(&self) -> Result<TcNetemRate, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(NetemAttrs::Rate(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"NetemAttrs",
"Rate",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_ecn(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(NetemAttrs::Ecn(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"NetemAttrs",
"Ecn",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_rate64(&self) -> Result<u64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(NetemAttrs::Rate64(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"NetemAttrs",
"Rate64",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pad(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(NetemAttrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"NetemAttrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_latency64(&self) -> Result<i64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(NetemAttrs::Latency64(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"NetemAttrs",
"Latency64",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_jitter64(&self) -> Result<i64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(NetemAttrs::Jitter64(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"NetemAttrs",
"Jitter64",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_slot(&self) -> Result<TcNetemSlot, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(NetemAttrs::Slot(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"NetemAttrs",
"Slot",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_slot_dist(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(NetemAttrs::SlotDist(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"NetemAttrs",
"SlotDist",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_prng_seed(&self) -> Result<u64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(NetemAttrs::PrngSeed(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"NetemAttrs",
"PrngSeed",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl NetemAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableNetemAttrs<'a> {
IterableNetemAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Corr",
2u16 => "DelayDist",
3u16 => "Reorder",
4u16 => "Corrupt",
5u16 => "Loss",
6u16 => "Rate",
7u16 => "Ecn",
8u16 => "Rate64",
9u16 => "Pad",
10u16 => "Latency64",
11u16 => "Jitter64",
12u16 => "Slot",
13u16 => "SlotDist",
14u16 => "PrngSeed",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableNetemAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableNetemAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableNetemAttrs<'a> {
type Item = Result<NetemAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => NetemAttrs::Corr({
let res = Some(TcNetemCorr::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
2u16 => NetemAttrs::DelayDist({
let res = Some(next);
let Some(val) = res else { break };
val
}),
3u16 => NetemAttrs::Reorder({
let res = Some(TcNetemReorder::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
4u16 => NetemAttrs::Corrupt({
let res = Some(TcNetemCorrupt::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
5u16 => NetemAttrs::Loss({
let res = Some(IterableNetemLossAttrs::with_loc(next, self.orig_loc));
let Some(val) = res else { break };
val
}),
6u16 => NetemAttrs::Rate({
let res = Some(TcNetemRate::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
7u16 => NetemAttrs::Ecn({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
8u16 => NetemAttrs::Rate64({
let res = parse_u64(next);
let Some(val) = res else { break };
val
}),
9u16 => NetemAttrs::Pad({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
10u16 => NetemAttrs::Latency64({
let res = parse_i64(next);
let Some(val) = res else { break };
val
}),
11u16 => NetemAttrs::Jitter64({
let res = parse_i64(next);
let Some(val) = res else { break };
val
}),
12u16 => NetemAttrs::Slot({
let res = Some(TcNetemSlot::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
13u16 => NetemAttrs::SlotDist({
let res = Some(next);
let Some(val) = res else { break };
val
}),
14u16 => NetemAttrs::PrngSeed({
let res = parse_u64(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"NetemAttrs",
r#type.and_then(|t| NetemAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableNetemAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("NetemAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
NetemAttrs::Corr(val) => fmt.field("Corr", &val),
NetemAttrs::DelayDist(val) => fmt.field("DelayDist", &val),
NetemAttrs::Reorder(val) => fmt.field("Reorder", &val),
NetemAttrs::Corrupt(val) => fmt.field("Corrupt", &val),
NetemAttrs::Loss(val) => fmt.field("Loss", &val),
NetemAttrs::Rate(val) => fmt.field("Rate", &val),
NetemAttrs::Ecn(val) => fmt.field("Ecn", &val),
NetemAttrs::Rate64(val) => fmt.field("Rate64", &val),
NetemAttrs::Pad(val) => fmt.field("Pad", &val),
NetemAttrs::Latency64(val) => fmt.field("Latency64", &val),
NetemAttrs::Jitter64(val) => fmt.field("Jitter64", &val),
NetemAttrs::Slot(val) => fmt.field("Slot", &val),
NetemAttrs::SlotDist(val) => fmt.field("SlotDist", &val),
NetemAttrs::PrngSeed(val) => fmt.field("PrngSeed", &val),
};
}
fmt.finish()
}
}
impl IterableNetemAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("NetemAttrs", offset));
return (
stack,
missing_type.and_then(|t| NetemAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
let mut missing = None;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
NetemAttrs::Corr(val) => {
if last_off == offset {
stack.push(("Corr", last_off));
break;
}
}
NetemAttrs::DelayDist(val) => {
if last_off == offset {
stack.push(("DelayDist", last_off));
break;
}
}
NetemAttrs::Reorder(val) => {
if last_off == offset {
stack.push(("Reorder", last_off));
break;
}
}
NetemAttrs::Corrupt(val) => {
if last_off == offset {
stack.push(("Corrupt", last_off));
break;
}
}
NetemAttrs::Loss(val) => {
(stack, missing) = val.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
NetemAttrs::Rate(val) => {
if last_off == offset {
stack.push(("Rate", last_off));
break;
}
}
NetemAttrs::Ecn(val) => {
if last_off == offset {
stack.push(("Ecn", last_off));
break;
}
}
NetemAttrs::Rate64(val) => {
if last_off == offset {
stack.push(("Rate64", last_off));
break;
}
}
NetemAttrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
NetemAttrs::Latency64(val) => {
if last_off == offset {
stack.push(("Latency64", last_off));
break;
}
}
NetemAttrs::Jitter64(val) => {
if last_off == offset {
stack.push(("Jitter64", last_off));
break;
}
}
NetemAttrs::Slot(val) => {
if last_off == offset {
stack.push(("Slot", last_off));
break;
}
}
NetemAttrs::SlotDist(val) => {
if last_off == offset {
stack.push(("SlotDist", last_off));
break;
}
}
NetemAttrs::PrngSeed(val) => {
if last_off == offset {
stack.push(("PrngSeed", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("NetemAttrs", cur));
}
(stack, missing)
}
}
#[derive(Clone)]
pub enum NetemLossAttrs {
#[doc = "General Intuitive - 4 state model\n"]
Gi(TcNetemGimodel),
#[doc = "Gilbert Elliot models\n"]
Ge(TcNetemGemodel),
}
impl<'a> IterableNetemLossAttrs<'a> {
#[doc = "General Intuitive - 4 state model\n"]
pub fn get_gi(&self) -> Result<TcNetemGimodel, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(NetemLossAttrs::Gi(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"NetemLossAttrs",
"Gi",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
#[doc = "Gilbert Elliot models\n"]
pub fn get_ge(&self) -> Result<TcNetemGemodel, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(NetemLossAttrs::Ge(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"NetemLossAttrs",
"Ge",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl NetemLossAttrs {
pub fn new<'a>(buf: &'a [u8]) -> IterableNetemLossAttrs<'a> {
IterableNetemLossAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Gi",
2u16 => "Ge",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableNetemLossAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableNetemLossAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableNetemLossAttrs<'a> {
type Item = Result<NetemLossAttrs, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => NetemLossAttrs::Gi({
let res = Some(TcNetemGimodel::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
2u16 => NetemLossAttrs::Ge({
let res = Some(TcNetemGemodel::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"NetemLossAttrs",
r#type.and_then(|t| NetemLossAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl std::fmt::Debug for IterableNetemLossAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("NetemLossAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
NetemLossAttrs::Gi(val) => fmt.field("Gi", &val),
NetemLossAttrs::Ge(val) => fmt.field("Ge", &val),
};
}
fmt.finish()
}
}
impl IterableNetemLossAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("NetemLossAttrs", offset));
return (
stack,
missing_type.and_then(|t| NetemLossAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
NetemLossAttrs::Gi(val) => {
if last_off == offset {
stack.push(("Gi", last_off));
break;
}
}
NetemLossAttrs::Ge(val) => {
if last_off == offset {
stack.push(("Ge", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("NetemLossAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum PieAttrs {
Target(u32),
Limit(u32),
Tupdate(u32),
Alpha(u32),
Beta(u32),
Ecn(u32),
Bytemode(u32),
DqRateEstimator(u32),
}
impl<'a> IterablePieAttrs<'a> {
pub fn get_target(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(PieAttrs::Target(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"PieAttrs",
"Target",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_limit(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(PieAttrs::Limit(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"PieAttrs",
"Limit",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_tupdate(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(PieAttrs::Tupdate(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"PieAttrs",
"Tupdate",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_alpha(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(PieAttrs::Alpha(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"PieAttrs",
"Alpha",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_beta(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(PieAttrs::Beta(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"PieAttrs",
"Beta",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_ecn(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(PieAttrs::Ecn(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"PieAttrs",
"Ecn",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_bytemode(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(PieAttrs::Bytemode(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"PieAttrs",
"Bytemode",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_dq_rate_estimator(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(PieAttrs::DqRateEstimator(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"PieAttrs",
"DqRateEstimator",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl PieAttrs {
pub fn new<'a>(buf: &'a [u8]) -> IterablePieAttrs<'a> {
IterablePieAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Target",
2u16 => "Limit",
3u16 => "Tupdate",
4u16 => "Alpha",
5u16 => "Beta",
6u16 => "Ecn",
7u16 => "Bytemode",
8u16 => "DqRateEstimator",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterablePieAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterablePieAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterablePieAttrs<'a> {
type Item = Result<PieAttrs, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => PieAttrs::Target({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
2u16 => PieAttrs::Limit({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
3u16 => PieAttrs::Tupdate({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
4u16 => PieAttrs::Alpha({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
5u16 => PieAttrs::Beta({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
6u16 => PieAttrs::Ecn({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
7u16 => PieAttrs::Bytemode({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
8u16 => PieAttrs::DqRateEstimator({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"PieAttrs",
r#type.and_then(|t| PieAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl std::fmt::Debug for IterablePieAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("PieAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
PieAttrs::Target(val) => fmt.field("Target", &val),
PieAttrs::Limit(val) => fmt.field("Limit", &val),
PieAttrs::Tupdate(val) => fmt.field("Tupdate", &val),
PieAttrs::Alpha(val) => fmt.field("Alpha", &val),
PieAttrs::Beta(val) => fmt.field("Beta", &val),
PieAttrs::Ecn(val) => fmt.field("Ecn", &val),
PieAttrs::Bytemode(val) => fmt.field("Bytemode", &val),
PieAttrs::DqRateEstimator(val) => fmt.field("DqRateEstimator", &val),
};
}
fmt.finish()
}
}
impl IterablePieAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("PieAttrs", offset));
return (
stack,
missing_type.and_then(|t| PieAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
PieAttrs::Target(val) => {
if last_off == offset {
stack.push(("Target", last_off));
break;
}
}
PieAttrs::Limit(val) => {
if last_off == offset {
stack.push(("Limit", last_off));
break;
}
}
PieAttrs::Tupdate(val) => {
if last_off == offset {
stack.push(("Tupdate", last_off));
break;
}
}
PieAttrs::Alpha(val) => {
if last_off == offset {
stack.push(("Alpha", last_off));
break;
}
}
PieAttrs::Beta(val) => {
if last_off == offset {
stack.push(("Beta", last_off));
break;
}
}
PieAttrs::Ecn(val) => {
if last_off == offset {
stack.push(("Ecn", last_off));
break;
}
}
PieAttrs::Bytemode(val) => {
if last_off == offset {
stack.push(("Bytemode", last_off));
break;
}
}
PieAttrs::DqRateEstimator(val) => {
if last_off == offset {
stack.push(("DqRateEstimator", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("PieAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum PoliceAttrs<'a> {
Tbf(TcPolice),
Rate(&'a [u8]),
Peakrate(&'a [u8]),
Avrate(u32),
Result(u32),
Tm(TcfT),
Pad(&'a [u8]),
Rate64(u64),
Peakrate64(u64),
Pktrate64(u64),
Pktburst64(u64),
}
impl<'a> IterablePoliceAttrs<'a> {
pub fn get_tbf(&self) -> Result<TcPolice, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(PoliceAttrs::Tbf(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"PoliceAttrs",
"Tbf",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_rate(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(PoliceAttrs::Rate(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"PoliceAttrs",
"Rate",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_peakrate(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(PoliceAttrs::Peakrate(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"PoliceAttrs",
"Peakrate",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_avrate(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(PoliceAttrs::Avrate(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"PoliceAttrs",
"Avrate",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_result(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(PoliceAttrs::Result(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"PoliceAttrs",
"Result",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_tm(&self) -> Result<TcfT, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(PoliceAttrs::Tm(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"PoliceAttrs",
"Tm",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(PoliceAttrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"PoliceAttrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_rate64(&self) -> Result<u64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(PoliceAttrs::Rate64(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"PoliceAttrs",
"Rate64",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_peakrate64(&self) -> Result<u64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(PoliceAttrs::Peakrate64(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"PoliceAttrs",
"Peakrate64",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pktrate64(&self) -> Result<u64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(PoliceAttrs::Pktrate64(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"PoliceAttrs",
"Pktrate64",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pktburst64(&self) -> Result<u64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(PoliceAttrs::Pktburst64(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"PoliceAttrs",
"Pktburst64",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl PoliceAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterablePoliceAttrs<'a> {
IterablePoliceAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Tbf",
2u16 => "Rate",
3u16 => "Peakrate",
4u16 => "Avrate",
5u16 => "Result",
6u16 => "Tm",
7u16 => "Pad",
8u16 => "Rate64",
9u16 => "Peakrate64",
10u16 => "Pktrate64",
11u16 => "Pktburst64",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterablePoliceAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterablePoliceAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterablePoliceAttrs<'a> {
type Item = Result<PoliceAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => PoliceAttrs::Tbf({
let res = Some(TcPolice::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
2u16 => PoliceAttrs::Rate({
let res = Some(next);
let Some(val) = res else { break };
val
}),
3u16 => PoliceAttrs::Peakrate({
let res = Some(next);
let Some(val) = res else { break };
val
}),
4u16 => PoliceAttrs::Avrate({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
5u16 => PoliceAttrs::Result({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
6u16 => PoliceAttrs::Tm({
let res = Some(TcfT::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
7u16 => PoliceAttrs::Pad({
let res = Some(next);
let Some(val) = res else { break };
val
}),
8u16 => PoliceAttrs::Rate64({
let res = parse_u64(next);
let Some(val) = res else { break };
val
}),
9u16 => PoliceAttrs::Peakrate64({
let res = parse_u64(next);
let Some(val) = res else { break };
val
}),
10u16 => PoliceAttrs::Pktrate64({
let res = parse_u64(next);
let Some(val) = res else { break };
val
}),
11u16 => PoliceAttrs::Pktburst64({
let res = parse_u64(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"PoliceAttrs",
r#type.and_then(|t| PoliceAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterablePoliceAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("PoliceAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
PoliceAttrs::Tbf(val) => fmt.field("Tbf", &val),
PoliceAttrs::Rate(val) => fmt.field("Rate", &val),
PoliceAttrs::Peakrate(val) => fmt.field("Peakrate", &val),
PoliceAttrs::Avrate(val) => fmt.field("Avrate", &val),
PoliceAttrs::Result(val) => fmt.field("Result", &val),
PoliceAttrs::Tm(val) => fmt.field("Tm", &val),
PoliceAttrs::Pad(val) => fmt.field("Pad", &val),
PoliceAttrs::Rate64(val) => fmt.field("Rate64", &val),
PoliceAttrs::Peakrate64(val) => fmt.field("Peakrate64", &val),
PoliceAttrs::Pktrate64(val) => fmt.field("Pktrate64", &val),
PoliceAttrs::Pktburst64(val) => fmt.field("Pktburst64", &val),
};
}
fmt.finish()
}
}
impl IterablePoliceAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("PoliceAttrs", offset));
return (
stack,
missing_type.and_then(|t| PoliceAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
PoliceAttrs::Tbf(val) => {
if last_off == offset {
stack.push(("Tbf", last_off));
break;
}
}
PoliceAttrs::Rate(val) => {
if last_off == offset {
stack.push(("Rate", last_off));
break;
}
}
PoliceAttrs::Peakrate(val) => {
if last_off == offset {
stack.push(("Peakrate", last_off));
break;
}
}
PoliceAttrs::Avrate(val) => {
if last_off == offset {
stack.push(("Avrate", last_off));
break;
}
}
PoliceAttrs::Result(val) => {
if last_off == offset {
stack.push(("Result", last_off));
break;
}
}
PoliceAttrs::Tm(val) => {
if last_off == offset {
stack.push(("Tm", last_off));
break;
}
}
PoliceAttrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
PoliceAttrs::Rate64(val) => {
if last_off == offset {
stack.push(("Rate64", last_off));
break;
}
}
PoliceAttrs::Peakrate64(val) => {
if last_off == offset {
stack.push(("Peakrate64", last_off));
break;
}
}
PoliceAttrs::Pktrate64(val) => {
if last_off == offset {
stack.push(("Pktrate64", last_off));
break;
}
}
PoliceAttrs::Pktburst64(val) => {
if last_off == offset {
stack.push(("Pktburst64", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("PoliceAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum QfqAttrs {
Weight(u32),
Lmax(u32),
}
impl<'a> IterableQfqAttrs<'a> {
pub fn get_weight(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(QfqAttrs::Weight(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"QfqAttrs",
"Weight",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_lmax(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(QfqAttrs::Lmax(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"QfqAttrs",
"Lmax",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl QfqAttrs {
pub fn new<'a>(buf: &'a [u8]) -> IterableQfqAttrs<'a> {
IterableQfqAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Weight",
2u16 => "Lmax",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableQfqAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableQfqAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableQfqAttrs<'a> {
type Item = Result<QfqAttrs, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => QfqAttrs::Weight({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
2u16 => QfqAttrs::Lmax({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"QfqAttrs",
r#type.and_then(|t| QfqAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl std::fmt::Debug for IterableQfqAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("QfqAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
QfqAttrs::Weight(val) => fmt.field("Weight", &val),
QfqAttrs::Lmax(val) => fmt.field("Lmax", &val),
};
}
fmt.finish()
}
}
impl IterableQfqAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("QfqAttrs", offset));
return (
stack,
missing_type.and_then(|t| QfqAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
QfqAttrs::Weight(val) => {
if last_off == offset {
stack.push(("Weight", last_off));
break;
}
}
QfqAttrs::Lmax(val) => {
if last_off == offset {
stack.push(("Lmax", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("QfqAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum RedAttrs<'a> {
Parms(TcRedQopt),
Stab(&'a [u8]),
MaxP(u32),
Flags(BuiltinBitfield32),
EarlyDropBlock(u32),
MarkBlock(u32),
}
impl<'a> IterableRedAttrs<'a> {
pub fn get_parms(&self) -> Result<TcRedQopt, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(RedAttrs::Parms(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"RedAttrs",
"Parms",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_stab(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(RedAttrs::Stab(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"RedAttrs",
"Stab",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_max_p(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(RedAttrs::MaxP(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"RedAttrs",
"MaxP",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_flags(&self) -> Result<BuiltinBitfield32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(RedAttrs::Flags(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"RedAttrs",
"Flags",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_early_drop_block(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(RedAttrs::EarlyDropBlock(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"RedAttrs",
"EarlyDropBlock",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_mark_block(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(RedAttrs::MarkBlock(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"RedAttrs",
"MarkBlock",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl RedAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableRedAttrs<'a> {
IterableRedAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Parms",
2u16 => "Stab",
3u16 => "MaxP",
4u16 => "Flags",
5u16 => "EarlyDropBlock",
6u16 => "MarkBlock",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableRedAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableRedAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableRedAttrs<'a> {
type Item = Result<RedAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => RedAttrs::Parms({
let res = Some(TcRedQopt::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
2u16 => RedAttrs::Stab({
let res = Some(next);
let Some(val) = res else { break };
val
}),
3u16 => RedAttrs::MaxP({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
4u16 => RedAttrs::Flags({
let res = BuiltinBitfield32::new_from_slice(next);
let Some(val) = res else { break };
val
}),
5u16 => RedAttrs::EarlyDropBlock({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
6u16 => RedAttrs::MarkBlock({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"RedAttrs",
r#type.and_then(|t| RedAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableRedAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("RedAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
RedAttrs::Parms(val) => fmt.field("Parms", &val),
RedAttrs::Stab(val) => fmt.field("Stab", &val),
RedAttrs::MaxP(val) => fmt.field("MaxP", &val),
RedAttrs::Flags(val) => fmt.field("Flags", &val),
RedAttrs::EarlyDropBlock(val) => fmt.field("EarlyDropBlock", &val),
RedAttrs::MarkBlock(val) => fmt.field("MarkBlock", &val),
};
}
fmt.finish()
}
}
impl IterableRedAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("RedAttrs", offset));
return (
stack,
missing_type.and_then(|t| RedAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
RedAttrs::Parms(val) => {
if last_off == offset {
stack.push(("Parms", last_off));
break;
}
}
RedAttrs::Stab(val) => {
if last_off == offset {
stack.push(("Stab", last_off));
break;
}
}
RedAttrs::MaxP(val) => {
if last_off == offset {
stack.push(("MaxP", last_off));
break;
}
}
RedAttrs::Flags(val) => {
if last_off == offset {
stack.push(("Flags", last_off));
break;
}
}
RedAttrs::EarlyDropBlock(val) => {
if last_off == offset {
stack.push(("EarlyDropBlock", last_off));
break;
}
}
RedAttrs::MarkBlock(val) => {
if last_off == offset {
stack.push(("MarkBlock", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("RedAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum RouteAttrs<'a> {
Classid(u32),
To(u32),
From(u32),
Iif(u32),
Police(IterablePoliceAttrs<'a>),
Act(IterableArrayActAttrs<'a>),
}
impl<'a> IterableRouteAttrs<'a> {
pub fn get_classid(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(RouteAttrs::Classid(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"RouteAttrs",
"Classid",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_to(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(RouteAttrs::To(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"RouteAttrs",
"To",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_from(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(RouteAttrs::From(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"RouteAttrs",
"From",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_iif(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(RouteAttrs::Iif(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"RouteAttrs",
"Iif",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_police(&self) -> Result<IterablePoliceAttrs<'a>, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(RouteAttrs::Police(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"RouteAttrs",
"Police",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_act(
&self,
) -> Result<ArrayIterable<IterableArrayActAttrs<'a>, IterableActAttrs<'a>>, ErrorContext> {
for attr in self.clone() {
if let Ok(RouteAttrs::Act(val)) = attr {
return Ok(ArrayIterable::new(val));
}
}
Err(ErrorContext::new_missing(
"RouteAttrs",
"Act",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl RouteAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableRouteAttrs<'a> {
IterableRouteAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Classid",
2u16 => "To",
3u16 => "From",
4u16 => "Iif",
5u16 => "Police",
6u16 => "Act",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableRouteAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableRouteAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableRouteAttrs<'a> {
type Item = Result<RouteAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => RouteAttrs::Classid({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
2u16 => RouteAttrs::To({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
3u16 => RouteAttrs::From({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
4u16 => RouteAttrs::Iif({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
5u16 => RouteAttrs::Police({
let res = Some(IterablePoliceAttrs::with_loc(next, self.orig_loc));
let Some(val) = res else { break };
val
}),
6u16 => RouteAttrs::Act({
let res = Some(IterableArrayActAttrs::with_loc(next, self.orig_loc));
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"RouteAttrs",
r#type.and_then(|t| RouteAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableRouteAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("RouteAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
RouteAttrs::Classid(val) => fmt.field("Classid", &val),
RouteAttrs::To(val) => fmt.field("To", &val),
RouteAttrs::From(val) => fmt.field("From", &val),
RouteAttrs::Iif(val) => fmt.field("Iif", &val),
RouteAttrs::Police(val) => fmt.field("Police", &val),
RouteAttrs::Act(val) => fmt.field("Act", &val),
};
}
fmt.finish()
}
}
impl IterableRouteAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("RouteAttrs", offset));
return (
stack,
missing_type.and_then(|t| RouteAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
let mut missing = None;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
RouteAttrs::Classid(val) => {
if last_off == offset {
stack.push(("Classid", last_off));
break;
}
}
RouteAttrs::To(val) => {
if last_off == offset {
stack.push(("To", last_off));
break;
}
}
RouteAttrs::From(val) => {
if last_off == offset {
stack.push(("From", last_off));
break;
}
}
RouteAttrs::Iif(val) => {
if last_off == offset {
stack.push(("Iif", last_off));
break;
}
}
RouteAttrs::Police(val) => {
(stack, missing) = val.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
RouteAttrs::Act(val) => {
for entry in val {
let Ok(attr) = entry else { break };
(stack, missing) = attr.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
if !stack.is_empty() {
stack.push(("Act", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("RouteAttrs", cur));
}
(stack, missing)
}
}
#[derive(Clone)]
pub enum TaprioAttrs<'a> {
Priomap(TcMqprioQopt),
SchedEntryList(IterableTaprioSchedEntryList<'a>),
SchedBaseTime(i64),
SchedSingleEntry(IterableTaprioSchedEntry<'a>),
SchedClockid(i32),
Pad(&'a [u8]),
AdminSched(&'a [u8]),
SchedCycleTime(i64),
SchedCycleTimeExtension(i64),
Flags(u32),
TxtimeDelay(u32),
TcEntry(IterableTaprioTcEntryAttrs<'a>),
}
impl<'a> IterableTaprioAttrs<'a> {
pub fn get_priomap(&self) -> Result<TcMqprioQopt, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TaprioAttrs::Priomap(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TaprioAttrs",
"Priomap",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_sched_entry_list(&self) -> Result<IterableTaprioSchedEntryList<'a>, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TaprioAttrs::SchedEntryList(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TaprioAttrs",
"SchedEntryList",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_sched_base_time(&self) -> Result<i64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TaprioAttrs::SchedBaseTime(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TaprioAttrs",
"SchedBaseTime",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_sched_single_entry(&self) -> Result<IterableTaprioSchedEntry<'a>, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TaprioAttrs::SchedSingleEntry(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TaprioAttrs",
"SchedSingleEntry",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_sched_clockid(&self) -> Result<i32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TaprioAttrs::SchedClockid(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TaprioAttrs",
"SchedClockid",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TaprioAttrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TaprioAttrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_admin_sched(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TaprioAttrs::AdminSched(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TaprioAttrs",
"AdminSched",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_sched_cycle_time(&self) -> Result<i64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TaprioAttrs::SchedCycleTime(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TaprioAttrs",
"SchedCycleTime",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_sched_cycle_time_extension(&self) -> Result<i64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TaprioAttrs::SchedCycleTimeExtension(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TaprioAttrs",
"SchedCycleTimeExtension",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_flags(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TaprioAttrs::Flags(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TaprioAttrs",
"Flags",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_txtime_delay(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TaprioAttrs::TxtimeDelay(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TaprioAttrs",
"TxtimeDelay",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_tc_entry(&self) -> Result<IterableTaprioTcEntryAttrs<'a>, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TaprioAttrs::TcEntry(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TaprioAttrs",
"TcEntry",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl TaprioAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableTaprioAttrs<'a> {
IterableTaprioAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Priomap",
2u16 => "SchedEntryList",
3u16 => "SchedBaseTime",
4u16 => "SchedSingleEntry",
5u16 => "SchedClockid",
6u16 => "Pad",
7u16 => "AdminSched",
8u16 => "SchedCycleTime",
9u16 => "SchedCycleTimeExtension",
10u16 => "Flags",
11u16 => "TxtimeDelay",
12u16 => "TcEntry",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableTaprioAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableTaprioAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableTaprioAttrs<'a> {
type Item = Result<TaprioAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => TaprioAttrs::Priomap({
let res = Some(TcMqprioQopt::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
2u16 => TaprioAttrs::SchedEntryList({
let res = Some(IterableTaprioSchedEntryList::with_loc(next, self.orig_loc));
let Some(val) = res else { break };
val
}),
3u16 => TaprioAttrs::SchedBaseTime({
let res = parse_i64(next);
let Some(val) = res else { break };
val
}),
4u16 => TaprioAttrs::SchedSingleEntry({
let res = Some(IterableTaprioSchedEntry::with_loc(next, self.orig_loc));
let Some(val) = res else { break };
val
}),
5u16 => TaprioAttrs::SchedClockid({
let res = parse_i32(next);
let Some(val) = res else { break };
val
}),
6u16 => TaprioAttrs::Pad({
let res = Some(next);
let Some(val) = res else { break };
val
}),
7u16 => TaprioAttrs::AdminSched({
let res = Some(next);
let Some(val) = res else { break };
val
}),
8u16 => TaprioAttrs::SchedCycleTime({
let res = parse_i64(next);
let Some(val) = res else { break };
val
}),
9u16 => TaprioAttrs::SchedCycleTimeExtension({
let res = parse_i64(next);
let Some(val) = res else { break };
val
}),
10u16 => TaprioAttrs::Flags({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
11u16 => TaprioAttrs::TxtimeDelay({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
12u16 => TaprioAttrs::TcEntry({
let res = Some(IterableTaprioTcEntryAttrs::with_loc(next, self.orig_loc));
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"TaprioAttrs",
r#type.and_then(|t| TaprioAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableTaprioAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("TaprioAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
TaprioAttrs::Priomap(val) => fmt.field("Priomap", &val),
TaprioAttrs::SchedEntryList(val) => fmt.field("SchedEntryList", &val),
TaprioAttrs::SchedBaseTime(val) => fmt.field("SchedBaseTime", &val),
TaprioAttrs::SchedSingleEntry(val) => fmt.field("SchedSingleEntry", &val),
TaprioAttrs::SchedClockid(val) => fmt.field("SchedClockid", &val),
TaprioAttrs::Pad(val) => fmt.field("Pad", &val),
TaprioAttrs::AdminSched(val) => fmt.field("AdminSched", &val),
TaprioAttrs::SchedCycleTime(val) => fmt.field("SchedCycleTime", &val),
TaprioAttrs::SchedCycleTimeExtension(val) => {
fmt.field("SchedCycleTimeExtension", &val)
}
TaprioAttrs::Flags(val) => fmt.field("Flags", &val),
TaprioAttrs::TxtimeDelay(val) => fmt.field("TxtimeDelay", &val),
TaprioAttrs::TcEntry(val) => fmt.field("TcEntry", &val),
};
}
fmt.finish()
}
}
impl IterableTaprioAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("TaprioAttrs", offset));
return (
stack,
missing_type.and_then(|t| TaprioAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
let mut missing = None;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
TaprioAttrs::Priomap(val) => {
if last_off == offset {
stack.push(("Priomap", last_off));
break;
}
}
TaprioAttrs::SchedEntryList(val) => {
(stack, missing) = val.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
TaprioAttrs::SchedBaseTime(val) => {
if last_off == offset {
stack.push(("SchedBaseTime", last_off));
break;
}
}
TaprioAttrs::SchedSingleEntry(val) => {
(stack, missing) = val.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
TaprioAttrs::SchedClockid(val) => {
if last_off == offset {
stack.push(("SchedClockid", last_off));
break;
}
}
TaprioAttrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
TaprioAttrs::AdminSched(val) => {
if last_off == offset {
stack.push(("AdminSched", last_off));
break;
}
}
TaprioAttrs::SchedCycleTime(val) => {
if last_off == offset {
stack.push(("SchedCycleTime", last_off));
break;
}
}
TaprioAttrs::SchedCycleTimeExtension(val) => {
if last_off == offset {
stack.push(("SchedCycleTimeExtension", last_off));
break;
}
}
TaprioAttrs::Flags(val) => {
if last_off == offset {
stack.push(("Flags", last_off));
break;
}
}
TaprioAttrs::TxtimeDelay(val) => {
if last_off == offset {
stack.push(("TxtimeDelay", last_off));
break;
}
}
TaprioAttrs::TcEntry(val) => {
(stack, missing) = val.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("TaprioAttrs", cur));
}
(stack, missing)
}
}
#[derive(Clone)]
pub enum TaprioSchedEntryList<'a> {
#[doc = "Attribute may repeat multiple times (treat it as array)"]
Entry(IterableTaprioSchedEntry<'a>),
}
impl<'a> IterableTaprioSchedEntryList<'a> {
#[doc = "Attribute may repeat multiple times (treat it as array)"]
pub fn get_entry(
&self,
) -> MultiAttrIterable<Self, TaprioSchedEntryList<'a>, IterableTaprioSchedEntry<'a>> {
MultiAttrIterable::new(self.clone(), |variant| {
if let TaprioSchedEntryList::Entry(val) = variant {
Some(val)
} else {
None
}
})
}
}
impl TaprioSchedEntryList<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableTaprioSchedEntryList<'a> {
IterableTaprioSchedEntryList::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Entry",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableTaprioSchedEntryList<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableTaprioSchedEntryList<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableTaprioSchedEntryList<'a> {
type Item = Result<TaprioSchedEntryList<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => TaprioSchedEntryList::Entry({
let res = Some(IterableTaprioSchedEntry::with_loc(next, self.orig_loc));
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"TaprioSchedEntryList",
r#type.and_then(|t| TaprioSchedEntryList::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableTaprioSchedEntryList<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("TaprioSchedEntryList");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
TaprioSchedEntryList::Entry(val) => fmt.field("Entry", &val),
};
}
fmt.finish()
}
}
impl IterableTaprioSchedEntryList<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("TaprioSchedEntryList", offset));
return (
stack,
missing_type.and_then(|t| TaprioSchedEntryList::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
let mut missing = None;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
TaprioSchedEntryList::Entry(val) => {
(stack, missing) = val.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("TaprioSchedEntryList", cur));
}
(stack, missing)
}
}
#[derive(Clone)]
pub enum TaprioSchedEntry {
Index(u32),
Cmd(u8),
GateMask(u32),
Interval(u32),
}
impl<'a> IterableTaprioSchedEntry<'a> {
pub fn get_index(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TaprioSchedEntry::Index(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TaprioSchedEntry",
"Index",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_cmd(&self) -> Result<u8, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TaprioSchedEntry::Cmd(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TaprioSchedEntry",
"Cmd",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_gate_mask(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TaprioSchedEntry::GateMask(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TaprioSchedEntry",
"GateMask",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_interval(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TaprioSchedEntry::Interval(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TaprioSchedEntry",
"Interval",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl TaprioSchedEntry {
pub fn new<'a>(buf: &'a [u8]) -> IterableTaprioSchedEntry<'a> {
IterableTaprioSchedEntry::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Index",
2u16 => "Cmd",
3u16 => "GateMask",
4u16 => "Interval",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableTaprioSchedEntry<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableTaprioSchedEntry<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableTaprioSchedEntry<'a> {
type Item = Result<TaprioSchedEntry, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => TaprioSchedEntry::Index({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
2u16 => TaprioSchedEntry::Cmd({
let res = parse_u8(next);
let Some(val) = res else { break };
val
}),
3u16 => TaprioSchedEntry::GateMask({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
4u16 => TaprioSchedEntry::Interval({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"TaprioSchedEntry",
r#type.and_then(|t| TaprioSchedEntry::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl std::fmt::Debug for IterableTaprioSchedEntry<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("TaprioSchedEntry");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
TaprioSchedEntry::Index(val) => fmt.field("Index", &val),
TaprioSchedEntry::Cmd(val) => fmt.field("Cmd", &val),
TaprioSchedEntry::GateMask(val) => fmt.field("GateMask", &val),
TaprioSchedEntry::Interval(val) => fmt.field("Interval", &val),
};
}
fmt.finish()
}
}
impl IterableTaprioSchedEntry<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("TaprioSchedEntry", offset));
return (
stack,
missing_type.and_then(|t| TaprioSchedEntry::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
TaprioSchedEntry::Index(val) => {
if last_off == offset {
stack.push(("Index", last_off));
break;
}
}
TaprioSchedEntry::Cmd(val) => {
if last_off == offset {
stack.push(("Cmd", last_off));
break;
}
}
TaprioSchedEntry::GateMask(val) => {
if last_off == offset {
stack.push(("GateMask", last_off));
break;
}
}
TaprioSchedEntry::Interval(val) => {
if last_off == offset {
stack.push(("Interval", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("TaprioSchedEntry", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum TaprioTcEntryAttrs {
Index(u32),
MaxSdu(u32),
Fp(u32),
}
impl<'a> IterableTaprioTcEntryAttrs<'a> {
pub fn get_index(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TaprioTcEntryAttrs::Index(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TaprioTcEntryAttrs",
"Index",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_max_sdu(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TaprioTcEntryAttrs::MaxSdu(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TaprioTcEntryAttrs",
"MaxSdu",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_fp(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TaprioTcEntryAttrs::Fp(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TaprioTcEntryAttrs",
"Fp",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl TaprioTcEntryAttrs {
pub fn new<'a>(buf: &'a [u8]) -> IterableTaprioTcEntryAttrs<'a> {
IterableTaprioTcEntryAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Index",
2u16 => "MaxSdu",
3u16 => "Fp",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableTaprioTcEntryAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableTaprioTcEntryAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableTaprioTcEntryAttrs<'a> {
type Item = Result<TaprioTcEntryAttrs, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => TaprioTcEntryAttrs::Index({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
2u16 => TaprioTcEntryAttrs::MaxSdu({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
3u16 => TaprioTcEntryAttrs::Fp({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"TaprioTcEntryAttrs",
r#type.and_then(|t| TaprioTcEntryAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl std::fmt::Debug for IterableTaprioTcEntryAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("TaprioTcEntryAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
TaprioTcEntryAttrs::Index(val) => fmt.field("Index", &val),
TaprioTcEntryAttrs::MaxSdu(val) => fmt.field("MaxSdu", &val),
TaprioTcEntryAttrs::Fp(val) => fmt.field("Fp", &val),
};
}
fmt.finish()
}
}
impl IterableTaprioTcEntryAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("TaprioTcEntryAttrs", offset));
return (
stack,
missing_type.and_then(|t| TaprioTcEntryAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
TaprioTcEntryAttrs::Index(val) => {
if last_off == offset {
stack.push(("Index", last_off));
break;
}
}
TaprioTcEntryAttrs::MaxSdu(val) => {
if last_off == offset {
stack.push(("MaxSdu", last_off));
break;
}
}
TaprioTcEntryAttrs::Fp(val) => {
if last_off == offset {
stack.push(("Fp", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("TaprioTcEntryAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum TbfAttrs<'a> {
Parms(TcTbfQopt),
Rtab(&'a [u8]),
Ptab(&'a [u8]),
Rate64(u64),
Prate64(u64),
Burst(u32),
Pburst(u32),
Pad(&'a [u8]),
}
impl<'a> IterableTbfAttrs<'a> {
pub fn get_parms(&self) -> Result<TcTbfQopt, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TbfAttrs::Parms(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TbfAttrs",
"Parms",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_rtab(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TbfAttrs::Rtab(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TbfAttrs",
"Rtab",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_ptab(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TbfAttrs::Ptab(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TbfAttrs",
"Ptab",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_rate64(&self) -> Result<u64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TbfAttrs::Rate64(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TbfAttrs",
"Rate64",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_prate64(&self) -> Result<u64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TbfAttrs::Prate64(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TbfAttrs",
"Prate64",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_burst(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TbfAttrs::Burst(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TbfAttrs",
"Burst",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pburst(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TbfAttrs::Pburst(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TbfAttrs",
"Pburst",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TbfAttrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TbfAttrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl TbfAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableTbfAttrs<'a> {
IterableTbfAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Parms",
2u16 => "Rtab",
3u16 => "Ptab",
4u16 => "Rate64",
5u16 => "Prate64",
6u16 => "Burst",
7u16 => "Pburst",
8u16 => "Pad",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableTbfAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableTbfAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableTbfAttrs<'a> {
type Item = Result<TbfAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => TbfAttrs::Parms({
let res = Some(TcTbfQopt::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
2u16 => TbfAttrs::Rtab({
let res = Some(next);
let Some(val) = res else { break };
val
}),
3u16 => TbfAttrs::Ptab({
let res = Some(next);
let Some(val) = res else { break };
val
}),
4u16 => TbfAttrs::Rate64({
let res = parse_u64(next);
let Some(val) = res else { break };
val
}),
5u16 => TbfAttrs::Prate64({
let res = parse_u64(next);
let Some(val) = res else { break };
val
}),
6u16 => TbfAttrs::Burst({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
7u16 => TbfAttrs::Pburst({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
8u16 => TbfAttrs::Pad({
let res = Some(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"TbfAttrs",
r#type.and_then(|t| TbfAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableTbfAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("TbfAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
TbfAttrs::Parms(val) => fmt.field("Parms", &val),
TbfAttrs::Rtab(val) => fmt.field("Rtab", &val),
TbfAttrs::Ptab(val) => fmt.field("Ptab", &val),
TbfAttrs::Rate64(val) => fmt.field("Rate64", &val),
TbfAttrs::Prate64(val) => fmt.field("Prate64", &val),
TbfAttrs::Burst(val) => fmt.field("Burst", &val),
TbfAttrs::Pburst(val) => fmt.field("Pburst", &val),
TbfAttrs::Pad(val) => fmt.field("Pad", &val),
};
}
fmt.finish()
}
}
impl IterableTbfAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("TbfAttrs", offset));
return (
stack,
missing_type.and_then(|t| TbfAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
TbfAttrs::Parms(val) => {
if last_off == offset {
stack.push(("Parms", last_off));
break;
}
}
TbfAttrs::Rtab(val) => {
if last_off == offset {
stack.push(("Rtab", last_off));
break;
}
}
TbfAttrs::Ptab(val) => {
if last_off == offset {
stack.push(("Ptab", last_off));
break;
}
}
TbfAttrs::Rate64(val) => {
if last_off == offset {
stack.push(("Rate64", last_off));
break;
}
}
TbfAttrs::Prate64(val) => {
if last_off == offset {
stack.push(("Prate64", last_off));
break;
}
}
TbfAttrs::Burst(val) => {
if last_off == offset {
stack.push(("Burst", last_off));
break;
}
}
TbfAttrs::Pburst(val) => {
if last_off == offset {
stack.push(("Pburst", last_off));
break;
}
}
TbfAttrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("TbfAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum ActSampleAttrs<'a> {
Tm(TcfT),
Parms(TcGact),
Rate(u32),
TruncSize(u32),
PsampleGroup(u32),
Pad(&'a [u8]),
}
impl<'a> IterableActSampleAttrs<'a> {
pub fn get_tm(&self) -> Result<TcfT, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActSampleAttrs::Tm(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActSampleAttrs",
"Tm",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_parms(&self) -> Result<TcGact, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActSampleAttrs::Parms(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActSampleAttrs",
"Parms",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_rate(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActSampleAttrs::Rate(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActSampleAttrs",
"Rate",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_trunc_size(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActSampleAttrs::TruncSize(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActSampleAttrs",
"TruncSize",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_psample_group(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActSampleAttrs::PsampleGroup(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActSampleAttrs",
"PsampleGroup",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActSampleAttrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActSampleAttrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl ActSampleAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableActSampleAttrs<'a> {
IterableActSampleAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Tm",
2u16 => "Parms",
3u16 => "Rate",
4u16 => "TruncSize",
5u16 => "PsampleGroup",
6u16 => "Pad",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableActSampleAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableActSampleAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableActSampleAttrs<'a> {
type Item = Result<ActSampleAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => ActSampleAttrs::Tm({
let res = Some(TcfT::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
2u16 => ActSampleAttrs::Parms({
let res = Some(TcGact::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
3u16 => ActSampleAttrs::Rate({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
4u16 => ActSampleAttrs::TruncSize({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
5u16 => ActSampleAttrs::PsampleGroup({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
6u16 => ActSampleAttrs::Pad({
let res = Some(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"ActSampleAttrs",
r#type.and_then(|t| ActSampleAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableActSampleAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("ActSampleAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
ActSampleAttrs::Tm(val) => fmt.field("Tm", &val),
ActSampleAttrs::Parms(val) => fmt.field("Parms", &val),
ActSampleAttrs::Rate(val) => fmt.field("Rate", &val),
ActSampleAttrs::TruncSize(val) => fmt.field("TruncSize", &val),
ActSampleAttrs::PsampleGroup(val) => fmt.field("PsampleGroup", &val),
ActSampleAttrs::Pad(val) => fmt.field("Pad", &val),
};
}
fmt.finish()
}
}
impl IterableActSampleAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("ActSampleAttrs", offset));
return (
stack,
missing_type.and_then(|t| ActSampleAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
ActSampleAttrs::Tm(val) => {
if last_off == offset {
stack.push(("Tm", last_off));
break;
}
}
ActSampleAttrs::Parms(val) => {
if last_off == offset {
stack.push(("Parms", last_off));
break;
}
}
ActSampleAttrs::Rate(val) => {
if last_off == offset {
stack.push(("Rate", last_off));
break;
}
}
ActSampleAttrs::TruncSize(val) => {
if last_off == offset {
stack.push(("TruncSize", last_off));
break;
}
}
ActSampleAttrs::PsampleGroup(val) => {
if last_off == offset {
stack.push(("PsampleGroup", last_off));
break;
}
}
ActSampleAttrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("ActSampleAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum ActGactAttrs<'a> {
Tm(TcfT),
Parms(TcGact),
Prob(TcGactP),
Pad(&'a [u8]),
}
impl<'a> IterableActGactAttrs<'a> {
pub fn get_tm(&self) -> Result<TcfT, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActGactAttrs::Tm(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActGactAttrs",
"Tm",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_parms(&self) -> Result<TcGact, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActGactAttrs::Parms(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActGactAttrs",
"Parms",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_prob(&self) -> Result<TcGactP, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActGactAttrs::Prob(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActGactAttrs",
"Prob",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(ActGactAttrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"ActGactAttrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl ActGactAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableActGactAttrs<'a> {
IterableActGactAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Tm",
2u16 => "Parms",
3u16 => "Prob",
4u16 => "Pad",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableActGactAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableActGactAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableActGactAttrs<'a> {
type Item = Result<ActGactAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => ActGactAttrs::Tm({
let res = Some(TcfT::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
2u16 => ActGactAttrs::Parms({
let res = Some(TcGact::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
3u16 => ActGactAttrs::Prob({
let res = Some(TcGactP::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
4u16 => ActGactAttrs::Pad({
let res = Some(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"ActGactAttrs",
r#type.and_then(|t| ActGactAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableActGactAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("ActGactAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
ActGactAttrs::Tm(val) => fmt.field("Tm", &val),
ActGactAttrs::Parms(val) => fmt.field("Parms", &val),
ActGactAttrs::Prob(val) => fmt.field("Prob", &val),
ActGactAttrs::Pad(val) => fmt.field("Pad", &val),
};
}
fmt.finish()
}
}
impl IterableActGactAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("ActGactAttrs", offset));
return (
stack,
missing_type.and_then(|t| ActGactAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
ActGactAttrs::Tm(val) => {
if last_off == offset {
stack.push(("Tm", last_off));
break;
}
}
ActGactAttrs::Parms(val) => {
if last_off == offset {
stack.push(("Parms", last_off));
break;
}
}
ActGactAttrs::Prob(val) => {
if last_off == offset {
stack.push(("Prob", last_off));
break;
}
}
ActGactAttrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("ActGactAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum TcaStabAttrs<'a> {
Base(TcSizespec),
Data(&'a [u8]),
}
impl<'a> IterableTcaStabAttrs<'a> {
pub fn get_base(&self) -> Result<TcSizespec, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TcaStabAttrs::Base(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TcaStabAttrs",
"Base",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_data(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TcaStabAttrs::Data(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TcaStabAttrs",
"Data",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl TcaStabAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableTcaStabAttrs<'a> {
IterableTcaStabAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Base",
2u16 => "Data",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableTcaStabAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableTcaStabAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableTcaStabAttrs<'a> {
type Item = Result<TcaStabAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => TcaStabAttrs::Base({
let res = Some(TcSizespec::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
2u16 => TcaStabAttrs::Data({
let res = Some(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"TcaStabAttrs",
r#type.and_then(|t| TcaStabAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableTcaStabAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("TcaStabAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
TcaStabAttrs::Base(val) => fmt.field("Base", &val),
TcaStabAttrs::Data(val) => fmt.field("Data", &val),
};
}
fmt.finish()
}
}
impl IterableTcaStabAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("TcaStabAttrs", offset));
return (
stack,
missing_type.and_then(|t| TcaStabAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
TcaStabAttrs::Base(val) => {
if last_off == offset {
stack.push(("Base", last_off));
break;
}
}
TcaStabAttrs::Data(val) => {
if last_off == offset {
stack.push(("Data", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("TcaStabAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum TcaStatsAttrs<'a> {
Basic(GnetStatsBasic),
RateEst(GnetStatsRateEst),
Queue(GnetStatsQueue),
App(TcaStatsAppMsg<'a>),
RateEst64(GnetStatsRateEst64),
Pad(&'a [u8]),
BasicHw(GnetStatsBasic),
Pkt64(u64),
}
impl<'a> IterableTcaStatsAttrs<'a> {
pub fn get_basic(&self) -> Result<GnetStatsBasic, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TcaStatsAttrs::Basic(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TcaStatsAttrs",
"Basic",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_rate_est(&self) -> Result<GnetStatsRateEst, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TcaStatsAttrs::RateEst(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TcaStatsAttrs",
"RateEst",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_queue(&self) -> Result<GnetStatsQueue, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TcaStatsAttrs::Queue(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TcaStatsAttrs",
"Queue",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_app(&self) -> Result<TcaStatsAppMsg<'a>, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TcaStatsAttrs::App(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TcaStatsAttrs",
"App",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_rate_est64(&self) -> Result<GnetStatsRateEst64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TcaStatsAttrs::RateEst64(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TcaStatsAttrs",
"RateEst64",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TcaStatsAttrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TcaStatsAttrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_basic_hw(&self) -> Result<GnetStatsBasic, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TcaStatsAttrs::BasicHw(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TcaStatsAttrs",
"BasicHw",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pkt64(&self) -> Result<u64, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(TcaStatsAttrs::Pkt64(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"TcaStatsAttrs",
"Pkt64",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl TcaStatsAttrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableTcaStatsAttrs<'a> {
IterableTcaStatsAttrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Basic",
2u16 => "RateEst",
3u16 => "Queue",
4u16 => "App",
5u16 => "RateEst64",
6u16 => "Pad",
7u16 => "BasicHw",
8u16 => "Pkt64",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableTcaStatsAttrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableTcaStatsAttrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableTcaStatsAttrs<'a> {
type Item = Result<TcaStatsAttrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => TcaStatsAttrs::Basic({
let res = Some(GnetStatsBasic::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
2u16 => TcaStatsAttrs::RateEst({
let res = Some(GnetStatsRateEst::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
3u16 => TcaStatsAttrs::Queue({
let res = Some(GnetStatsQueue::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
5u16 => TcaStatsAttrs::RateEst64({
let res = Some(GnetStatsRateEst64::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
6u16 => TcaStatsAttrs::Pad({
let res = Some(next);
let Some(val) = res else { break };
val
}),
7u16 => TcaStatsAttrs::BasicHw({
let res = Some(GnetStatsBasic::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
8u16 => TcaStatsAttrs::Pkt64({
let res = parse_u64(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"TcaStatsAttrs",
r#type.and_then(|t| TcaStatsAttrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableTcaStatsAttrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("TcaStatsAttrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
TcaStatsAttrs::Basic(val) => fmt.field("Basic", &val),
TcaStatsAttrs::RateEst(val) => fmt.field("RateEst", &val),
TcaStatsAttrs::Queue(val) => fmt.field("Queue", &val),
TcaStatsAttrs::App(val) => fmt.field("App", &val),
TcaStatsAttrs::RateEst64(val) => fmt.field("RateEst64", &val),
TcaStatsAttrs::Pad(val) => fmt.field("Pad", &val),
TcaStatsAttrs::BasicHw(val) => fmt.field("BasicHw", &val),
TcaStatsAttrs::Pkt64(val) => fmt.field("Pkt64", &val),
};
}
fmt.finish()
}
}
impl IterableTcaStatsAttrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("TcaStatsAttrs", offset));
return (
stack,
missing_type.and_then(|t| TcaStatsAttrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
TcaStatsAttrs::Basic(val) => {
if last_off == offset {
stack.push(("Basic", last_off));
break;
}
}
TcaStatsAttrs::RateEst(val) => {
if last_off == offset {
stack.push(("RateEst", last_off));
break;
}
}
TcaStatsAttrs::Queue(val) => {
if last_off == offset {
stack.push(("Queue", last_off));
break;
}
}
TcaStatsAttrs::App(val) => {
if last_off == offset {
stack.push(("App", last_off));
break;
}
}
TcaStatsAttrs::RateEst64(val) => {
if last_off == offset {
stack.push(("RateEst64", last_off));
break;
}
}
TcaStatsAttrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
TcaStatsAttrs::BasicHw(val) => {
if last_off == offset {
stack.push(("BasicHw", last_off));
break;
}
}
TcaStatsAttrs::Pkt64(val) => {
if last_off == offset {
stack.push(("Pkt64", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("TcaStatsAttrs", cur));
}
(stack, None)
}
}
#[derive(Clone)]
pub enum U32Attrs<'a> {
Classid(u32),
Hash(u32),
Link(u32),
Divisor(u32),
Sel(TcU32Sel),
Police(IterablePoliceAttrs<'a>),
Act(IterableArrayActAttrs<'a>),
Indev(&'a CStr),
Pcnt(TcU32Pcnt),
Mark(TcU32Mark),
Flags(u32),
Pad(&'a [u8]),
}
impl<'a> IterableU32Attrs<'a> {
pub fn get_classid(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(U32Attrs::Classid(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"U32Attrs",
"Classid",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_hash(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(U32Attrs::Hash(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"U32Attrs",
"Hash",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_link(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(U32Attrs::Link(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"U32Attrs",
"Link",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_divisor(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(U32Attrs::Divisor(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"U32Attrs",
"Divisor",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_sel(&self) -> Result<TcU32Sel, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(U32Attrs::Sel(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"U32Attrs",
"Sel",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_police(&self) -> Result<IterablePoliceAttrs<'a>, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(U32Attrs::Police(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"U32Attrs",
"Police",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_act(
&self,
) -> Result<ArrayIterable<IterableArrayActAttrs<'a>, IterableActAttrs<'a>>, ErrorContext> {
for attr in self.clone() {
if let Ok(U32Attrs::Act(val)) = attr {
return Ok(ArrayIterable::new(val));
}
}
Err(ErrorContext::new_missing(
"U32Attrs",
"Act",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_indev(&self) -> Result<&'a CStr, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(U32Attrs::Indev(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"U32Attrs",
"Indev",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pcnt(&self) -> Result<TcU32Pcnt, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(U32Attrs::Pcnt(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"U32Attrs",
"Pcnt",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_mark(&self) -> Result<TcU32Mark, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(U32Attrs::Mark(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"U32Attrs",
"Mark",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_flags(&self) -> Result<u32, ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(U32Attrs::Flags(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"U32Attrs",
"Flags",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
pub fn get_pad(&self) -> Result<&'a [u8], ErrorContext> {
let mut iter = self.clone();
iter.pos = 0;
for attr in iter {
if let Ok(U32Attrs::Pad(val)) = attr {
return Ok(val);
}
}
Err(ErrorContext::new_missing(
"U32Attrs",
"Pad",
self.orig_loc,
self.buf.as_ptr() as usize,
))
}
}
impl U32Attrs<'_> {
pub fn new<'a>(buf: &'a [u8]) -> IterableU32Attrs<'a> {
IterableU32Attrs::with_loc(buf, buf.as_ptr() as usize)
}
fn attr_from_type(r#type: u16) -> Option<&'static str> {
let res = match r#type {
1u16 => "Classid",
2u16 => "Hash",
3u16 => "Link",
4u16 => "Divisor",
5u16 => "Sel",
6u16 => "Police",
7u16 => "Act",
8u16 => "Indev",
9u16 => "Pcnt",
10u16 => "Mark",
11u16 => "Flags",
12u16 => "Pad",
_ => return None,
};
Some(res)
}
}
#[derive(Clone, Copy, Default)]
pub struct IterableU32Attrs<'a> {
buf: &'a [u8],
pos: usize,
orig_loc: usize,
}
impl<'a> IterableU32Attrs<'a> {
fn with_loc(buf: &'a [u8], orig_loc: usize) -> Self {
Self {
buf,
pos: 0,
orig_loc,
}
}
pub fn get_buf(&self) -> &'a [u8] {
self.buf
}
}
impl<'a> Iterator for IterableU32Attrs<'a> {
type Item = Result<U32Attrs<'a>, ErrorContext>;
fn next(&mut self) -> Option<Self::Item> {
let mut pos;
let mut r#type;
loop {
pos = self.pos;
r#type = None;
if self.buf.len() == self.pos {
return None;
}
let Some((header, next)) = chop_header(self.buf, &mut self.pos) else {
self.pos = self.buf.len();
break;
};
r#type = Some(header.r#type);
let res = match header.r#type {
1u16 => U32Attrs::Classid({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
2u16 => U32Attrs::Hash({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
3u16 => U32Attrs::Link({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
4u16 => U32Attrs::Divisor({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
5u16 => U32Attrs::Sel({
let res = Some(TcU32Sel::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
6u16 => U32Attrs::Police({
let res = Some(IterablePoliceAttrs::with_loc(next, self.orig_loc));
let Some(val) = res else { break };
val
}),
7u16 => U32Attrs::Act({
let res = Some(IterableArrayActAttrs::with_loc(next, self.orig_loc));
let Some(val) = res else { break };
val
}),
8u16 => U32Attrs::Indev({
let res = CStr::from_bytes_with_nul(next).ok();
let Some(val) = res else { break };
val
}),
9u16 => U32Attrs::Pcnt({
let res = Some(TcU32Pcnt::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
10u16 => U32Attrs::Mark({
let res = Some(TcU32Mark::new_from_zeroed(next));
let Some(val) = res else { break };
val
}),
11u16 => U32Attrs::Flags({
let res = parse_u32(next);
let Some(val) = res else { break };
val
}),
12u16 => U32Attrs::Pad({
let res = Some(next);
let Some(val) = res else { break };
val
}),
n if cfg!(any(test, feature = "deny-unknown-attrs")) => break,
n => continue,
};
return Some(Ok(res));
}
Some(Err(ErrorContext::new(
"U32Attrs",
r#type.and_then(|t| U32Attrs::attr_from_type(t)),
self.orig_loc,
self.buf.as_ptr().wrapping_add(pos) as usize,
)))
}
}
impl<'a> std::fmt::Debug for IterableU32Attrs<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut fmt = f.debug_struct("U32Attrs");
for attr in self.clone() {
let attr = match attr {
Ok(a) => a,
Err(err) => {
fmt.finish()?;
f.write_str("Err(")?;
err.fmt(f)?;
return f.write_str(")");
}
};
match attr {
U32Attrs::Classid(val) => fmt.field("Classid", &val),
U32Attrs::Hash(val) => fmt.field("Hash", &val),
U32Attrs::Link(val) => fmt.field("Link", &val),
U32Attrs::Divisor(val) => fmt.field("Divisor", &val),
U32Attrs::Sel(val) => fmt.field("Sel", &val),
U32Attrs::Police(val) => fmt.field("Police", &val),
U32Attrs::Act(val) => fmt.field("Act", &val),
U32Attrs::Indev(val) => fmt.field("Indev", &val),
U32Attrs::Pcnt(val) => fmt.field("Pcnt", &val),
U32Attrs::Mark(val) => fmt.field("Mark", &val),
U32Attrs::Flags(val) => fmt.field("Flags", &val),
U32Attrs::Pad(val) => fmt.field("Pad", &val),
};
}
fmt.finish()
}
}
impl IterableU32Attrs<'_> {
pub fn lookup_attr(
&self,
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
let mut stack = Vec::new();
let cur = ErrorContext::calc_offset(self.orig_loc, self.buf.as_ptr() as usize);
if missing_type.is_some() && cur == offset {
stack.push(("U32Attrs", offset));
return (
stack,
missing_type.and_then(|t| U32Attrs::attr_from_type(t)),
);
}
if cur > offset || cur + self.buf.len() < offset {
return (stack, None);
}
let mut attrs = self.clone();
let mut last_off = cur + attrs.pos;
let mut missing = None;
while let Some(attr) = attrs.next() {
let Ok(attr) = attr else { break };
match attr {
U32Attrs::Classid(val) => {
if last_off == offset {
stack.push(("Classid", last_off));
break;
}
}
U32Attrs::Hash(val) => {
if last_off == offset {
stack.push(("Hash", last_off));
break;
}
}
U32Attrs::Link(val) => {
if last_off == offset {
stack.push(("Link", last_off));
break;
}
}
U32Attrs::Divisor(val) => {
if last_off == offset {
stack.push(("Divisor", last_off));
break;
}
}
U32Attrs::Sel(val) => {
if last_off == offset {
stack.push(("Sel", last_off));
break;
}
}
U32Attrs::Police(val) => {
(stack, missing) = val.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
U32Attrs::Act(val) => {
for entry in val {
let Ok(attr) = entry else { break };
(stack, missing) = attr.lookup_attr(offset, missing_type);
if !stack.is_empty() {
break;
}
}
if !stack.is_empty() {
stack.push(("Act", last_off));
break;
}
}
U32Attrs::Indev(val) => {
if last_off == offset {
stack.push(("Indev", last_off));
break;
}
}
U32Attrs::Pcnt(val) => {
if last_off == offset {
stack.push(("Pcnt", last_off));
break;
}
}
U32Attrs::Mark(val) => {
if last_off == offset {
stack.push(("Mark", last_off));
break;
}
}
U32Attrs::Flags(val) => {
if last_off == offset {
stack.push(("Flags", last_off));
break;
}
}
U32Attrs::Pad(val) => {
if last_off == offset {
stack.push(("Pad", last_off));
break;
}
}
_ => {}
};
last_off = cur + attrs.pos;
}
if !stack.is_empty() {
stack.push(("U32Attrs", cur));
}
(stack, missing)
}
}
pub struct PushAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_kind(mut self, value: &CStr) -> Self {
push_header(
self.as_vec_mut(),
1u16,
value.to_bytes_with_nul().len() as u16,
);
self.as_vec_mut().extend(value.to_bytes_with_nul());
self
}
pub fn push_kind_bytes(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 1u16, (value.len() + 1) as u16);
self.as_vec_mut().extend(value);
self.as_vec_mut().push(0);
self
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_basic(mut self) -> PushBasicAttrs<PushDummy<Prev>> {
self = self.push_kind(c"basic");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushBasicAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_bpf(mut self) -> PushBpfAttrs<PushDummy<Prev>> {
self = self.push_kind(c"bpf");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushBpfAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_bfifo(mut self, fixed_header: &TcFifoQopt) -> Self {
self = self.push_kind(c"bfifo");
self.header_offset = Some(push_nested_header(self.as_vec_mut(), 2u16));
self.as_vec_mut().extend(fixed_header.as_slice());
self
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_cake(mut self) -> PushCakeAttrs<PushDummy<Prev>> {
self = self.push_kind(c"cake");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushCakeAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_cbs(mut self) -> PushCbsAttrs<PushDummy<Prev>> {
self = self.push_kind(c"cbs");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushCbsAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_cgroup(mut self) -> PushCgroupAttrs<PushDummy<Prev>> {
self = self.push_kind(c"cgroup");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushCgroupAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_choke(mut self) -> PushChokeAttrs<PushDummy<Prev>> {
self = self.push_kind(c"choke");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushChokeAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_clsact(mut self) -> Self {
self = self.push_kind(c"clsact");
self.header_offset = Some(push_nested_header(self.as_vec_mut(), 2u16));
self
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_codel(mut self) -> PushCodelAttrs<PushDummy<Prev>> {
self = self.push_kind(c"codel");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushCodelAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_drr(mut self) -> PushDrrAttrs<PushDummy<Prev>> {
self = self.push_kind(c"drr");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushDrrAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_dualpi2(mut self) -> PushDualpi2Attrs<PushDummy<Prev>> {
self = self.push_kind(c"dualpi2");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushDualpi2Attrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_etf(mut self) -> PushEtfAttrs<PushDummy<Prev>> {
self = self.push_kind(c"etf");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushEtfAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_ets(mut self) -> PushEtsAttrs<PushDummy<Prev>> {
self = self.push_kind(c"ets");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushEtsAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_flow(mut self) -> PushFlowAttrs<PushDummy<Prev>> {
self = self.push_kind(c"flow");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushFlowAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_flower(mut self) -> PushFlowerAttrs<PushDummy<Prev>> {
self = self.push_kind(c"flower");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushFlowerAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_fq(mut self) -> PushFqAttrs<PushDummy<Prev>> {
self = self.push_kind(c"fq");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushFqAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_fq_codel(mut self) -> PushFqCodelAttrs<PushDummy<Prev>> {
self = self.push_kind(c"fq_codel");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushFqCodelAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_fq_pie(mut self) -> PushFqPieAttrs<PushDummy<Prev>> {
self = self.push_kind(c"fq_pie");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushFqPieAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_fw(mut self) -> PushFwAttrs<PushDummy<Prev>> {
self = self.push_kind(c"fw");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushFwAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_gred(mut self) -> PushGredAttrs<PushDummy<Prev>> {
self = self.push_kind(c"gred");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushGredAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_hfsc(mut self, fixed_header: &TcHfscQopt) -> Self {
self = self.push_kind(c"hfsc");
self.header_offset = Some(push_nested_header(self.as_vec_mut(), 2u16));
self.as_vec_mut().extend(fixed_header.as_slice());
self
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_hhf(mut self) -> PushHhfAttrs<PushDummy<Prev>> {
self = self.push_kind(c"hhf");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushHhfAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_htb(mut self) -> PushHtbAttrs<PushDummy<Prev>> {
self = self.push_kind(c"htb");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushHtbAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_ingress(mut self) -> Self {
self = self.push_kind(c"ingress");
self.header_offset = Some(push_nested_header(self.as_vec_mut(), 2u16));
self
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_matchall(mut self) -> PushMatchallAttrs<PushDummy<Prev>> {
self = self.push_kind(c"matchall");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushMatchallAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_mq(mut self) -> Self {
self = self.push_kind(c"mq");
self.header_offset = Some(push_nested_header(self.as_vec_mut(), 2u16));
self
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_mqprio(mut self, fixed_header: &TcMqprioQopt) -> Self {
self = self.push_kind(c"mqprio");
self.header_offset = Some(push_nested_header(self.as_vec_mut(), 2u16));
self.as_vec_mut().extend(fixed_header.as_slice());
self
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_multiq(mut self, fixed_header: &TcMultiqQopt) -> Self {
self = self.push_kind(c"multiq");
self.header_offset = Some(push_nested_header(self.as_vec_mut(), 2u16));
self.as_vec_mut().extend(fixed_header.as_slice());
self
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_netem(
mut self,
fixed_header: &TcNetemQopt,
) -> PushNetemAttrs<PushDummy<Prev>> {
self = self.push_kind(c"netem");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
self.as_vec_mut().extend(fixed_header.as_slice());
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushNetemAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_pfifo(mut self, fixed_header: &TcFifoQopt) -> Self {
self = self.push_kind(c"pfifo");
self.header_offset = Some(push_nested_header(self.as_vec_mut(), 2u16));
self.as_vec_mut().extend(fixed_header.as_slice());
self
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_pfifo_fast(mut self, fixed_header: &TcPrioQopt) -> Self {
self = self.push_kind(c"pfifo_fast");
self.header_offset = Some(push_nested_header(self.as_vec_mut(), 2u16));
self.as_vec_mut().extend(fixed_header.as_slice());
self
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_pfifo_head_drop(mut self, fixed_header: &TcFifoQopt) -> Self {
self = self.push_kind(c"pfifo_head_drop");
self.header_offset = Some(push_nested_header(self.as_vec_mut(), 2u16));
self.as_vec_mut().extend(fixed_header.as_slice());
self
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_pie(mut self) -> PushPieAttrs<PushDummy<Prev>> {
self = self.push_kind(c"pie");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushPieAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_plug(mut self, fixed_header: &TcPlugQopt) -> Self {
self = self.push_kind(c"plug");
self.header_offset = Some(push_nested_header(self.as_vec_mut(), 2u16));
self.as_vec_mut().extend(fixed_header.as_slice());
self
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_prio(mut self, fixed_header: &TcPrioQopt) -> Self {
self = self.push_kind(c"prio");
self.header_offset = Some(push_nested_header(self.as_vec_mut(), 2u16));
self.as_vec_mut().extend(fixed_header.as_slice());
self
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_qfq(mut self) -> PushQfqAttrs<PushDummy<Prev>> {
self = self.push_kind(c"qfq");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushQfqAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_red(mut self) -> PushRedAttrs<PushDummy<Prev>> {
self = self.push_kind(c"red");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushRedAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_route(mut self) -> PushRouteAttrs<PushDummy<Prev>> {
self = self.push_kind(c"route");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushRouteAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_sfb(mut self, fixed_header: &TcSfbQopt) -> Self {
self = self.push_kind(c"sfb");
self.header_offset = Some(push_nested_header(self.as_vec_mut(), 2u16));
self.as_vec_mut().extend(fixed_header.as_slice());
self
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_sfq(mut self, fixed_header: &TcSfqQoptV1) -> Self {
self = self.push_kind(c"sfq");
self.header_offset = Some(push_nested_header(self.as_vec_mut(), 2u16));
self.as_vec_mut().extend(fixed_header.as_slice());
self
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_taprio(mut self) -> PushTaprioAttrs<PushDummy<Prev>> {
self = self.push_kind(c"taprio");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushTaprioAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_tbf(mut self) -> PushTbfAttrs<PushDummy<Prev>> {
self = self.push_kind(c"tbf");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushTbfAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_u32(mut self) -> PushU32Attrs<PushDummy<Prev>> {
self = self.push_kind(c"u32");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushU32Attrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
pub fn push_stats(mut self, value: TcStats) -> Self {
push_header(self.as_vec_mut(), 3u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_xstats_cake(mut self) -> PushCakeStatsAttrs<PushDummy<Prev>> {
self = self.push_kind(c"cake");
let new_header_offset = push_nested_header(self.as_vec_mut(), 4u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushCakeStatsAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_xstats_choke(mut self, fixed_header: &TcChokeXstats) -> Self {
self = self.push_kind(c"choke");
self.header_offset = Some(push_nested_header(self.as_vec_mut(), 4u16));
self.as_vec_mut().extend(fixed_header.as_slice());
self
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_xstats_codel(mut self, fixed_header: &TcCodelXstats) -> Self {
self = self.push_kind(c"codel");
self.header_offset = Some(push_nested_header(self.as_vec_mut(), 4u16));
self.as_vec_mut().extend(fixed_header.as_slice());
self
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_xstats_dualpi2(mut self, fixed_header: &TcDualpi2Xstats) -> Self {
self = self.push_kind(c"dualpi2");
self.header_offset = Some(push_nested_header(self.as_vec_mut(), 4u16));
self.as_vec_mut().extend(fixed_header.as_slice());
self
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_xstats_fq(mut self, fixed_header: &TcFqQdStats) -> Self {
self = self.push_kind(c"fq");
self.header_offset = Some(push_nested_header(self.as_vec_mut(), 4u16));
self.as_vec_mut().extend(fixed_header.as_slice());
self
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_xstats_fq_codel(mut self, fixed_header: &TcFqCodelXstats) -> Self {
self = self.push_kind(c"fq_codel");
self.header_offset = Some(push_nested_header(self.as_vec_mut(), 4u16));
self.as_vec_mut().extend(fixed_header.as_slice());
self
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_xstats_fq_pie(mut self, fixed_header: &TcFqPieXstats) -> Self {
self = self.push_kind(c"fq_pie");
self.header_offset = Some(push_nested_header(self.as_vec_mut(), 4u16));
self.as_vec_mut().extend(fixed_header.as_slice());
self
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_xstats_hhf(mut self, fixed_header: &TcHhfXstats) -> Self {
self = self.push_kind(c"hhf");
self.header_offset = Some(push_nested_header(self.as_vec_mut(), 4u16));
self.as_vec_mut().extend(fixed_header.as_slice());
self
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_xstats_pie(mut self, fixed_header: &TcPieXstats) -> Self {
self = self.push_kind(c"pie");
self.header_offset = Some(push_nested_header(self.as_vec_mut(), 4u16));
self.as_vec_mut().extend(fixed_header.as_slice());
self
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_xstats_red(mut self, fixed_header: &TcRedXstats) -> Self {
self = self.push_kind(c"red");
self.header_offset = Some(push_nested_header(self.as_vec_mut(), 4u16));
self.as_vec_mut().extend(fixed_header.as_slice());
self
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_xstats_sfb(mut self, fixed_header: &TcSfbXstats) -> Self {
self = self.push_kind(c"sfb");
self.header_offset = Some(push_nested_header(self.as_vec_mut(), 4u16));
self.as_vec_mut().extend(fixed_header.as_slice());
self
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_xstats_sfq(mut self, fixed_header: &TcSfqXstats) -> Self {
self = self.push_kind(c"sfq");
self.header_offset = Some(push_nested_header(self.as_vec_mut(), 4u16));
self.as_vec_mut().extend(fixed_header.as_slice());
self
}
pub fn push_rate(mut self, value: GnetEstimator) -> Self {
push_header(self.as_vec_mut(), 5u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_fcnt(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 6u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn nested_stats2(mut self) -> PushTcaStatsAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 7u16);
PushTcaStatsAttrs {
prev: Some(self),
header_offset: Some(header_offset),
}
}
pub fn nested_stab(mut self) -> PushTcaStabAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 8u16);
PushTcaStabAttrs {
prev: Some(self),
header_offset: Some(header_offset),
}
}
pub fn push_pad(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 9u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_dump_invisible(mut self, value: ()) -> Self {
push_header(self.as_vec_mut(), 10u16, 0 as u16);
self
}
pub fn push_chain(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 11u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_hw_offload(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 12u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_ingress_block(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 13u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_egress_block(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 14u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_dump_flags(mut self, value: BuiltinBitfield32) -> Self {
push_header(self.as_vec_mut(), 15u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_ext_warn_msg(mut self, value: &CStr) -> Self {
push_header(
self.as_vec_mut(),
16u16,
value.to_bytes_with_nul().len() as u16,
);
self.as_vec_mut().extend(value.to_bytes_with_nul());
self
}
pub fn push_ext_warn_msg_bytes(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 16u16, (value.len() + 1) as u16);
self.as_vec_mut().extend(value);
self.as_vec_mut().push(0);
self
}
}
impl<Prev: Pusher> Drop for PushAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushActAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushActAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushActAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_kind(mut self, value: &CStr) -> Self {
push_header(
self.as_vec_mut(),
1u16,
value.to_bytes_with_nul().len() as u16,
);
self.as_vec_mut().extend(value.to_bytes_with_nul());
self
}
pub fn push_kind_bytes(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 1u16, (value.len() + 1) as u16);
self.as_vec_mut().extend(value);
self.as_vec_mut().push(0);
self
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_bpf(mut self) -> PushActBpfAttrs<PushDummy<Prev>> {
self = self.push_kind(c"bpf");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushActBpfAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_connmark(mut self) -> PushActConnmarkAttrs<PushDummy<Prev>> {
self = self.push_kind(c"connmark");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushActConnmarkAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_csum(mut self) -> PushActCsumAttrs<PushDummy<Prev>> {
self = self.push_kind(c"csum");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushActCsumAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_ct(mut self) -> PushActCtAttrs<PushDummy<Prev>> {
self = self.push_kind(c"ct");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushActCtAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_ctinfo(mut self) -> PushActCtinfoAttrs<PushDummy<Prev>> {
self = self.push_kind(c"ctinfo");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushActCtinfoAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_gact(mut self) -> PushActGactAttrs<PushDummy<Prev>> {
self = self.push_kind(c"gact");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushActGactAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_gate(mut self) -> PushActGateAttrs<PushDummy<Prev>> {
self = self.push_kind(c"gate");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushActGateAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_ife(mut self) -> PushActIfeAttrs<PushDummy<Prev>> {
self = self.push_kind(c"ife");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushActIfeAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_mirred(mut self) -> PushActMirredAttrs<PushDummy<Prev>> {
self = self.push_kind(c"mirred");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushActMirredAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_mpls(mut self) -> PushActMplsAttrs<PushDummy<Prev>> {
self = self.push_kind(c"mpls");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushActMplsAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_nat(mut self) -> PushActNatAttrs<PushDummy<Prev>> {
self = self.push_kind(c"nat");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushActNatAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_pedit(mut self) -> PushActPeditAttrs<PushDummy<Prev>> {
self = self.push_kind(c"pedit");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushActPeditAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_police(mut self) -> PushPoliceAttrs<PushDummy<Prev>> {
self = self.push_kind(c"police");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushPoliceAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_sample(mut self) -> PushActSampleAttrs<PushDummy<Prev>> {
self = self.push_kind(c"sample");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushActSampleAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_simple(mut self) -> PushActSimpleAttrs<PushDummy<Prev>> {
self = self.push_kind(c"simple");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushActSimpleAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_skbedit(mut self) -> PushActSkbeditAttrs<PushDummy<Prev>> {
self = self.push_kind(c"skbedit");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushActSkbeditAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_skbmod(mut self) -> PushActSkbmodAttrs<PushDummy<Prev>> {
self = self.push_kind(c"skbmod");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushActSkbmodAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_tunnel_key(mut self) -> PushActTunnelKeyAttrs<PushDummy<Prev>> {
self = self.push_kind(c"tunnel_key");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushActTunnelKeyAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
#[doc = "Selector attribute `kind` is inserted automatically."]
#[doc = "At most one sub-message attribute is expected per attribute set."]
pub fn nested_options_vlan(mut self) -> PushActVlanAttrs<PushDummy<Prev>> {
self = self.push_kind(c"vlan");
let new_header_offset = push_nested_header(self.as_vec_mut(), 2u16);
let dummy = PushDummy {
prev: self.prev.take(),
header_offset: self.header_offset.take(),
};
PushActVlanAttrs {
prev: Some(dummy),
header_offset: Some(new_header_offset),
}
}
pub fn push_index(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 3u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn nested_stats(mut self) -> PushTcaStatsAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 4u16);
PushTcaStatsAttrs {
prev: Some(self),
header_offset: Some(header_offset),
}
}
pub fn push_pad(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 5u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_cookie(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 6u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_flags(mut self, value: BuiltinBitfield32) -> Self {
push_header(self.as_vec_mut(), 7u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_hw_stats(mut self, value: BuiltinBitfield32) -> Self {
push_header(self.as_vec_mut(), 8u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_used_hw_stats(mut self, value: BuiltinBitfield32) -> Self {
push_header(self.as_vec_mut(), 9u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_in_hw_count(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 10u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushActAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushActBpfAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushActBpfAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushActBpfAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_tm(mut self, value: TcfT) -> Self {
push_header(self.as_vec_mut(), 1u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_parms(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 2u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_ops_len(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 3u16, 2 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_ops(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 4u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_fd(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 5u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_name(mut self, value: &CStr) -> Self {
push_header(
self.as_vec_mut(),
6u16,
value.to_bytes_with_nul().len() as u16,
);
self.as_vec_mut().extend(value.to_bytes_with_nul());
self
}
pub fn push_name_bytes(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 6u16, (value.len() + 1) as u16);
self.as_vec_mut().extend(value);
self.as_vec_mut().push(0);
self
}
pub fn push_pad(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 7u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_tag(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 8u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_id(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 9u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
}
impl<Prev: Pusher> Drop for PushActBpfAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushActConnmarkAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushActConnmarkAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushActConnmarkAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_parms(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 1u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_tm(mut self, value: TcfT) -> Self {
push_header(self.as_vec_mut(), 2u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_pad(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 3u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
}
impl<Prev: Pusher> Drop for PushActConnmarkAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushActCsumAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushActCsumAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushActCsumAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_parms(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 1u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_tm(mut self, value: TcfT) -> Self {
push_header(self.as_vec_mut(), 2u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_pad(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 3u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
}
impl<Prev: Pusher> Drop for PushActCsumAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushActCtAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushActCtAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushActCtAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_parms(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 1u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_tm(mut self, value: TcfT) -> Self {
push_header(self.as_vec_mut(), 2u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_action(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 3u16, 2 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_zone(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 4u16, 2 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_mark(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 5u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_mark_mask(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 6u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_labels(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 7u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_labels_mask(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 8u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_nat_ipv4_min(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 9u16, 4 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_nat_ipv4_max(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 10u16, 4 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_nat_ipv6_min(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 11u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_nat_ipv6_max(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 12u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_nat_port_min(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 13u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_nat_port_max(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 14u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_pad(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 15u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_helper_name(mut self, value: &CStr) -> Self {
push_header(
self.as_vec_mut(),
16u16,
value.to_bytes_with_nul().len() as u16,
);
self.as_vec_mut().extend(value.to_bytes_with_nul());
self
}
pub fn push_helper_name_bytes(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 16u16, (value.len() + 1) as u16);
self.as_vec_mut().extend(value);
self.as_vec_mut().push(0);
self
}
pub fn push_helper_family(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 17u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_helper_proto(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 18u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushActCtAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushActCtinfoAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushActCtinfoAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushActCtinfoAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_pad(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 1u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_tm(mut self, value: TcfT) -> Self {
push_header(self.as_vec_mut(), 2u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_act(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 3u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_zone(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 4u16, 2 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_parms_dscp_mask(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 5u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_parms_dscp_statemask(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 6u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_parms_cpmark_mask(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 7u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_stats_dscp_set(mut self, value: u64) -> Self {
push_header(self.as_vec_mut(), 8u16, 8 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_stats_dscp_error(mut self, value: u64) -> Self {
push_header(self.as_vec_mut(), 9u16, 8 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_stats_cpmark_set(mut self, value: u64) -> Self {
push_header(self.as_vec_mut(), 10u16, 8 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushActCtinfoAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushActGateAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushActGateAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushActGateAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_tm(mut self, value: TcfT) -> Self {
push_header(self.as_vec_mut(), 1u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_parms(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 2u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_pad(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 3u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_priority(mut self, value: i32) -> Self {
push_header(self.as_vec_mut(), 4u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_entry_list(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 5u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_base_time(mut self, value: u64) -> Self {
push_header(self.as_vec_mut(), 6u16, 8 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_cycle_time(mut self, value: u64) -> Self {
push_header(self.as_vec_mut(), 7u16, 8 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_cycle_time_ext(mut self, value: u64) -> Self {
push_header(self.as_vec_mut(), 8u16, 8 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_flags(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 9u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_clockid(mut self, value: i32) -> Self {
push_header(self.as_vec_mut(), 10u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushActGateAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushActIfeAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushActIfeAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushActIfeAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_parms(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 1u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_tm(mut self, value: TcfT) -> Self {
push_header(self.as_vec_mut(), 2u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_dmac(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 3u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_smac(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 4u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_type(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 5u16, 2 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_metalst(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 6u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_pad(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 7u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
}
impl<Prev: Pusher> Drop for PushActIfeAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushActMirredAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushActMirredAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushActMirredAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_tm(mut self, value: TcfT) -> Self {
push_header(self.as_vec_mut(), 1u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_parms(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 2u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_pad(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 3u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_blockid(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 4u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
}
impl<Prev: Pusher> Drop for PushActMirredAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushActMplsAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushActMplsAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushActMplsAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_tm(mut self, value: TcfT) -> Self {
push_header(self.as_vec_mut(), 1u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_parms(mut self, value: TcMpls) -> Self {
push_header(self.as_vec_mut(), 2u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_pad(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 3u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_proto(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 4u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_label(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 5u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_tc(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 6u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_ttl(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 7u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_bos(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 8u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushActMplsAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushActNatAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushActNatAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushActNatAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_parms(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 1u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_tm(mut self, value: TcfT) -> Self {
push_header(self.as_vec_mut(), 2u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_pad(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 3u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
}
impl<Prev: Pusher> Drop for PushActNatAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushActPeditAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushActPeditAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushActPeditAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_tm(mut self, value: TcfT) -> Self {
push_header(self.as_vec_mut(), 1u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_parms(mut self, value: TcPeditSel) -> Self {
push_header(self.as_vec_mut(), 2u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_pad(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 3u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_parms_ex(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 4u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_keys_ex(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 5u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_key_ex(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 6u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
}
impl<Prev: Pusher> Drop for PushActPeditAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushActSimpleAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushActSimpleAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushActSimpleAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_tm(mut self, value: TcfT) -> Self {
push_header(self.as_vec_mut(), 1u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_parms(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 2u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_data(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 3u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_pad(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 4u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
}
impl<Prev: Pusher> Drop for PushActSimpleAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushActSkbeditAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushActSkbeditAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushActSkbeditAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_tm(mut self, value: TcfT) -> Self {
push_header(self.as_vec_mut(), 1u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_parms(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 2u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_priority(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 3u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_queue_mapping(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 4u16, 2 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_mark(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 5u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_pad(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 6u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_ptype(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 7u16, 2 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_mask(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 8u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_flags(mut self, value: u64) -> Self {
push_header(self.as_vec_mut(), 9u16, 8 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_queue_mapping_max(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 10u16, 2 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushActSkbeditAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushActSkbmodAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushActSkbmodAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushActSkbmodAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_tm(mut self, value: TcfT) -> Self {
push_header(self.as_vec_mut(), 1u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_parms(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 2u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_dmac(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 3u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_smac(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 4u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_etype(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 5u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_pad(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 6u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
}
impl<Prev: Pusher> Drop for PushActSkbmodAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushActTunnelKeyAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushActTunnelKeyAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushActTunnelKeyAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_tm(mut self, value: TcfT) -> Self {
push_header(self.as_vec_mut(), 1u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_parms(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 2u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_enc_ipv4_src(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 3u16, 4 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_enc_ipv4_dst(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 4u16, 4 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_enc_ipv6_src(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 5u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_enc_ipv6_dst(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 6u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_enc_key_id(mut self, value: u64) -> Self {
push_header(self.as_vec_mut(), 7u16, 8 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_pad(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 8u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_enc_dst_port(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 9u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_no_csum(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 10u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_enc_opts(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 11u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_enc_tos(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 12u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_enc_ttl(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 13u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_no_frag(mut self, value: ()) -> Self {
push_header(self.as_vec_mut(), 14u16, 0 as u16);
self
}
}
impl<Prev: Pusher> Drop for PushActTunnelKeyAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushActVlanAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushActVlanAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushActVlanAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_tm(mut self, value: TcfT) -> Self {
push_header(self.as_vec_mut(), 1u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_parms(mut self, value: TcVlan) -> Self {
push_header(self.as_vec_mut(), 2u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_push_vlan_id(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 3u16, 2 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_push_vlan_protocol(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 4u16, 2 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_pad(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 5u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_push_vlan_priority(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 6u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_push_eth_dst(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 7u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_push_eth_src(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 8u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
}
impl<Prev: Pusher> Drop for PushActVlanAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushBasicAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushBasicAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
pub struct PushArrayActAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
pub(crate) counter: u16,
}
impl<Prev: Pusher> Pusher for PushArrayActAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushArrayActAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
counter: 0,
}
}
pub fn end_array(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn entry_nested(mut self) -> PushActAttrs<Self> {
let index = self.counter;
self.counter += 1;
let header_offset = push_nested_header(self.as_vec_mut(), index);
PushActAttrs {
prev: Some(self),
header_offset: Some(header_offset),
}
}
}
impl<Prev: Pusher> Drop for PushArrayActAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
impl<Prev: Pusher> PushBasicAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_classid(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 1u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn nested_ematches(mut self) -> PushEmatchAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 2u16);
PushEmatchAttrs {
prev: Some(self),
header_offset: Some(header_offset),
}
}
pub fn array_act(mut self) -> PushArrayActAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 3u16);
PushArrayActAttrs {
prev: Some(self),
header_offset: Some(header_offset),
counter: 0,
}
}
pub fn nested_police(mut self) -> PushPoliceAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 4u16);
PushPoliceAttrs {
prev: Some(self),
header_offset: Some(header_offset),
}
}
pub fn push_pcnt(mut self, value: TcBasicPcnt) -> Self {
push_header(self.as_vec_mut(), 5u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_pad(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 6u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
}
impl<Prev: Pusher> Drop for PushBasicAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushBpfAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushBpfAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushBpfAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn array_act(mut self) -> PushArrayActAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 1u16);
PushArrayActAttrs {
prev: Some(self),
header_offset: Some(header_offset),
counter: 0,
}
}
pub fn nested_police(mut self) -> PushPoliceAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 2u16);
PushPoliceAttrs {
prev: Some(self),
header_offset: Some(header_offset),
}
}
pub fn push_classid(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 3u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_ops_len(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 4u16, 2 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_ops(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 5u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_fd(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 6u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_name(mut self, value: &CStr) -> Self {
push_header(
self.as_vec_mut(),
7u16,
value.to_bytes_with_nul().len() as u16,
);
self.as_vec_mut().extend(value.to_bytes_with_nul());
self
}
pub fn push_name_bytes(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 7u16, (value.len() + 1) as u16);
self.as_vec_mut().extend(value);
self.as_vec_mut().push(0);
self
}
pub fn push_flags(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 8u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_flags_gen(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 9u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_tag(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 10u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_id(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 11u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushBpfAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushCakeAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushCakeAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushCakeAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_pad(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 1u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_base_rate64(mut self, value: u64) -> Self {
push_header(self.as_vec_mut(), 2u16, 8 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_diffserv_mode(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 3u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_atm(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 4u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_flow_mode(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 5u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_overhead(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 6u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_rtt(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 7u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_target(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 8u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_autorate(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 9u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_memory(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 10u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_nat(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 11u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_raw(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 12u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_wash(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 13u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_mpu(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 14u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_ingress(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 15u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_ack_filter(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 16u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_split_gso(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 17u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_fwmark(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 18u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushCakeAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushCakeStatsAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushCakeStatsAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
pub struct PushArrayCakeTinStatsAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
pub(crate) counter: u16,
}
impl<Prev: Pusher> Pusher for PushArrayCakeTinStatsAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushArrayCakeTinStatsAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
counter: 0,
}
}
pub fn end_array(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn entry_nested(mut self) -> PushCakeTinStatsAttrs<Self> {
let index = self.counter;
self.counter += 1;
let header_offset = push_nested_header(self.as_vec_mut(), index);
PushCakeTinStatsAttrs {
prev: Some(self),
header_offset: Some(header_offset),
}
}
}
impl<Prev: Pusher> Drop for PushArrayCakeTinStatsAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
impl<Prev: Pusher> PushCakeStatsAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_pad(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 1u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_capacity_estimate64(mut self, value: u64) -> Self {
push_header(self.as_vec_mut(), 2u16, 8 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_memory_limit(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 3u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_memory_used(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 4u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_avg_netoff(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 5u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_min_netlen(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 6u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_max_netlen(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 7u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_min_adjlen(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 8u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_max_adjlen(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 9u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn array_tin_stats(mut self) -> PushArrayCakeTinStatsAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 10u16);
PushArrayCakeTinStatsAttrs {
prev: Some(self),
header_offset: Some(header_offset),
counter: 0,
}
}
pub fn push_deficit(mut self, value: i32) -> Self {
push_header(self.as_vec_mut(), 11u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_cobalt_count(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 12u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_dropping(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 13u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_drop_next_us(mut self, value: i32) -> Self {
push_header(self.as_vec_mut(), 14u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_p_drop(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 15u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_blue_timer_us(mut self, value: i32) -> Self {
push_header(self.as_vec_mut(), 16u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_active_queues(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 17u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushCakeStatsAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushCakeTinStatsAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushCakeTinStatsAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushCakeTinStatsAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_pad(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 1u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_sent_packets(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 2u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_sent_bytes64(mut self, value: u64) -> Self {
push_header(self.as_vec_mut(), 3u16, 8 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_dropped_packets(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 4u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_dropped_bytes64(mut self, value: u64) -> Self {
push_header(self.as_vec_mut(), 5u16, 8 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_acks_dropped_packets(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 6u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_acks_dropped_bytes64(mut self, value: u64) -> Self {
push_header(self.as_vec_mut(), 7u16, 8 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_ecn_marked_packets(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 8u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_ecn_marked_bytes64(mut self, value: u64) -> Self {
push_header(self.as_vec_mut(), 9u16, 8 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_backlog_packets(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 10u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_backlog_bytes(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 11u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_threshold_rate64(mut self, value: u64) -> Self {
push_header(self.as_vec_mut(), 12u16, 8 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_target_us(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 13u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_interval_us(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 14u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_way_indirect_hits(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 15u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_way_misses(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 16u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_way_collisions(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 17u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_peak_delay_us(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 18u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_avg_delay_us(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 19u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_base_delay_us(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 20u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_sparse_flows(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 21u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_bulk_flows(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 22u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_unresponsive_flows(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 23u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_max_skblen(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 24u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_flow_quantum(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 25u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushCakeTinStatsAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushCbsAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushCbsAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushCbsAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_parms(mut self, value: TcCbsQopt) -> Self {
push_header(self.as_vec_mut(), 1u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
}
impl<Prev: Pusher> Drop for PushCbsAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushCgroupAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushCgroupAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushCgroupAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn array_act(mut self) -> PushArrayActAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 1u16);
PushArrayActAttrs {
prev: Some(self),
header_offset: Some(header_offset),
counter: 0,
}
}
pub fn nested_police(mut self) -> PushPoliceAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 2u16);
PushPoliceAttrs {
prev: Some(self),
header_offset: Some(header_offset),
}
}
pub fn push_ematches(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 3u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
}
impl<Prev: Pusher> Drop for PushCgroupAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushChokeAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushChokeAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushChokeAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_parms(mut self, value: TcRedQopt) -> Self {
push_header(self.as_vec_mut(), 1u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_stab(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 2u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_max_p(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 3u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushChokeAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushCodelAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushCodelAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushCodelAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_target(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 1u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_limit(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 2u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_interval(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 3u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_ecn(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 4u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_ce_threshold(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 5u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushCodelAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushDrrAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushDrrAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushDrrAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_quantum(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 1u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushDrrAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushDualpi2Attrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushDualpi2Attrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushDualpi2Attrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
#[doc = "Limit of total number of packets in queue\n"]
pub fn push_limit(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 1u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
#[doc = "Memory limit of total number of packets in queue\n"]
pub fn push_memory_limit(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 2u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
#[doc = "Classic target delay in microseconds\n"]
pub fn push_target(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 3u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
#[doc = "Drop probability update interval time in microseconds\n"]
pub fn push_tupdate(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 4u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
#[doc = "Integral gain factor in Hz for PI controller\n"]
pub fn push_alpha(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 5u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
#[doc = "Proportional gain factor in Hz for PI controller\n"]
pub fn push_beta(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 6u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
#[doc = "L4S step marking threshold in packets\n"]
pub fn push_step_thresh_pkts(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 7u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
#[doc = "L4S Step marking threshold in microseconds\n"]
pub fn push_step_thresh_us(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 8u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
#[doc = "Packets enqueued to the L-queue can apply the step threshold when the\nqueue length of L-queue is larger than this value. (0 is recommended)\n"]
pub fn push_min_qlen_step(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 9u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
#[doc = "Probability coupling factor between Classic and L4S (2 is recommended)\n"]
pub fn push_coupling(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 10u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
#[doc = "Control the overload strategy (drop to preserve latency or let the queue\noverflow)\n\nAssociated type: [`Dualpi2DropOverload`] (enum)"]
pub fn push_drop_overload(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 11u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
#[doc = "Decide where the Classic packets are PI-based dropped or marked\n\nAssociated type: [`Dualpi2DropEarly`] (enum)"]
pub fn push_drop_early(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 12u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
#[doc = "Classic WRR weight in percentage (from 0 to 100)\n"]
pub fn push_c_protection(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 13u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
#[doc = "Configure the L-queue ECN classifier\n\nAssociated type: [`Dualpi2EcnMask`] (enum)"]
pub fn push_ecn_mask(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 14u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
#[doc = "Split aggregated skb or not\n\nAssociated type: [`Dualpi2SplitGso`] (enum)"]
pub fn push_split_gso(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 15u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushDualpi2Attrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushEmatchAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushEmatchAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushEmatchAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_tree_hdr(mut self, value: TcfEmatchTreeHdr) -> Self {
push_header(self.as_vec_mut(), 1u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_tree_list(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 2u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
}
impl<Prev: Pusher> Drop for PushEmatchAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushFlowAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushFlowAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushFlowAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_keys(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 1u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_mode(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 2u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_baseclass(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 3u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_rshift(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 4u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_addend(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 5u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_mask(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 6u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_xor(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 7u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_divisor(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 8u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_act(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 9u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn nested_police(mut self) -> PushPoliceAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 10u16);
PushPoliceAttrs {
prev: Some(self),
header_offset: Some(header_offset),
}
}
pub fn push_ematches(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 11u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_perturb(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 12u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushFlowAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushFlowerAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushFlowerAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushFlowerAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_classid(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 1u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_indev(mut self, value: &CStr) -> Self {
push_header(
self.as_vec_mut(),
2u16,
value.to_bytes_with_nul().len() as u16,
);
self.as_vec_mut().extend(value.to_bytes_with_nul());
self
}
pub fn push_indev_bytes(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 2u16, (value.len() + 1) as u16);
self.as_vec_mut().extend(value);
self.as_vec_mut().push(0);
self
}
pub fn array_act(mut self) -> PushArrayActAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 3u16);
PushArrayActAttrs {
prev: Some(self),
header_offset: Some(header_offset),
counter: 0,
}
}
pub fn push_key_eth_dst(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 4u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_key_eth_dst_mask(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 5u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_key_eth_src(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 6u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_key_eth_src_mask(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 7u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_key_eth_type(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 8u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_ip_proto(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 9u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_ipv4_src(mut self, value: std::net::Ipv4Addr) -> Self {
push_header(self.as_vec_mut(), 10u16, 4 as u16);
self.as_vec_mut().extend(&value.to_bits().to_be_bytes());
self
}
pub fn push_key_ipv4_src_mask(mut self, value: std::net::Ipv4Addr) -> Self {
push_header(self.as_vec_mut(), 11u16, 4 as u16);
self.as_vec_mut().extend(&value.to_bits().to_be_bytes());
self
}
pub fn push_key_ipv4_dst(mut self, value: std::net::Ipv4Addr) -> Self {
push_header(self.as_vec_mut(), 12u16, 4 as u16);
self.as_vec_mut().extend(&value.to_bits().to_be_bytes());
self
}
pub fn push_key_ipv4_dst_mask(mut self, value: std::net::Ipv4Addr) -> Self {
push_header(self.as_vec_mut(), 13u16, 4 as u16);
self.as_vec_mut().extend(&value.to_bits().to_be_bytes());
self
}
pub fn push_key_ipv6_src(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 14u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_key_ipv6_src_mask(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 15u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_key_ipv6_dst(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 16u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_key_ipv6_dst_mask(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 17u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_key_tcp_src(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 18u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_tcp_dst(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 19u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_udp_src(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 20u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_udp_dst(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 21u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
#[doc = "Associated type: [`ClsFlags`] (1 bit per enumeration)"]
pub fn push_flags(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 22u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_vlan_id(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 23u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_vlan_prio(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 24u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_vlan_eth_type(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 25u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_enc_key_id(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 26u16, 4 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_enc_ipv4_src(mut self, value: std::net::Ipv4Addr) -> Self {
push_header(self.as_vec_mut(), 27u16, 4 as u16);
self.as_vec_mut().extend(&value.to_bits().to_be_bytes());
self
}
pub fn push_key_enc_ipv4_src_mask(mut self, value: std::net::Ipv4Addr) -> Self {
push_header(self.as_vec_mut(), 28u16, 4 as u16);
self.as_vec_mut().extend(&value.to_bits().to_be_bytes());
self
}
pub fn push_key_enc_ipv4_dst(mut self, value: std::net::Ipv4Addr) -> Self {
push_header(self.as_vec_mut(), 29u16, 4 as u16);
self.as_vec_mut().extend(&value.to_bits().to_be_bytes());
self
}
pub fn push_key_enc_ipv4_dst_mask(mut self, value: std::net::Ipv4Addr) -> Self {
push_header(self.as_vec_mut(), 30u16, 4 as u16);
self.as_vec_mut().extend(&value.to_bits().to_be_bytes());
self
}
pub fn push_key_enc_ipv6_src(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 31u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_key_enc_ipv6_src_mask(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 32u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_key_enc_ipv6_dst(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 33u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_key_enc_ipv6_dst_mask(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 34u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_key_tcp_src_mask(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 35u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_tcp_dst_mask(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 36u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_udp_src_mask(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 37u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_udp_dst_mask(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 38u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_sctp_src_mask(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 39u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_sctp_dst_mask(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 40u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_sctp_src(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 41u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_sctp_dst(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 42u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_enc_udp_src_port(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 43u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_enc_udp_src_port_mask(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 44u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_enc_udp_dst_port(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 45u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_enc_udp_dst_port_mask(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 46u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
#[doc = "Associated type: [`FlowerKeyCtrlFlags`] (1 bit per enumeration)"]
pub fn push_key_flags(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 47u16, 4 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
#[doc = "Associated type: [`FlowerKeyCtrlFlags`] (1 bit per enumeration)"]
pub fn push_key_flags_mask(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 48u16, 4 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_icmpv4_code(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 49u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_icmpv4_code_mask(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 50u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_icmpv4_type(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 51u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_icmpv4_type_mask(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 52u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_icmpv6_code(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 53u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_icmpv6_code_mask(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 54u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_icmpv6_type(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 55u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_icmpv6_type_mask(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 56u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_arp_sip(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 57u16, 4 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_arp_sip_mask(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 58u16, 4 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_arp_tip(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 59u16, 4 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_arp_tip_mask(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 60u16, 4 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_arp_op(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 61u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_arp_op_mask(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 62u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_arp_sha(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 63u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_key_arp_sha_mask(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 64u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_key_arp_tha(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 65u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_key_arp_tha_mask(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 66u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_key_mpls_ttl(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 67u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_mpls_bos(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 68u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_mpls_tc(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 69u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_mpls_label(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 70u16, 4 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_tcp_flags(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 71u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_tcp_flags_mask(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 72u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_ip_tos(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 73u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_ip_tos_mask(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 74u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_ip_ttl(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 75u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_ip_ttl_mask(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 76u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_cvlan_id(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 77u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_cvlan_prio(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 78u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_cvlan_eth_type(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 79u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_enc_ip_tos(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 80u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_enc_ip_tos_mask(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 81u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_enc_ip_ttl(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 82u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_enc_ip_ttl_mask(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 83u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn nested_key_enc_opts(mut self) -> PushFlowerKeyEncOptsAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 84u16);
PushFlowerKeyEncOptsAttrs {
prev: Some(self),
header_offset: Some(header_offset),
}
}
pub fn nested_key_enc_opts_mask(mut self) -> PushFlowerKeyEncOptsAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 85u16);
PushFlowerKeyEncOptsAttrs {
prev: Some(self),
header_offset: Some(header_offset),
}
}
pub fn push_in_hw_count(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 86u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_port_src_min(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 87u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_port_src_max(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 88u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_port_dst_min(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 89u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_port_dst_max(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 90u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_ct_state(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 91u16, 2 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_ct_state_mask(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 92u16, 2 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_ct_zone(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 93u16, 2 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_ct_zone_mask(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 94u16, 2 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_ct_mark(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 95u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_ct_mark_mask(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 96u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_ct_labels(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 97u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_key_ct_labels_mask(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 98u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn nested_key_mpls_opts(mut self) -> PushFlowerKeyMplsOptAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 99u16);
PushFlowerKeyMplsOptAttrs {
prev: Some(self),
header_offset: Some(header_offset),
}
}
pub fn push_key_hash(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 100u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_hash_mask(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 101u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_num_of_vlans(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 102u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_key_pppoe_sid(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 103u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_ppp_proto(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 104u16, 2 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_l2tpv3_sid(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 105u16, 4 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_l2_miss(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 106u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn nested_key_cfm(mut self) -> PushFlowerKeyCfmAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 107u16);
PushFlowerKeyCfmAttrs {
prev: Some(self),
header_offset: Some(header_offset),
}
}
pub fn push_key_spi(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 108u16, 4 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
pub fn push_key_spi_mask(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 109u16, 4 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
#[doc = "Associated type: [`FlowerKeyCtrlFlags`] (1 bit per enumeration)"]
pub fn push_key_enc_flags(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 110u16, 4 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
#[doc = "Associated type: [`FlowerKeyCtrlFlags`] (1 bit per enumeration)"]
pub fn push_key_enc_flags_mask(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 111u16, 4 as u16);
self.as_vec_mut().extend(value.to_be_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushFlowerAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushFlowerKeyEncOptsAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushFlowerKeyEncOptsAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushFlowerKeyEncOptsAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn nested_geneve(mut self) -> PushFlowerKeyEncOptGeneveAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 1u16);
PushFlowerKeyEncOptGeneveAttrs {
prev: Some(self),
header_offset: Some(header_offset),
}
}
pub fn nested_vxlan(mut self) -> PushFlowerKeyEncOptVxlanAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 2u16);
PushFlowerKeyEncOptVxlanAttrs {
prev: Some(self),
header_offset: Some(header_offset),
}
}
pub fn nested_erspan(mut self) -> PushFlowerKeyEncOptErspanAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 3u16);
PushFlowerKeyEncOptErspanAttrs {
prev: Some(self),
header_offset: Some(header_offset),
}
}
pub fn nested_gtp(mut self) -> PushFlowerKeyEncOptGtpAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 4u16);
PushFlowerKeyEncOptGtpAttrs {
prev: Some(self),
header_offset: Some(header_offset),
}
}
}
impl<Prev: Pusher> Drop for PushFlowerKeyEncOptsAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushFlowerKeyEncOptGeneveAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushFlowerKeyEncOptGeneveAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushFlowerKeyEncOptGeneveAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_class(mut self, value: u16) -> Self {
push_header(self.as_vec_mut(), 1u16, 2 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_type(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 2u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_data(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 3u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
}
impl<Prev: Pusher> Drop for PushFlowerKeyEncOptGeneveAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushFlowerKeyEncOptVxlanAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushFlowerKeyEncOptVxlanAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushFlowerKeyEncOptVxlanAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_gbp(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 1u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushFlowerKeyEncOptVxlanAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushFlowerKeyEncOptErspanAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushFlowerKeyEncOptErspanAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushFlowerKeyEncOptErspanAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_ver(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 1u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_index(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 2u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_dir(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 3u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_hwid(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 4u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushFlowerKeyEncOptErspanAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushFlowerKeyEncOptGtpAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushFlowerKeyEncOptGtpAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushFlowerKeyEncOptGtpAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_pdu_type(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 1u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_qfi(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 2u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushFlowerKeyEncOptGtpAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushFlowerKeyMplsOptAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushFlowerKeyMplsOptAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushFlowerKeyMplsOptAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_lse_depth(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 1u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_lse_ttl(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 2u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_lse_bos(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 3u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_lse_tc(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 4u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_lse_label(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 5u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushFlowerKeyMplsOptAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushFlowerKeyCfmAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushFlowerKeyCfmAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushFlowerKeyCfmAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_md_level(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 1u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_opcode(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 2u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushFlowerKeyCfmAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushFwAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushFwAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushFwAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_classid(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 1u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn nested_police(mut self) -> PushPoliceAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 2u16);
PushPoliceAttrs {
prev: Some(self),
header_offset: Some(header_offset),
}
}
pub fn push_indev(mut self, value: &CStr) -> Self {
push_header(
self.as_vec_mut(),
3u16,
value.to_bytes_with_nul().len() as u16,
);
self.as_vec_mut().extend(value.to_bytes_with_nul());
self
}
pub fn push_indev_bytes(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 3u16, (value.len() + 1) as u16);
self.as_vec_mut().extend(value);
self.as_vec_mut().push(0);
self
}
pub fn array_act(mut self) -> PushArrayActAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 4u16);
PushArrayActAttrs {
prev: Some(self),
header_offset: Some(header_offset),
counter: 0,
}
}
pub fn push_mask(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 5u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushFwAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushGredAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushGredAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushGredAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_parms(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 1u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_stab(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 2u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_dps(mut self, value: TcGredSopt) -> Self {
push_header(self.as_vec_mut(), 3u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_max_p(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 4u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_limit(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 5u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn nested_vq_list(mut self) -> PushTcaGredVqListAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 6u16);
PushTcaGredVqListAttrs {
prev: Some(self),
header_offset: Some(header_offset),
}
}
}
impl<Prev: Pusher> Drop for PushGredAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushTcaGredVqListAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushTcaGredVqListAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushTcaGredVqListAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
#[doc = "Attribute may repeat multiple times (treat it as array)"]
pub fn nested_entry(mut self) -> PushTcaGredVqEntryAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 1u16);
PushTcaGredVqEntryAttrs {
prev: Some(self),
header_offset: Some(header_offset),
}
}
}
impl<Prev: Pusher> Drop for PushTcaGredVqListAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushTcaGredVqEntryAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushTcaGredVqEntryAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushTcaGredVqEntryAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_pad(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 1u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_dp(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 2u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_stat_bytes(mut self, value: u64) -> Self {
push_header(self.as_vec_mut(), 3u16, 8 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_stat_packets(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 4u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_stat_backlog(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 5u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_stat_prob_drop(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 6u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_stat_prob_mark(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 7u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_stat_forced_drop(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 8u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_stat_forced_mark(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 9u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_stat_pdrop(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 10u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_stat_other(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 11u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_flags(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 12u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushTcaGredVqEntryAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushHfscAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushHfscAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushHfscAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_rsc(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 1u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_fsc(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 2u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_usc(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 3u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
}
impl<Prev: Pusher> Drop for PushHfscAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushHhfAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushHhfAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushHhfAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_backlog_limit(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 1u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_quantum(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 2u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_hh_flows_limit(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 3u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_reset_timeout(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 4u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_admit_bytes(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 5u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_evict_timeout(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 6u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_non_hh_weight(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 7u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushHhfAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushHtbAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushHtbAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushHtbAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_parms(mut self, value: TcHtbOpt) -> Self {
push_header(self.as_vec_mut(), 1u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_init(mut self, value: TcHtbGlob) -> Self {
push_header(self.as_vec_mut(), 2u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_ctab(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 3u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_rtab(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 4u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_direct_qlen(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 5u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_rate64(mut self, value: u64) -> Self {
push_header(self.as_vec_mut(), 6u16, 8 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_ceil64(mut self, value: u64) -> Self {
push_header(self.as_vec_mut(), 7u16, 8 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_pad(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 8u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_offload(mut self, value: ()) -> Self {
push_header(self.as_vec_mut(), 9u16, 0 as u16);
self
}
}
impl<Prev: Pusher> Drop for PushHtbAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushMatchallAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushMatchallAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushMatchallAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_classid(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 1u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn array_act(mut self) -> PushArrayActAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 2u16);
PushArrayActAttrs {
prev: Some(self),
header_offset: Some(header_offset),
counter: 0,
}
}
pub fn push_flags(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 3u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_pcnt(mut self, value: TcMatchallPcnt) -> Self {
push_header(self.as_vec_mut(), 4u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_pad(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 5u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
}
impl<Prev: Pusher> Drop for PushMatchallAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushEtfAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushEtfAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushEtfAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_parms(mut self, value: TcEtfQopt) -> Self {
push_header(self.as_vec_mut(), 1u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
}
impl<Prev: Pusher> Drop for PushEtfAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushEtsAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushEtsAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushEtsAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_nbands(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 1u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_nstrict(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 2u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn nested_quanta(mut self) -> PushEtsAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 3u16);
PushEtsAttrs {
prev: Some(self),
header_offset: Some(header_offset),
}
}
#[doc = "Attribute may repeat multiple times (treat it as array)"]
pub fn push_quanta_band(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 4u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn nested_priomap(mut self) -> PushEtsAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 5u16);
PushEtsAttrs {
prev: Some(self),
header_offset: Some(header_offset),
}
}
#[doc = "Attribute may repeat multiple times (treat it as array)"]
pub fn push_priomap_band(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 6u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushEtsAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushFqAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushFqAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushFqAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
#[doc = "Limit of total number of packets in queue\n"]
pub fn push_plimit(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 1u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
#[doc = "Limit of packets per flow\n"]
pub fn push_flow_plimit(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 2u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
#[doc = "RR quantum\n"]
pub fn push_quantum(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 3u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
#[doc = "RR quantum for new flow\n"]
pub fn push_initial_quantum(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 4u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
#[doc = "Enable / disable rate limiting\n"]
pub fn push_rate_enable(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 5u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
#[doc = "Obsolete, do not use\n"]
pub fn push_flow_default_rate(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 6u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
#[doc = "Per flow max rate\n"]
pub fn push_flow_max_rate(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 7u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
#[doc = "log2(number of buckets)\n"]
pub fn push_buckets_log(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 8u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
#[doc = "Flow credit refill delay in usec\n"]
pub fn push_flow_refill_delay(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 9u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
#[doc = "Mask applied to orphaned skb hashes\n"]
pub fn push_orphan_mask(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 10u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
#[doc = "Per packet delay under this rate\n"]
pub fn push_low_rate_threshold(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 11u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
#[doc = "DCTCP-like CE marking threshold\n"]
pub fn push_ce_threshold(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 12u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_timer_slack(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 13u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
#[doc = "Time horizon in usec\n"]
pub fn push_horizon(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 14u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
#[doc = "Drop packets beyond horizon, or cap their EDT\n"]
pub fn push_horizon_drop(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 15u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_priomap(mut self, value: TcPrioQopt) -> Self {
push_header(self.as_vec_mut(), 16u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
#[doc = "Weights for each band\n"]
pub fn push_weights(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 17u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
}
impl<Prev: Pusher> Drop for PushFqAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushFqCodelAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushFqCodelAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushFqCodelAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_target(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 1u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_limit(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 2u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_interval(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 3u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_ecn(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 4u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_flows(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 5u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_quantum(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 6u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_ce_threshold(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 7u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_drop_batch_size(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 8u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_memory_limit(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 9u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_ce_threshold_selector(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 10u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_ce_threshold_mask(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 11u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushFqCodelAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushFqPieAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushFqPieAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushFqPieAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_limit(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 1u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_flows(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 2u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_target(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 3u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_tupdate(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 4u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_alpha(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 5u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_beta(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 6u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_quantum(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 7u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_memory_limit(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 8u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_ecn_prob(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 9u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_ecn(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 10u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_bytemode(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 11u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_dq_rate_estimator(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 12u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushFqPieAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushNetemAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushNetemAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushNetemAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_corr(mut self, value: TcNetemCorr) -> Self {
push_header(self.as_vec_mut(), 1u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_delay_dist(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 2u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_reorder(mut self, value: TcNetemReorder) -> Self {
push_header(self.as_vec_mut(), 3u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_corrupt(mut self, value: TcNetemCorrupt) -> Self {
push_header(self.as_vec_mut(), 4u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn nested_loss(mut self) -> PushNetemLossAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 5u16);
PushNetemLossAttrs {
prev: Some(self),
header_offset: Some(header_offset),
}
}
pub fn push_rate(mut self, value: TcNetemRate) -> Self {
push_header(self.as_vec_mut(), 6u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_ecn(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 7u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_rate64(mut self, value: u64) -> Self {
push_header(self.as_vec_mut(), 8u16, 8 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_pad(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 9u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_latency64(mut self, value: i64) -> Self {
push_header(self.as_vec_mut(), 10u16, 8 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_jitter64(mut self, value: i64) -> Self {
push_header(self.as_vec_mut(), 11u16, 8 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_slot(mut self, value: TcNetemSlot) -> Self {
push_header(self.as_vec_mut(), 12u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_slot_dist(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 13u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_prng_seed(mut self, value: u64) -> Self {
push_header(self.as_vec_mut(), 14u16, 8 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushNetemAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushNetemLossAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushNetemLossAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushNetemLossAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
#[doc = "General Intuitive - 4 state model\n"]
pub fn push_gi(mut self, value: TcNetemGimodel) -> Self {
push_header(self.as_vec_mut(), 1u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
#[doc = "Gilbert Elliot models\n"]
pub fn push_ge(mut self, value: TcNetemGemodel) -> Self {
push_header(self.as_vec_mut(), 2u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
}
impl<Prev: Pusher> Drop for PushNetemLossAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushPieAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushPieAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushPieAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_target(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 1u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_limit(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 2u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_tupdate(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 3u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_alpha(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 4u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_beta(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 5u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_ecn(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 6u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_bytemode(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 7u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_dq_rate_estimator(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 8u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushPieAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushPoliceAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushPoliceAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushPoliceAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_tbf(mut self, value: TcPolice) -> Self {
push_header(self.as_vec_mut(), 1u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_rate(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 2u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_peakrate(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 3u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_avrate(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 4u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_result(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 5u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_tm(mut self, value: TcfT) -> Self {
push_header(self.as_vec_mut(), 6u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_pad(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 7u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_rate64(mut self, value: u64) -> Self {
push_header(self.as_vec_mut(), 8u16, 8 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_peakrate64(mut self, value: u64) -> Self {
push_header(self.as_vec_mut(), 9u16, 8 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_pktrate64(mut self, value: u64) -> Self {
push_header(self.as_vec_mut(), 10u16, 8 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_pktburst64(mut self, value: u64) -> Self {
push_header(self.as_vec_mut(), 11u16, 8 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushPoliceAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushQfqAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushQfqAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushQfqAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_weight(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 1u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_lmax(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 2u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushQfqAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushRedAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushRedAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushRedAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_parms(mut self, value: TcRedQopt) -> Self {
push_header(self.as_vec_mut(), 1u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_stab(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 2u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_max_p(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 3u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_flags(mut self, value: BuiltinBitfield32) -> Self {
push_header(self.as_vec_mut(), 4u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_early_drop_block(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 5u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_mark_block(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 6u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushRedAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushRouteAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushRouteAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushRouteAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_classid(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 1u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_to(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 2u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_from(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 3u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_iif(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 4u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn nested_police(mut self) -> PushPoliceAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 5u16);
PushPoliceAttrs {
prev: Some(self),
header_offset: Some(header_offset),
}
}
pub fn array_act(mut self) -> PushArrayActAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 6u16);
PushArrayActAttrs {
prev: Some(self),
header_offset: Some(header_offset),
counter: 0,
}
}
}
impl<Prev: Pusher> Drop for PushRouteAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushTaprioAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushTaprioAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushTaprioAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_priomap(mut self, value: TcMqprioQopt) -> Self {
push_header(self.as_vec_mut(), 1u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn nested_sched_entry_list(mut self) -> PushTaprioSchedEntryList<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 2u16);
PushTaprioSchedEntryList {
prev: Some(self),
header_offset: Some(header_offset),
}
}
pub fn push_sched_base_time(mut self, value: i64) -> Self {
push_header(self.as_vec_mut(), 3u16, 8 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn nested_sched_single_entry(mut self) -> PushTaprioSchedEntry<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 4u16);
PushTaprioSchedEntry {
prev: Some(self),
header_offset: Some(header_offset),
}
}
pub fn push_sched_clockid(mut self, value: i32) -> Self {
push_header(self.as_vec_mut(), 5u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_pad(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 6u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_admin_sched(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 7u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_sched_cycle_time(mut self, value: i64) -> Self {
push_header(self.as_vec_mut(), 8u16, 8 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_sched_cycle_time_extension(mut self, value: i64) -> Self {
push_header(self.as_vec_mut(), 9u16, 8 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_flags(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 10u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_txtime_delay(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 11u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn nested_tc_entry(mut self) -> PushTaprioTcEntryAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 12u16);
PushTaprioTcEntryAttrs {
prev: Some(self),
header_offset: Some(header_offset),
}
}
}
impl<Prev: Pusher> Drop for PushTaprioAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushTaprioSchedEntryList<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushTaprioSchedEntryList<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushTaprioSchedEntryList<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
#[doc = "Attribute may repeat multiple times (treat it as array)"]
pub fn nested_entry(mut self) -> PushTaprioSchedEntry<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 1u16);
PushTaprioSchedEntry {
prev: Some(self),
header_offset: Some(header_offset),
}
}
}
impl<Prev: Pusher> Drop for PushTaprioSchedEntryList<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushTaprioSchedEntry<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushTaprioSchedEntry<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushTaprioSchedEntry<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_index(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 1u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_cmd(mut self, value: u8) -> Self {
push_header(self.as_vec_mut(), 2u16, 1 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_gate_mask(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 3u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_interval(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 4u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushTaprioSchedEntry<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushTaprioTcEntryAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushTaprioTcEntryAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushTaprioTcEntryAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_index(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 1u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_max_sdu(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 2u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_fp(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 3u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushTaprioTcEntryAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushTbfAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushTbfAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushTbfAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_parms(mut self, value: TcTbfQopt) -> Self {
push_header(self.as_vec_mut(), 1u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_rtab(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 2u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_ptab(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 3u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_rate64(mut self, value: u64) -> Self {
push_header(self.as_vec_mut(), 4u16, 8 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_prate64(mut self, value: u64) -> Self {
push_header(self.as_vec_mut(), 5u16, 8 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_burst(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 6u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_pburst(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 7u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_pad(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 8u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
}
impl<Prev: Pusher> Drop for PushTbfAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushActSampleAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushActSampleAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushActSampleAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_tm(mut self, value: TcfT) -> Self {
push_header(self.as_vec_mut(), 1u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_parms(mut self, value: TcGact) -> Self {
push_header(self.as_vec_mut(), 2u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_rate(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 3u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_trunc_size(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 4u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_psample_group(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 5u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_pad(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 6u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
}
impl<Prev: Pusher> Drop for PushActSampleAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushActGactAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushActGactAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushActGactAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_tm(mut self, value: TcfT) -> Self {
push_header(self.as_vec_mut(), 1u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_parms(mut self, value: TcGact) -> Self {
push_header(self.as_vec_mut(), 2u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_prob(mut self, value: TcGactP) -> Self {
push_header(self.as_vec_mut(), 3u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_pad(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 4u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
}
impl<Prev: Pusher> Drop for PushActGactAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushTcaStabAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushTcaStabAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushTcaStabAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_base(mut self, value: TcSizespec) -> Self {
push_header(self.as_vec_mut(), 1u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_data(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 2u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
}
impl<Prev: Pusher> Drop for PushTcaStabAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushTcaStatsAttrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushTcaStatsAttrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushTcaStatsAttrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_basic(mut self, value: GnetStatsBasic) -> Self {
push_header(self.as_vec_mut(), 1u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_rate_est(mut self, value: GnetStatsRateEst) -> Self {
push_header(self.as_vec_mut(), 2u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_queue(mut self, value: GnetStatsQueue) -> Self {
push_header(self.as_vec_mut(), 3u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_rate_est64(mut self, value: GnetStatsRateEst64) -> Self {
push_header(self.as_vec_mut(), 5u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_pad(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 6u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
pub fn push_basic_hw(mut self, value: GnetStatsBasic) -> Self {
push_header(self.as_vec_mut(), 7u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_pkt64(mut self, value: u64) -> Self {
push_header(self.as_vec_mut(), 8u16, 8 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
}
impl<Prev: Pusher> Drop for PushTcaStatsAttrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
pub struct PushU32Attrs<Prev: Pusher> {
pub(crate) prev: Option<Prev>,
pub(crate) header_offset: Option<usize>,
}
impl<Prev: Pusher> Pusher for PushU32Attrs<Prev> {
fn as_vec_mut(&mut self) -> &mut Vec<u8> {
self.prev.as_mut().unwrap().as_vec_mut()
}
fn as_vec(&self) -> &Vec<u8> {
self.prev.as_ref().unwrap().as_vec()
}
}
impl<Prev: Pusher> PushU32Attrs<Prev> {
pub fn new(prev: Prev) -> Self {
Self {
prev: Some(prev),
header_offset: None,
}
}
pub fn end_nested(mut self) -> Prev {
let mut prev = self.prev.take().unwrap();
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
prev
}
pub fn push_classid(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 1u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_hash(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 2u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_link(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 3u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_divisor(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 4u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_sel(mut self, value: TcU32Sel) -> Self {
push_header(self.as_vec_mut(), 5u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn nested_police(mut self) -> PushPoliceAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 6u16);
PushPoliceAttrs {
prev: Some(self),
header_offset: Some(header_offset),
}
}
pub fn array_act(mut self) -> PushArrayActAttrs<Self> {
let header_offset = push_nested_header(self.as_vec_mut(), 7u16);
PushArrayActAttrs {
prev: Some(self),
header_offset: Some(header_offset),
counter: 0,
}
}
pub fn push_indev(mut self, value: &CStr) -> Self {
push_header(
self.as_vec_mut(),
8u16,
value.to_bytes_with_nul().len() as u16,
);
self.as_vec_mut().extend(value.to_bytes_with_nul());
self
}
pub fn push_indev_bytes(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 8u16, (value.len() + 1) as u16);
self.as_vec_mut().extend(value);
self.as_vec_mut().push(0);
self
}
pub fn push_pcnt(mut self, value: TcU32Pcnt) -> Self {
push_header(self.as_vec_mut(), 9u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_mark(mut self, value: TcU32Mark) -> Self {
push_header(self.as_vec_mut(), 10u16, value.as_slice().len() as u16);
self.as_vec_mut().extend(value.as_slice());
self
}
pub fn push_flags(mut self, value: u32) -> Self {
push_header(self.as_vec_mut(), 11u16, 4 as u16);
self.as_vec_mut().extend(value.to_ne_bytes());
self
}
pub fn push_pad(mut self, value: &[u8]) -> Self {
push_header(self.as_vec_mut(), 12u16, value.len() as u16);
self.as_vec_mut().extend(value);
self
}
}
impl<Prev: Pusher> Drop for PushU32Attrs<Prev> {
fn drop(&mut self) {
if let Some(prev) = &mut self.prev {
if let Some(header_offset) = &self.header_offset {
finalize_nested_header(prev.as_vec_mut(), *header_offset);
}
}
}
}
#[doc = "Create new tc qdisc.\n\nRequest attributes:\n- [.push_kind()](PushAttrs::push_kind)\n- [.nested_options_basic()](PushAttrs::nested_options_basic)\n- [.nested_options_bpf()](PushAttrs::nested_options_bpf)\n- [.nested_options_bfifo()](PushAttrs::nested_options_bfifo)\n- [.nested_options_cake()](PushAttrs::nested_options_cake)\n- [.nested_options_cbs()](PushAttrs::nested_options_cbs)\n- [.nested_options_cgroup()](PushAttrs::nested_options_cgroup)\n- [.nested_options_choke()](PushAttrs::nested_options_choke)\n- [.nested_options_clsact()](PushAttrs::nested_options_clsact)\n- [.nested_options_codel()](PushAttrs::nested_options_codel)\n- [.nested_options_drr()](PushAttrs::nested_options_drr)\n- [.nested_options_dualpi2()](PushAttrs::nested_options_dualpi2)\n- [.nested_options_etf()](PushAttrs::nested_options_etf)\n- [.nested_options_ets()](PushAttrs::nested_options_ets)\n- [.nested_options_flow()](PushAttrs::nested_options_flow)\n- [.nested_options_flower()](PushAttrs::nested_options_flower)\n- [.nested_options_fq()](PushAttrs::nested_options_fq)\n- [.nested_options_fq_codel()](PushAttrs::nested_options_fq_codel)\n- [.nested_options_fq_pie()](PushAttrs::nested_options_fq_pie)\n- [.nested_options_fw()](PushAttrs::nested_options_fw)\n- [.nested_options_gred()](PushAttrs::nested_options_gred)\n- [.nested_options_hfsc()](PushAttrs::nested_options_hfsc)\n- [.nested_options_hhf()](PushAttrs::nested_options_hhf)\n- [.nested_options_htb()](PushAttrs::nested_options_htb)\n- [.nested_options_ingress()](PushAttrs::nested_options_ingress)\n- [.nested_options_matchall()](PushAttrs::nested_options_matchall)\n- [.nested_options_mq()](PushAttrs::nested_options_mq)\n- [.nested_options_mqprio()](PushAttrs::nested_options_mqprio)\n- [.nested_options_multiq()](PushAttrs::nested_options_multiq)\n- [.nested_options_netem()](PushAttrs::nested_options_netem)\n- [.nested_options_pfifo()](PushAttrs::nested_options_pfifo)\n- [.nested_options_pfifo_fast()](PushAttrs::nested_options_pfifo_fast)\n- [.nested_options_pfifo_head_drop()](PushAttrs::nested_options_pfifo_head_drop)\n- [.nested_options_pie()](PushAttrs::nested_options_pie)\n- [.nested_options_plug()](PushAttrs::nested_options_plug)\n- [.nested_options_prio()](PushAttrs::nested_options_prio)\n- [.nested_options_qfq()](PushAttrs::nested_options_qfq)\n- [.nested_options_red()](PushAttrs::nested_options_red)\n- [.nested_options_route()](PushAttrs::nested_options_route)\n- [.nested_options_sfb()](PushAttrs::nested_options_sfb)\n- [.nested_options_sfq()](PushAttrs::nested_options_sfq)\n- [.nested_options_taprio()](PushAttrs::nested_options_taprio)\n- [.nested_options_tbf()](PushAttrs::nested_options_tbf)\n- [.nested_options_u32()](PushAttrs::nested_options_u32)\n- [.push_rate()](PushAttrs::push_rate)\n- [.push_chain()](PushAttrs::push_chain)\n- [.push_ingress_block()](PushAttrs::push_ingress_block)\n- [.push_egress_block()](PushAttrs::push_egress_block)\n\n"]
#[derive(Debug)]
pub struct OpNewqdiscDo<'r> {
request: Request<'r>,
}
impl<'r> OpNewqdiscDo<'r> {
pub fn new(mut request: Request<'r>, header: &Tcmsg) -> Self {
Self::write_header(request.buf_mut(), header);
Self { request: request }
}
pub fn encode_request<'buf>(
buf: &'buf mut Vec<u8>,
header: &Tcmsg,
) -> PushAttrs<&'buf mut Vec<u8>> {
Self::write_header(buf, header);
PushAttrs::new(buf)
}
pub fn encode(&mut self) -> PushAttrs<&mut Vec<u8>> {
PushAttrs::new(self.request.buf_mut())
}
pub fn into_encoder(self) -> PushAttrs<RequestBuf<'r>> {
PushAttrs::new(self.request.buf)
}
pub fn decode_request<'a>(buf: &'a [u8]) -> (Tcmsg, IterableAttrs<'a>) {
let (header, attrs) = buf.split_at(buf.len().min(Tcmsg::len()));
(
Tcmsg::new_from_slice(header).unwrap_or_default(),
IterableAttrs::with_loc(attrs, buf.as_ptr() as usize),
)
}
fn write_header<Prev: Pusher>(prev: &mut Prev, header: &Tcmsg) {
prev.as_vec_mut().extend(header.as_slice());
}
}
impl NetlinkRequest for OpNewqdiscDo<'_> {
fn protocol(&self) -> Protocol {
Protocol::Raw {
protonum: 0u16,
request_type: 36u16,
}
}
fn flags(&self) -> u16 {
self.request.flags
}
fn payload(&self) -> &[u8] {
self.request.buf()
}
type ReplyType<'buf> = (Tcmsg, IterableAttrs<'buf>);
fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
Self::decode_request(buf)
}
fn lookup(
buf: &[u8],
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
Self::decode_request(buf)
.1
.lookup_attr(offset, missing_type)
}
}
#[doc = "Delete existing tc qdisc.\n\n"]
#[derive(Debug)]
pub struct OpDelqdiscDo<'r> {
request: Request<'r>,
}
impl<'r> OpDelqdiscDo<'r> {
pub fn new(mut request: Request<'r>, header: &Tcmsg) -> Self {
Self::write_header(request.buf_mut(), header);
Self { request: request }
}
pub fn encode_request<'buf>(
buf: &'buf mut Vec<u8>,
header: &Tcmsg,
) -> PushAttrs<&'buf mut Vec<u8>> {
Self::write_header(buf, header);
PushAttrs::new(buf)
}
pub fn encode(&mut self) -> PushAttrs<&mut Vec<u8>> {
PushAttrs::new(self.request.buf_mut())
}
pub fn into_encoder(self) -> PushAttrs<RequestBuf<'r>> {
PushAttrs::new(self.request.buf)
}
pub fn decode_request<'a>(buf: &'a [u8]) -> (Tcmsg, IterableAttrs<'a>) {
let (header, attrs) = buf.split_at(buf.len().min(Tcmsg::len()));
(
Tcmsg::new_from_slice(header).unwrap_or_default(),
IterableAttrs::with_loc(attrs, buf.as_ptr() as usize),
)
}
fn write_header<Prev: Pusher>(prev: &mut Prev, header: &Tcmsg) {
prev.as_vec_mut().extend(header.as_slice());
}
}
impl NetlinkRequest for OpDelqdiscDo<'_> {
fn protocol(&self) -> Protocol {
Protocol::Raw {
protonum: 0u16,
request_type: 37u16,
}
}
fn flags(&self) -> u16 {
self.request.flags
}
fn payload(&self) -> &[u8] {
self.request.buf()
}
type ReplyType<'buf> = (Tcmsg, IterableAttrs<'buf>);
fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
Self::decode_request(buf)
}
fn lookup(
buf: &[u8],
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
Self::decode_request(buf)
.1
.lookup_attr(offset, missing_type)
}
}
#[doc = "Get / dump tc qdisc information.\n\nRequest attributes:\n- [.push_dump_invisible()](PushAttrs::push_dump_invisible)\n\nReply attributes:\n- [.get_kind()](IterableAttrs::get_kind)\n- [.get_options()](IterableAttrs::get_options)\n- [.get_stats()](IterableAttrs::get_stats)\n- [.get_xstats()](IterableAttrs::get_xstats)\n- [.get_rate()](IterableAttrs::get_rate)\n- [.get_fcnt()](IterableAttrs::get_fcnt)\n- [.get_stats2()](IterableAttrs::get_stats2)\n- [.get_stab()](IterableAttrs::get_stab)\n- [.get_chain()](IterableAttrs::get_chain)\n- [.get_ingress_block()](IterableAttrs::get_ingress_block)\n- [.get_egress_block()](IterableAttrs::get_egress_block)\n\n"]
#[derive(Debug)]
pub struct OpGetqdiscDump<'r> {
request: Request<'r>,
}
impl<'r> OpGetqdiscDump<'r> {
pub fn new(mut request: Request<'r>, header: &Tcmsg) -> Self {
Self::write_header(request.buf_mut(), header);
Self {
request: request.set_dump(),
}
}
pub fn encode_request<'buf>(
buf: &'buf mut Vec<u8>,
header: &Tcmsg,
) -> PushAttrs<&'buf mut Vec<u8>> {
Self::write_header(buf, header);
PushAttrs::new(buf)
}
pub fn encode(&mut self) -> PushAttrs<&mut Vec<u8>> {
PushAttrs::new(self.request.buf_mut())
}
pub fn into_encoder(self) -> PushAttrs<RequestBuf<'r>> {
PushAttrs::new(self.request.buf)
}
pub fn decode_request<'a>(buf: &'a [u8]) -> (Tcmsg, IterableAttrs<'a>) {
let (header, attrs) = buf.split_at(buf.len().min(Tcmsg::len()));
(
Tcmsg::new_from_slice(header).unwrap_or_default(),
IterableAttrs::with_loc(attrs, buf.as_ptr() as usize),
)
}
fn write_header<Prev: Pusher>(prev: &mut Prev, header: &Tcmsg) {
prev.as_vec_mut().extend(header.as_slice());
}
}
impl NetlinkRequest for OpGetqdiscDump<'_> {
fn protocol(&self) -> Protocol {
Protocol::Raw {
protonum: 0u16,
request_type: 38u16,
}
}
fn flags(&self) -> u16 {
self.request.flags
}
fn payload(&self) -> &[u8] {
self.request.buf()
}
type ReplyType<'buf> = (Tcmsg, IterableAttrs<'buf>);
fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
Self::decode_request(buf)
}
fn lookup(
buf: &[u8],
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
Self::decode_request(buf)
.1
.lookup_attr(offset, missing_type)
}
}
#[doc = "Get / dump tc qdisc information.\n\nRequest attributes:\n- [.push_dump_invisible()](PushAttrs::push_dump_invisible)\n\nReply attributes:\n- [.get_kind()](IterableAttrs::get_kind)\n- [.get_options()](IterableAttrs::get_options)\n- [.get_stats()](IterableAttrs::get_stats)\n- [.get_xstats()](IterableAttrs::get_xstats)\n- [.get_rate()](IterableAttrs::get_rate)\n- [.get_fcnt()](IterableAttrs::get_fcnt)\n- [.get_stats2()](IterableAttrs::get_stats2)\n- [.get_stab()](IterableAttrs::get_stab)\n- [.get_chain()](IterableAttrs::get_chain)\n- [.get_ingress_block()](IterableAttrs::get_ingress_block)\n- [.get_egress_block()](IterableAttrs::get_egress_block)\n\n"]
#[derive(Debug)]
pub struct OpGetqdiscDo<'r> {
request: Request<'r>,
}
impl<'r> OpGetqdiscDo<'r> {
pub fn new(mut request: Request<'r>, header: &Tcmsg) -> Self {
Self::write_header(request.buf_mut(), header);
Self { request: request }
}
pub fn encode_request<'buf>(
buf: &'buf mut Vec<u8>,
header: &Tcmsg,
) -> PushAttrs<&'buf mut Vec<u8>> {
Self::write_header(buf, header);
PushAttrs::new(buf)
}
pub fn encode(&mut self) -> PushAttrs<&mut Vec<u8>> {
PushAttrs::new(self.request.buf_mut())
}
pub fn into_encoder(self) -> PushAttrs<RequestBuf<'r>> {
PushAttrs::new(self.request.buf)
}
pub fn decode_request<'a>(buf: &'a [u8]) -> (Tcmsg, IterableAttrs<'a>) {
let (header, attrs) = buf.split_at(buf.len().min(Tcmsg::len()));
(
Tcmsg::new_from_slice(header).unwrap_or_default(),
IterableAttrs::with_loc(attrs, buf.as_ptr() as usize),
)
}
fn write_header<Prev: Pusher>(prev: &mut Prev, header: &Tcmsg) {
prev.as_vec_mut().extend(header.as_slice());
}
}
impl NetlinkRequest for OpGetqdiscDo<'_> {
fn protocol(&self) -> Protocol {
Protocol::Raw {
protonum: 0u16,
request_type: 38u16,
}
}
fn flags(&self) -> u16 {
self.request.flags
}
fn payload(&self) -> &[u8] {
self.request.buf()
}
type ReplyType<'buf> = (Tcmsg, IterableAttrs<'buf>);
fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
Self::decode_request(buf)
}
fn lookup(
buf: &[u8],
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
Self::decode_request(buf)
.1
.lookup_attr(offset, missing_type)
}
}
#[doc = "Get / dump tc traffic class information.\n\nRequest attributes:\n- [.push_kind()](PushAttrs::push_kind)\n- [.nested_options_basic()](PushAttrs::nested_options_basic)\n- [.nested_options_bpf()](PushAttrs::nested_options_bpf)\n- [.nested_options_bfifo()](PushAttrs::nested_options_bfifo)\n- [.nested_options_cake()](PushAttrs::nested_options_cake)\n- [.nested_options_cbs()](PushAttrs::nested_options_cbs)\n- [.nested_options_cgroup()](PushAttrs::nested_options_cgroup)\n- [.nested_options_choke()](PushAttrs::nested_options_choke)\n- [.nested_options_clsact()](PushAttrs::nested_options_clsact)\n- [.nested_options_codel()](PushAttrs::nested_options_codel)\n- [.nested_options_drr()](PushAttrs::nested_options_drr)\n- [.nested_options_dualpi2()](PushAttrs::nested_options_dualpi2)\n- [.nested_options_etf()](PushAttrs::nested_options_etf)\n- [.nested_options_ets()](PushAttrs::nested_options_ets)\n- [.nested_options_flow()](PushAttrs::nested_options_flow)\n- [.nested_options_flower()](PushAttrs::nested_options_flower)\n- [.nested_options_fq()](PushAttrs::nested_options_fq)\n- [.nested_options_fq_codel()](PushAttrs::nested_options_fq_codel)\n- [.nested_options_fq_pie()](PushAttrs::nested_options_fq_pie)\n- [.nested_options_fw()](PushAttrs::nested_options_fw)\n- [.nested_options_gred()](PushAttrs::nested_options_gred)\n- [.nested_options_hfsc()](PushAttrs::nested_options_hfsc)\n- [.nested_options_hhf()](PushAttrs::nested_options_hhf)\n- [.nested_options_htb()](PushAttrs::nested_options_htb)\n- [.nested_options_ingress()](PushAttrs::nested_options_ingress)\n- [.nested_options_matchall()](PushAttrs::nested_options_matchall)\n- [.nested_options_mq()](PushAttrs::nested_options_mq)\n- [.nested_options_mqprio()](PushAttrs::nested_options_mqprio)\n- [.nested_options_multiq()](PushAttrs::nested_options_multiq)\n- [.nested_options_netem()](PushAttrs::nested_options_netem)\n- [.nested_options_pfifo()](PushAttrs::nested_options_pfifo)\n- [.nested_options_pfifo_fast()](PushAttrs::nested_options_pfifo_fast)\n- [.nested_options_pfifo_head_drop()](PushAttrs::nested_options_pfifo_head_drop)\n- [.nested_options_pie()](PushAttrs::nested_options_pie)\n- [.nested_options_plug()](PushAttrs::nested_options_plug)\n- [.nested_options_prio()](PushAttrs::nested_options_prio)\n- [.nested_options_qfq()](PushAttrs::nested_options_qfq)\n- [.nested_options_red()](PushAttrs::nested_options_red)\n- [.nested_options_route()](PushAttrs::nested_options_route)\n- [.nested_options_sfb()](PushAttrs::nested_options_sfb)\n- [.nested_options_sfq()](PushAttrs::nested_options_sfq)\n- [.nested_options_taprio()](PushAttrs::nested_options_taprio)\n- [.nested_options_tbf()](PushAttrs::nested_options_tbf)\n- [.nested_options_u32()](PushAttrs::nested_options_u32)\n- [.push_rate()](PushAttrs::push_rate)\n- [.push_chain()](PushAttrs::push_chain)\n- [.push_ingress_block()](PushAttrs::push_ingress_block)\n- [.push_egress_block()](PushAttrs::push_egress_block)\n\n"]
#[derive(Debug)]
pub struct OpNewtclassDo<'r> {
request: Request<'r>,
}
impl<'r> OpNewtclassDo<'r> {
pub fn new(mut request: Request<'r>, header: &Tcmsg) -> Self {
Self::write_header(request.buf_mut(), header);
Self { request: request }
}
pub fn encode_request<'buf>(
buf: &'buf mut Vec<u8>,
header: &Tcmsg,
) -> PushAttrs<&'buf mut Vec<u8>> {
Self::write_header(buf, header);
PushAttrs::new(buf)
}
pub fn encode(&mut self) -> PushAttrs<&mut Vec<u8>> {
PushAttrs::new(self.request.buf_mut())
}
pub fn into_encoder(self) -> PushAttrs<RequestBuf<'r>> {
PushAttrs::new(self.request.buf)
}
pub fn decode_request<'a>(buf: &'a [u8]) -> (Tcmsg, IterableAttrs<'a>) {
let (header, attrs) = buf.split_at(buf.len().min(Tcmsg::len()));
(
Tcmsg::new_from_slice(header).unwrap_or_default(),
IterableAttrs::with_loc(attrs, buf.as_ptr() as usize),
)
}
fn write_header<Prev: Pusher>(prev: &mut Prev, header: &Tcmsg) {
prev.as_vec_mut().extend(header.as_slice());
}
}
impl NetlinkRequest for OpNewtclassDo<'_> {
fn protocol(&self) -> Protocol {
Protocol::Raw {
protonum: 0u16,
request_type: 40u16,
}
}
fn flags(&self) -> u16 {
self.request.flags
}
fn payload(&self) -> &[u8] {
self.request.buf()
}
type ReplyType<'buf> = (Tcmsg, IterableAttrs<'buf>);
fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
Self::decode_request(buf)
}
fn lookup(
buf: &[u8],
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
Self::decode_request(buf)
.1
.lookup_attr(offset, missing_type)
}
}
#[doc = "Get / dump tc traffic class information.\n\n"]
#[derive(Debug)]
pub struct OpDeltclassDo<'r> {
request: Request<'r>,
}
impl<'r> OpDeltclassDo<'r> {
pub fn new(mut request: Request<'r>, header: &Tcmsg) -> Self {
Self::write_header(request.buf_mut(), header);
Self { request: request }
}
pub fn encode_request<'buf>(
buf: &'buf mut Vec<u8>,
header: &Tcmsg,
) -> PushAttrs<&'buf mut Vec<u8>> {
Self::write_header(buf, header);
PushAttrs::new(buf)
}
pub fn encode(&mut self) -> PushAttrs<&mut Vec<u8>> {
PushAttrs::new(self.request.buf_mut())
}
pub fn into_encoder(self) -> PushAttrs<RequestBuf<'r>> {
PushAttrs::new(self.request.buf)
}
pub fn decode_request<'a>(buf: &'a [u8]) -> (Tcmsg, IterableAttrs<'a>) {
let (header, attrs) = buf.split_at(buf.len().min(Tcmsg::len()));
(
Tcmsg::new_from_slice(header).unwrap_or_default(),
IterableAttrs::with_loc(attrs, buf.as_ptr() as usize),
)
}
fn write_header<Prev: Pusher>(prev: &mut Prev, header: &Tcmsg) {
prev.as_vec_mut().extend(header.as_slice());
}
}
impl NetlinkRequest for OpDeltclassDo<'_> {
fn protocol(&self) -> Protocol {
Protocol::Raw {
protonum: 0u16,
request_type: 41u16,
}
}
fn flags(&self) -> u16 {
self.request.flags
}
fn payload(&self) -> &[u8] {
self.request.buf()
}
type ReplyType<'buf> = (Tcmsg, IterableAttrs<'buf>);
fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
Self::decode_request(buf)
}
fn lookup(
buf: &[u8],
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
Self::decode_request(buf)
.1
.lookup_attr(offset, missing_type)
}
}
#[doc = "Get / dump tc traffic class information.\n\nReply attributes:\n- [.get_kind()](IterableAttrs::get_kind)\n- [.get_options()](IterableAttrs::get_options)\n- [.get_stats()](IterableAttrs::get_stats)\n- [.get_xstats()](IterableAttrs::get_xstats)\n- [.get_rate()](IterableAttrs::get_rate)\n- [.get_fcnt()](IterableAttrs::get_fcnt)\n- [.get_stats2()](IterableAttrs::get_stats2)\n- [.get_stab()](IterableAttrs::get_stab)\n- [.get_chain()](IterableAttrs::get_chain)\n- [.get_ingress_block()](IterableAttrs::get_ingress_block)\n- [.get_egress_block()](IterableAttrs::get_egress_block)\n\n"]
#[derive(Debug)]
pub struct OpGettclassDo<'r> {
request: Request<'r>,
}
impl<'r> OpGettclassDo<'r> {
pub fn new(mut request: Request<'r>, header: &Tcmsg) -> Self {
Self::write_header(request.buf_mut(), header);
Self { request: request }
}
pub fn encode_request<'buf>(
buf: &'buf mut Vec<u8>,
header: &Tcmsg,
) -> PushAttrs<&'buf mut Vec<u8>> {
Self::write_header(buf, header);
PushAttrs::new(buf)
}
pub fn encode(&mut self) -> PushAttrs<&mut Vec<u8>> {
PushAttrs::new(self.request.buf_mut())
}
pub fn into_encoder(self) -> PushAttrs<RequestBuf<'r>> {
PushAttrs::new(self.request.buf)
}
pub fn decode_request<'a>(buf: &'a [u8]) -> (Tcmsg, IterableAttrs<'a>) {
let (header, attrs) = buf.split_at(buf.len().min(Tcmsg::len()));
(
Tcmsg::new_from_slice(header).unwrap_or_default(),
IterableAttrs::with_loc(attrs, buf.as_ptr() as usize),
)
}
fn write_header<Prev: Pusher>(prev: &mut Prev, header: &Tcmsg) {
prev.as_vec_mut().extend(header.as_slice());
}
}
impl NetlinkRequest for OpGettclassDo<'_> {
fn protocol(&self) -> Protocol {
Protocol::Raw {
protonum: 0u16,
request_type: 42u16,
}
}
fn flags(&self) -> u16 {
self.request.flags
}
fn payload(&self) -> &[u8] {
self.request.buf()
}
type ReplyType<'buf> = (Tcmsg, IterableAttrs<'buf>);
fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
Self::decode_request(buf)
}
fn lookup(
buf: &[u8],
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
Self::decode_request(buf)
.1
.lookup_attr(offset, missing_type)
}
}
#[doc = "Get / dump tc filter information.\n\nRequest attributes:\n- [.push_kind()](PushAttrs::push_kind)\n- [.nested_options_basic()](PushAttrs::nested_options_basic)\n- [.nested_options_bpf()](PushAttrs::nested_options_bpf)\n- [.nested_options_bfifo()](PushAttrs::nested_options_bfifo)\n- [.nested_options_cake()](PushAttrs::nested_options_cake)\n- [.nested_options_cbs()](PushAttrs::nested_options_cbs)\n- [.nested_options_cgroup()](PushAttrs::nested_options_cgroup)\n- [.nested_options_choke()](PushAttrs::nested_options_choke)\n- [.nested_options_clsact()](PushAttrs::nested_options_clsact)\n- [.nested_options_codel()](PushAttrs::nested_options_codel)\n- [.nested_options_drr()](PushAttrs::nested_options_drr)\n- [.nested_options_dualpi2()](PushAttrs::nested_options_dualpi2)\n- [.nested_options_etf()](PushAttrs::nested_options_etf)\n- [.nested_options_ets()](PushAttrs::nested_options_ets)\n- [.nested_options_flow()](PushAttrs::nested_options_flow)\n- [.nested_options_flower()](PushAttrs::nested_options_flower)\n- [.nested_options_fq()](PushAttrs::nested_options_fq)\n- [.nested_options_fq_codel()](PushAttrs::nested_options_fq_codel)\n- [.nested_options_fq_pie()](PushAttrs::nested_options_fq_pie)\n- [.nested_options_fw()](PushAttrs::nested_options_fw)\n- [.nested_options_gred()](PushAttrs::nested_options_gred)\n- [.nested_options_hfsc()](PushAttrs::nested_options_hfsc)\n- [.nested_options_hhf()](PushAttrs::nested_options_hhf)\n- [.nested_options_htb()](PushAttrs::nested_options_htb)\n- [.nested_options_ingress()](PushAttrs::nested_options_ingress)\n- [.nested_options_matchall()](PushAttrs::nested_options_matchall)\n- [.nested_options_mq()](PushAttrs::nested_options_mq)\n- [.nested_options_mqprio()](PushAttrs::nested_options_mqprio)\n- [.nested_options_multiq()](PushAttrs::nested_options_multiq)\n- [.nested_options_netem()](PushAttrs::nested_options_netem)\n- [.nested_options_pfifo()](PushAttrs::nested_options_pfifo)\n- [.nested_options_pfifo_fast()](PushAttrs::nested_options_pfifo_fast)\n- [.nested_options_pfifo_head_drop()](PushAttrs::nested_options_pfifo_head_drop)\n- [.nested_options_pie()](PushAttrs::nested_options_pie)\n- [.nested_options_plug()](PushAttrs::nested_options_plug)\n- [.nested_options_prio()](PushAttrs::nested_options_prio)\n- [.nested_options_qfq()](PushAttrs::nested_options_qfq)\n- [.nested_options_red()](PushAttrs::nested_options_red)\n- [.nested_options_route()](PushAttrs::nested_options_route)\n- [.nested_options_sfb()](PushAttrs::nested_options_sfb)\n- [.nested_options_sfq()](PushAttrs::nested_options_sfq)\n- [.nested_options_taprio()](PushAttrs::nested_options_taprio)\n- [.nested_options_tbf()](PushAttrs::nested_options_tbf)\n- [.nested_options_u32()](PushAttrs::nested_options_u32)\n- [.push_rate()](PushAttrs::push_rate)\n- [.push_chain()](PushAttrs::push_chain)\n- [.push_ingress_block()](PushAttrs::push_ingress_block)\n- [.push_egress_block()](PushAttrs::push_egress_block)\n\n"]
#[derive(Debug)]
pub struct OpNewtfilterDo<'r> {
request: Request<'r>,
}
impl<'r> OpNewtfilterDo<'r> {
pub fn new(mut request: Request<'r>, header: &Tcmsg) -> Self {
Self::write_header(request.buf_mut(), header);
Self { request: request }
}
pub fn encode_request<'buf>(
buf: &'buf mut Vec<u8>,
header: &Tcmsg,
) -> PushAttrs<&'buf mut Vec<u8>> {
Self::write_header(buf, header);
PushAttrs::new(buf)
}
pub fn encode(&mut self) -> PushAttrs<&mut Vec<u8>> {
PushAttrs::new(self.request.buf_mut())
}
pub fn into_encoder(self) -> PushAttrs<RequestBuf<'r>> {
PushAttrs::new(self.request.buf)
}
pub fn decode_request<'a>(buf: &'a [u8]) -> (Tcmsg, IterableAttrs<'a>) {
let (header, attrs) = buf.split_at(buf.len().min(Tcmsg::len()));
(
Tcmsg::new_from_slice(header).unwrap_or_default(),
IterableAttrs::with_loc(attrs, buf.as_ptr() as usize),
)
}
fn write_header<Prev: Pusher>(prev: &mut Prev, header: &Tcmsg) {
prev.as_vec_mut().extend(header.as_slice());
}
}
impl NetlinkRequest for OpNewtfilterDo<'_> {
fn protocol(&self) -> Protocol {
Protocol::Raw {
protonum: 0u16,
request_type: 44u16,
}
}
fn flags(&self) -> u16 {
self.request.flags
}
fn payload(&self) -> &[u8] {
self.request.buf()
}
type ReplyType<'buf> = (Tcmsg, IterableAttrs<'buf>);
fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
Self::decode_request(buf)
}
fn lookup(
buf: &[u8],
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
Self::decode_request(buf)
.1
.lookup_attr(offset, missing_type)
}
}
#[doc = "Get / dump tc filter information.\n\nRequest attributes:\n- [.push_kind()](PushAttrs::push_kind)\n- [.push_chain()](PushAttrs::push_chain)\n\n"]
#[derive(Debug)]
pub struct OpDeltfilterDo<'r> {
request: Request<'r>,
}
impl<'r> OpDeltfilterDo<'r> {
pub fn new(mut request: Request<'r>, header: &Tcmsg) -> Self {
Self::write_header(request.buf_mut(), header);
Self { request: request }
}
pub fn encode_request<'buf>(
buf: &'buf mut Vec<u8>,
header: &Tcmsg,
) -> PushAttrs<&'buf mut Vec<u8>> {
Self::write_header(buf, header);
PushAttrs::new(buf)
}
pub fn encode(&mut self) -> PushAttrs<&mut Vec<u8>> {
PushAttrs::new(self.request.buf_mut())
}
pub fn into_encoder(self) -> PushAttrs<RequestBuf<'r>> {
PushAttrs::new(self.request.buf)
}
pub fn decode_request<'a>(buf: &'a [u8]) -> (Tcmsg, IterableAttrs<'a>) {
let (header, attrs) = buf.split_at(buf.len().min(Tcmsg::len()));
(
Tcmsg::new_from_slice(header).unwrap_or_default(),
IterableAttrs::with_loc(attrs, buf.as_ptr() as usize),
)
}
fn write_header<Prev: Pusher>(prev: &mut Prev, header: &Tcmsg) {
prev.as_vec_mut().extend(header.as_slice());
}
}
impl NetlinkRequest for OpDeltfilterDo<'_> {
fn protocol(&self) -> Protocol {
Protocol::Raw {
protonum: 0u16,
request_type: 45u16,
}
}
fn flags(&self) -> u16 {
self.request.flags
}
fn payload(&self) -> &[u8] {
self.request.buf()
}
type ReplyType<'buf> = (Tcmsg, IterableAttrs<'buf>);
fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
Self::decode_request(buf)
}
fn lookup(
buf: &[u8],
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
Self::decode_request(buf)
.1
.lookup_attr(offset, missing_type)
}
}
#[doc = "Get / dump tc filter information.\n\nRequest attributes:\n- [.push_chain()](PushAttrs::push_chain)\n- [.push_dump_flags()](PushAttrs::push_dump_flags)\n\nReply attributes:\n- [.get_kind()](IterableAttrs::get_kind)\n- [.get_options()](IterableAttrs::get_options)\n- [.get_stats()](IterableAttrs::get_stats)\n- [.get_xstats()](IterableAttrs::get_xstats)\n- [.get_rate()](IterableAttrs::get_rate)\n- [.get_fcnt()](IterableAttrs::get_fcnt)\n- [.get_stats2()](IterableAttrs::get_stats2)\n- [.get_stab()](IterableAttrs::get_stab)\n- [.get_chain()](IterableAttrs::get_chain)\n- [.get_ingress_block()](IterableAttrs::get_ingress_block)\n- [.get_egress_block()](IterableAttrs::get_egress_block)\n\n"]
#[derive(Debug)]
pub struct OpGettfilterDump<'r> {
request: Request<'r>,
}
impl<'r> OpGettfilterDump<'r> {
pub fn new(mut request: Request<'r>, header: &Tcmsg) -> Self {
Self::write_header(request.buf_mut(), header);
Self {
request: request.set_dump(),
}
}
pub fn encode_request<'buf>(
buf: &'buf mut Vec<u8>,
header: &Tcmsg,
) -> PushAttrs<&'buf mut Vec<u8>> {
Self::write_header(buf, header);
PushAttrs::new(buf)
}
pub fn encode(&mut self) -> PushAttrs<&mut Vec<u8>> {
PushAttrs::new(self.request.buf_mut())
}
pub fn into_encoder(self) -> PushAttrs<RequestBuf<'r>> {
PushAttrs::new(self.request.buf)
}
pub fn decode_request<'a>(buf: &'a [u8]) -> (Tcmsg, IterableAttrs<'a>) {
let (header, attrs) = buf.split_at(buf.len().min(Tcmsg::len()));
(
Tcmsg::new_from_slice(header).unwrap_or_default(),
IterableAttrs::with_loc(attrs, buf.as_ptr() as usize),
)
}
fn write_header<Prev: Pusher>(prev: &mut Prev, header: &Tcmsg) {
prev.as_vec_mut().extend(header.as_slice());
}
}
impl NetlinkRequest for OpGettfilterDump<'_> {
fn protocol(&self) -> Protocol {
Protocol::Raw {
protonum: 0u16,
request_type: 46u16,
}
}
fn flags(&self) -> u16 {
self.request.flags
}
fn payload(&self) -> &[u8] {
self.request.buf()
}
type ReplyType<'buf> = (Tcmsg, IterableAttrs<'buf>);
fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
Self::decode_request(buf)
}
fn lookup(
buf: &[u8],
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
Self::decode_request(buf)
.1
.lookup_attr(offset, missing_type)
}
}
#[doc = "Get / dump tc filter information.\n\nRequest attributes:\n- [.push_kind()](PushAttrs::push_kind)\n- [.push_chain()](PushAttrs::push_chain)\n\nReply attributes:\n- [.get_kind()](IterableAttrs::get_kind)\n- [.get_options()](IterableAttrs::get_options)\n- [.get_stats()](IterableAttrs::get_stats)\n- [.get_xstats()](IterableAttrs::get_xstats)\n- [.get_rate()](IterableAttrs::get_rate)\n- [.get_fcnt()](IterableAttrs::get_fcnt)\n- [.get_stats2()](IterableAttrs::get_stats2)\n- [.get_stab()](IterableAttrs::get_stab)\n- [.get_chain()](IterableAttrs::get_chain)\n- [.get_ingress_block()](IterableAttrs::get_ingress_block)\n- [.get_egress_block()](IterableAttrs::get_egress_block)\n\n"]
#[derive(Debug)]
pub struct OpGettfilterDo<'r> {
request: Request<'r>,
}
impl<'r> OpGettfilterDo<'r> {
pub fn new(mut request: Request<'r>, header: &Tcmsg) -> Self {
Self::write_header(request.buf_mut(), header);
Self { request: request }
}
pub fn encode_request<'buf>(
buf: &'buf mut Vec<u8>,
header: &Tcmsg,
) -> PushAttrs<&'buf mut Vec<u8>> {
Self::write_header(buf, header);
PushAttrs::new(buf)
}
pub fn encode(&mut self) -> PushAttrs<&mut Vec<u8>> {
PushAttrs::new(self.request.buf_mut())
}
pub fn into_encoder(self) -> PushAttrs<RequestBuf<'r>> {
PushAttrs::new(self.request.buf)
}
pub fn decode_request<'a>(buf: &'a [u8]) -> (Tcmsg, IterableAttrs<'a>) {
let (header, attrs) = buf.split_at(buf.len().min(Tcmsg::len()));
(
Tcmsg::new_from_slice(header).unwrap_or_default(),
IterableAttrs::with_loc(attrs, buf.as_ptr() as usize),
)
}
fn write_header<Prev: Pusher>(prev: &mut Prev, header: &Tcmsg) {
prev.as_vec_mut().extend(header.as_slice());
}
}
impl NetlinkRequest for OpGettfilterDo<'_> {
fn protocol(&self) -> Protocol {
Protocol::Raw {
protonum: 0u16,
request_type: 46u16,
}
}
fn flags(&self) -> u16 {
self.request.flags
}
fn payload(&self) -> &[u8] {
self.request.buf()
}
type ReplyType<'buf> = (Tcmsg, IterableAttrs<'buf>);
fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
Self::decode_request(buf)
}
fn lookup(
buf: &[u8],
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
Self::decode_request(buf)
.1
.lookup_attr(offset, missing_type)
}
}
#[doc = "Get / dump tc chain information.\n\nRequest attributes:\n- [.push_kind()](PushAttrs::push_kind)\n- [.nested_options_basic()](PushAttrs::nested_options_basic)\n- [.nested_options_bpf()](PushAttrs::nested_options_bpf)\n- [.nested_options_bfifo()](PushAttrs::nested_options_bfifo)\n- [.nested_options_cake()](PushAttrs::nested_options_cake)\n- [.nested_options_cbs()](PushAttrs::nested_options_cbs)\n- [.nested_options_cgroup()](PushAttrs::nested_options_cgroup)\n- [.nested_options_choke()](PushAttrs::nested_options_choke)\n- [.nested_options_clsact()](PushAttrs::nested_options_clsact)\n- [.nested_options_codel()](PushAttrs::nested_options_codel)\n- [.nested_options_drr()](PushAttrs::nested_options_drr)\n- [.nested_options_dualpi2()](PushAttrs::nested_options_dualpi2)\n- [.nested_options_etf()](PushAttrs::nested_options_etf)\n- [.nested_options_ets()](PushAttrs::nested_options_ets)\n- [.nested_options_flow()](PushAttrs::nested_options_flow)\n- [.nested_options_flower()](PushAttrs::nested_options_flower)\n- [.nested_options_fq()](PushAttrs::nested_options_fq)\n- [.nested_options_fq_codel()](PushAttrs::nested_options_fq_codel)\n- [.nested_options_fq_pie()](PushAttrs::nested_options_fq_pie)\n- [.nested_options_fw()](PushAttrs::nested_options_fw)\n- [.nested_options_gred()](PushAttrs::nested_options_gred)\n- [.nested_options_hfsc()](PushAttrs::nested_options_hfsc)\n- [.nested_options_hhf()](PushAttrs::nested_options_hhf)\n- [.nested_options_htb()](PushAttrs::nested_options_htb)\n- [.nested_options_ingress()](PushAttrs::nested_options_ingress)\n- [.nested_options_matchall()](PushAttrs::nested_options_matchall)\n- [.nested_options_mq()](PushAttrs::nested_options_mq)\n- [.nested_options_mqprio()](PushAttrs::nested_options_mqprio)\n- [.nested_options_multiq()](PushAttrs::nested_options_multiq)\n- [.nested_options_netem()](PushAttrs::nested_options_netem)\n- [.nested_options_pfifo()](PushAttrs::nested_options_pfifo)\n- [.nested_options_pfifo_fast()](PushAttrs::nested_options_pfifo_fast)\n- [.nested_options_pfifo_head_drop()](PushAttrs::nested_options_pfifo_head_drop)\n- [.nested_options_pie()](PushAttrs::nested_options_pie)\n- [.nested_options_plug()](PushAttrs::nested_options_plug)\n- [.nested_options_prio()](PushAttrs::nested_options_prio)\n- [.nested_options_qfq()](PushAttrs::nested_options_qfq)\n- [.nested_options_red()](PushAttrs::nested_options_red)\n- [.nested_options_route()](PushAttrs::nested_options_route)\n- [.nested_options_sfb()](PushAttrs::nested_options_sfb)\n- [.nested_options_sfq()](PushAttrs::nested_options_sfq)\n- [.nested_options_taprio()](PushAttrs::nested_options_taprio)\n- [.nested_options_tbf()](PushAttrs::nested_options_tbf)\n- [.nested_options_u32()](PushAttrs::nested_options_u32)\n- [.push_rate()](PushAttrs::push_rate)\n- [.push_chain()](PushAttrs::push_chain)\n- [.push_ingress_block()](PushAttrs::push_ingress_block)\n- [.push_egress_block()](PushAttrs::push_egress_block)\n\n"]
#[derive(Debug)]
pub struct OpNewchainDo<'r> {
request: Request<'r>,
}
impl<'r> OpNewchainDo<'r> {
pub fn new(mut request: Request<'r>, header: &Tcmsg) -> Self {
Self::write_header(request.buf_mut(), header);
Self { request: request }
}
pub fn encode_request<'buf>(
buf: &'buf mut Vec<u8>,
header: &Tcmsg,
) -> PushAttrs<&'buf mut Vec<u8>> {
Self::write_header(buf, header);
PushAttrs::new(buf)
}
pub fn encode(&mut self) -> PushAttrs<&mut Vec<u8>> {
PushAttrs::new(self.request.buf_mut())
}
pub fn into_encoder(self) -> PushAttrs<RequestBuf<'r>> {
PushAttrs::new(self.request.buf)
}
pub fn decode_request<'a>(buf: &'a [u8]) -> (Tcmsg, IterableAttrs<'a>) {
let (header, attrs) = buf.split_at(buf.len().min(Tcmsg::len()));
(
Tcmsg::new_from_slice(header).unwrap_or_default(),
IterableAttrs::with_loc(attrs, buf.as_ptr() as usize),
)
}
fn write_header<Prev: Pusher>(prev: &mut Prev, header: &Tcmsg) {
prev.as_vec_mut().extend(header.as_slice());
}
}
impl NetlinkRequest for OpNewchainDo<'_> {
fn protocol(&self) -> Protocol {
Protocol::Raw {
protonum: 0u16,
request_type: 100u16,
}
}
fn flags(&self) -> u16 {
self.request.flags
}
fn payload(&self) -> &[u8] {
self.request.buf()
}
type ReplyType<'buf> = (Tcmsg, IterableAttrs<'buf>);
fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
Self::decode_request(buf)
}
fn lookup(
buf: &[u8],
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
Self::decode_request(buf)
.1
.lookup_attr(offset, missing_type)
}
}
#[doc = "Get / dump tc chain information.\n\nRequest attributes:\n- [.push_chain()](PushAttrs::push_chain)\n\n"]
#[derive(Debug)]
pub struct OpDelchainDo<'r> {
request: Request<'r>,
}
impl<'r> OpDelchainDo<'r> {
pub fn new(mut request: Request<'r>, header: &Tcmsg) -> Self {
Self::write_header(request.buf_mut(), header);
Self { request: request }
}
pub fn encode_request<'buf>(
buf: &'buf mut Vec<u8>,
header: &Tcmsg,
) -> PushAttrs<&'buf mut Vec<u8>> {
Self::write_header(buf, header);
PushAttrs::new(buf)
}
pub fn encode(&mut self) -> PushAttrs<&mut Vec<u8>> {
PushAttrs::new(self.request.buf_mut())
}
pub fn into_encoder(self) -> PushAttrs<RequestBuf<'r>> {
PushAttrs::new(self.request.buf)
}
pub fn decode_request<'a>(buf: &'a [u8]) -> (Tcmsg, IterableAttrs<'a>) {
let (header, attrs) = buf.split_at(buf.len().min(Tcmsg::len()));
(
Tcmsg::new_from_slice(header).unwrap_or_default(),
IterableAttrs::with_loc(attrs, buf.as_ptr() as usize),
)
}
fn write_header<Prev: Pusher>(prev: &mut Prev, header: &Tcmsg) {
prev.as_vec_mut().extend(header.as_slice());
}
}
impl NetlinkRequest for OpDelchainDo<'_> {
fn protocol(&self) -> Protocol {
Protocol::Raw {
protonum: 0u16,
request_type: 101u16,
}
}
fn flags(&self) -> u16 {
self.request.flags
}
fn payload(&self) -> &[u8] {
self.request.buf()
}
type ReplyType<'buf> = (Tcmsg, IterableAttrs<'buf>);
fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
Self::decode_request(buf)
}
fn lookup(
buf: &[u8],
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
Self::decode_request(buf)
.1
.lookup_attr(offset, missing_type)
}
}
#[doc = "Get / dump tc chain information.\n\nRequest attributes:\n- [.push_chain()](PushAttrs::push_chain)\n\nReply attributes:\n- [.get_kind()](IterableAttrs::get_kind)\n- [.get_options()](IterableAttrs::get_options)\n- [.get_stats()](IterableAttrs::get_stats)\n- [.get_xstats()](IterableAttrs::get_xstats)\n- [.get_rate()](IterableAttrs::get_rate)\n- [.get_fcnt()](IterableAttrs::get_fcnt)\n- [.get_stats2()](IterableAttrs::get_stats2)\n- [.get_stab()](IterableAttrs::get_stab)\n- [.get_chain()](IterableAttrs::get_chain)\n- [.get_ingress_block()](IterableAttrs::get_ingress_block)\n- [.get_egress_block()](IterableAttrs::get_egress_block)\n\n"]
#[derive(Debug)]
pub struct OpGetchainDo<'r> {
request: Request<'r>,
}
impl<'r> OpGetchainDo<'r> {
pub fn new(mut request: Request<'r>, header: &Tcmsg) -> Self {
Self::write_header(request.buf_mut(), header);
Self { request: request }
}
pub fn encode_request<'buf>(
buf: &'buf mut Vec<u8>,
header: &Tcmsg,
) -> PushAttrs<&'buf mut Vec<u8>> {
Self::write_header(buf, header);
PushAttrs::new(buf)
}
pub fn encode(&mut self) -> PushAttrs<&mut Vec<u8>> {
PushAttrs::new(self.request.buf_mut())
}
pub fn into_encoder(self) -> PushAttrs<RequestBuf<'r>> {
PushAttrs::new(self.request.buf)
}
pub fn decode_request<'a>(buf: &'a [u8]) -> (Tcmsg, IterableAttrs<'a>) {
let (header, attrs) = buf.split_at(buf.len().min(Tcmsg::len()));
(
Tcmsg::new_from_slice(header).unwrap_or_default(),
IterableAttrs::with_loc(attrs, buf.as_ptr() as usize),
)
}
fn write_header<Prev: Pusher>(prev: &mut Prev, header: &Tcmsg) {
prev.as_vec_mut().extend(header.as_slice());
}
}
impl NetlinkRequest for OpGetchainDo<'_> {
fn protocol(&self) -> Protocol {
Protocol::Raw {
protonum: 0u16,
request_type: 102u16,
}
}
fn flags(&self) -> u16 {
self.request.flags
}
fn payload(&self) -> &[u8] {
self.request.buf()
}
type ReplyType<'buf> = (Tcmsg, IterableAttrs<'buf>);
fn decode_reply<'buf>(buf: &'buf [u8]) -> Self::ReplyType<'buf> {
Self::decode_request(buf)
}
fn lookup(
buf: &[u8],
offset: usize,
missing_type: Option<u16>,
) -> (Vec<(&'static str, usize)>, Option<&'static str>) {
Self::decode_request(buf)
.1
.lookup_attr(offset, missing_type)
}
}
#[derive(Debug)]
pub struct ChainedFinal<'a> {
inner: Chained<'a>,
}
#[derive(Debug)]
pub struct Chained<'a> {
buf: RequestBuf<'a>,
first_seq: u32,
lookups: Vec<(&'static str, LookupFn)>,
last_header_offset: usize,
last_kind: Option<RequestInfo>,
}
impl<'a> ChainedFinal<'a> {
pub fn into_chained(self) -> Chained<'a> {
self.inner
}
pub fn buf(&self) -> &Vec<u8> {
self.inner.buf()
}
pub fn buf_mut(&mut self) -> &mut Vec<u8> {
self.inner.buf_mut()
}
fn get_index(&self, seq: u32) -> Option<u32> {
let min = self.inner.first_seq;
let max = min.wrapping_add(self.inner.lookups.len() as u32);
return if min <= max {
(min..max).contains(&seq).then(|| seq - min)
} else if min <= seq {
Some(seq - min)
} else if seq < max {
Some(u32::MAX - min + seq)
} else {
None
};
}
}
impl crate::traits::NetlinkChained for ChainedFinal<'_> {
fn protonum(&self) -> u16 {
PROTONUM
}
fn payload(&self) -> &[u8] {
self.buf()
}
fn chain_len(&self) -> usize {
self.inner.lookups.len()
}
fn get_index(&self, seq: u32) -> Option<usize> {
self.get_index(seq).map(|n| n as usize)
}
fn name(&self, index: usize) -> &'static str {
self.inner.lookups[index].0
}
fn lookup(&self, index: usize) -> LookupFn {
self.inner.lookups[index].1
}
}
impl Chained<'static> {
pub fn new(first_seq: u32) -> Self {
Self::new_from_buf(Vec::new(), first_seq)
}
pub fn new_from_buf(buf: Vec<u8>, first_seq: u32) -> Self {
Self {
buf: RequestBuf::Own(buf),
first_seq,
lookups: Vec::new(),
last_header_offset: 0,
last_kind: None,
}
}
pub fn into_buf(self) -> Vec<u8> {
match self.buf {
RequestBuf::Own(buf) => buf,
_ => unreachable!(),
}
}
}
impl<'a> Chained<'a> {
pub fn new_with_buf(buf: &'a mut Vec<u8>, first_seq: u32) -> Self {
Self {
buf: RequestBuf::Ref(buf),
first_seq,
lookups: Vec::new(),
last_header_offset: 0,
last_kind: None,
}
}
pub fn finalize(mut self) -> ChainedFinal<'a> {
self.update_header();
ChainedFinal { inner: self }
}
pub fn request(&mut self) -> Request<'_> {
self.update_header();
self.last_header_offset = self.buf().len();
self.buf_mut().extend_from_slice(Nlmsghdr::new().as_slice());
let mut request = Request::new_extend(self.buf.buf_mut());
self.last_kind = None;
request.writeback = Some(&mut self.last_kind);
request
}
pub fn buf(&self) -> &Vec<u8> {
self.buf.buf()
}
pub fn buf_mut(&mut self) -> &mut Vec<u8> {
self.buf.buf_mut()
}
fn update_header(&mut self) {
let Some(RequestInfo {
protocol,
flags,
name,
lookup,
}) = self.last_kind
else {
if !self.buf().is_empty() {
assert_eq!(self.last_header_offset + Nlmsghdr::len(), self.buf().len());
self.buf.buf_mut().truncate(self.last_header_offset);
}
return;
};
let header_offset = self.last_header_offset;
let request_type = match protocol {
Protocol::Raw { request_type, .. } => request_type,
Protocol::Generic(_) => unreachable!(),
};
let index = self.lookups.len();
let seq = self.first_seq.wrapping_add(index as u32);
self.lookups.push((name, lookup));
let buf = self.buf_mut();
align(buf);
let header = Nlmsghdr {
len: (buf.len() - header_offset) as u32,
r#type: request_type,
flags: flags | consts::NLM_F_REQUEST as u16 | consts::NLM_F_ACK as u16,
seq,
pid: 0,
};
buf[header_offset..(header_offset + 16)].clone_from_slice(header.as_slice());
}
}
use crate::traits::LookupFn;
use crate::utils::RequestBuf;
#[derive(Debug)]
pub struct Request<'buf> {
buf: RequestBuf<'buf>,
flags: u16,
writeback: Option<&'buf mut Option<RequestInfo>>,
}
#[allow(unused)]
#[derive(Debug, Clone)]
pub struct RequestInfo {
protocol: Protocol,
flags: u16,
name: &'static str,
lookup: LookupFn,
}
impl Request<'static> {
pub fn new() -> Self {
Self::new_from_buf(Vec::new())
}
pub fn new_from_buf(buf: Vec<u8>) -> Self {
Self {
flags: 0,
buf: RequestBuf::Own(buf),
writeback: None,
}
}
pub fn into_buf(self) -> Vec<u8> {
match self.buf {
RequestBuf::Own(buf) => buf,
_ => unreachable!(),
}
}
}
impl<'buf> Request<'buf> {
pub fn new_with_buf(buf: &'buf mut Vec<u8>) -> Self {
buf.clear();
Self::new_extend(buf)
}
pub fn new_extend(buf: &'buf mut Vec<u8>) -> Self {
Self {
flags: 0,
buf: RequestBuf::Ref(buf),
writeback: None,
}
}
fn do_writeback(&mut self, protocol: Protocol, name: &'static str, lookup: LookupFn) {
let Some(writeback) = &mut self.writeback else {
return;
};
**writeback = Some(RequestInfo {
protocol,
flags: self.flags,
name,
lookup,
})
}
pub fn buf(&self) -> &Vec<u8> {
self.buf.buf()
}
pub fn buf_mut(&mut self) -> &mut Vec<u8> {
self.buf.buf_mut()
}
#[doc = "Set `NLM_F_CREATE` flag"]
pub fn set_create(mut self) -> Self {
self.flags |= consts::NLM_F_CREATE as u16;
self
}
#[doc = "Set `NLM_F_EXCL` flag"]
pub fn set_excl(mut self) -> Self {
self.flags |= consts::NLM_F_EXCL as u16;
self
}
#[doc = "Set `NLM_F_REPLACE` flag"]
pub fn set_replace(mut self) -> Self {
self.flags |= consts::NLM_F_REPLACE as u16;
self
}
#[doc = "Set `NLM_F_CREATE` and `NLM_F_REPLACE` flag"]
pub fn set_change(self) -> Self {
self.set_create().set_replace()
}
#[doc = "Set `NLM_F_APPEND` flag"]
pub fn set_append(mut self) -> Self {
self.flags |= consts::NLM_F_APPEND as u16;
self
}
#[doc = "Set `self.flags |= flags`"]
pub fn set_flags(mut self, flags: u16) -> Self {
self.flags |= flags;
self
}
#[doc = "Set `self.flags ^= self.flags & flags`"]
pub fn unset_flags(mut self, flags: u16) -> Self {
self.flags ^= self.flags & flags;
self
}
#[doc = "Set `NLM_F_DUMP` flag"]
fn set_dump(mut self) -> Self {
self.flags |= consts::NLM_F_DUMP as u16;
self
}
#[doc = "Create new tc qdisc.\n\nRequest attributes:\n- [.push_kind()](PushAttrs::push_kind)\n- [.nested_options_basic()](PushAttrs::nested_options_basic)\n- [.nested_options_bpf()](PushAttrs::nested_options_bpf)\n- [.nested_options_bfifo()](PushAttrs::nested_options_bfifo)\n- [.nested_options_cake()](PushAttrs::nested_options_cake)\n- [.nested_options_cbs()](PushAttrs::nested_options_cbs)\n- [.nested_options_cgroup()](PushAttrs::nested_options_cgroup)\n- [.nested_options_choke()](PushAttrs::nested_options_choke)\n- [.nested_options_clsact()](PushAttrs::nested_options_clsact)\n- [.nested_options_codel()](PushAttrs::nested_options_codel)\n- [.nested_options_drr()](PushAttrs::nested_options_drr)\n- [.nested_options_dualpi2()](PushAttrs::nested_options_dualpi2)\n- [.nested_options_etf()](PushAttrs::nested_options_etf)\n- [.nested_options_ets()](PushAttrs::nested_options_ets)\n- [.nested_options_flow()](PushAttrs::nested_options_flow)\n- [.nested_options_flower()](PushAttrs::nested_options_flower)\n- [.nested_options_fq()](PushAttrs::nested_options_fq)\n- [.nested_options_fq_codel()](PushAttrs::nested_options_fq_codel)\n- [.nested_options_fq_pie()](PushAttrs::nested_options_fq_pie)\n- [.nested_options_fw()](PushAttrs::nested_options_fw)\n- [.nested_options_gred()](PushAttrs::nested_options_gred)\n- [.nested_options_hfsc()](PushAttrs::nested_options_hfsc)\n- [.nested_options_hhf()](PushAttrs::nested_options_hhf)\n- [.nested_options_htb()](PushAttrs::nested_options_htb)\n- [.nested_options_ingress()](PushAttrs::nested_options_ingress)\n- [.nested_options_matchall()](PushAttrs::nested_options_matchall)\n- [.nested_options_mq()](PushAttrs::nested_options_mq)\n- [.nested_options_mqprio()](PushAttrs::nested_options_mqprio)\n- [.nested_options_multiq()](PushAttrs::nested_options_multiq)\n- [.nested_options_netem()](PushAttrs::nested_options_netem)\n- [.nested_options_pfifo()](PushAttrs::nested_options_pfifo)\n- [.nested_options_pfifo_fast()](PushAttrs::nested_options_pfifo_fast)\n- [.nested_options_pfifo_head_drop()](PushAttrs::nested_options_pfifo_head_drop)\n- [.nested_options_pie()](PushAttrs::nested_options_pie)\n- [.nested_options_plug()](PushAttrs::nested_options_plug)\n- [.nested_options_prio()](PushAttrs::nested_options_prio)\n- [.nested_options_qfq()](PushAttrs::nested_options_qfq)\n- [.nested_options_red()](PushAttrs::nested_options_red)\n- [.nested_options_route()](PushAttrs::nested_options_route)\n- [.nested_options_sfb()](PushAttrs::nested_options_sfb)\n- [.nested_options_sfq()](PushAttrs::nested_options_sfq)\n- [.nested_options_taprio()](PushAttrs::nested_options_taprio)\n- [.nested_options_tbf()](PushAttrs::nested_options_tbf)\n- [.nested_options_u32()](PushAttrs::nested_options_u32)\n- [.push_rate()](PushAttrs::push_rate)\n- [.push_chain()](PushAttrs::push_chain)\n- [.push_ingress_block()](PushAttrs::push_ingress_block)\n- [.push_egress_block()](PushAttrs::push_egress_block)\n\n"]
pub fn op_newqdisc_do(self, header: &Tcmsg) -> OpNewqdiscDo<'buf> {
let mut res = OpNewqdiscDo::new(self, header);
res.request
.do_writeback(res.protocol(), "op-newqdisc-do", OpNewqdiscDo::lookup);
res
}
#[doc = "Delete existing tc qdisc.\n\n"]
pub fn op_delqdisc_do(self, header: &Tcmsg) -> OpDelqdiscDo<'buf> {
let mut res = OpDelqdiscDo::new(self, header);
res.request
.do_writeback(res.protocol(), "op-delqdisc-do", OpDelqdiscDo::lookup);
res
}
#[doc = "Get / dump tc qdisc information.\n\nRequest attributes:\n- [.push_dump_invisible()](PushAttrs::push_dump_invisible)\n\nReply attributes:\n- [.get_kind()](IterableAttrs::get_kind)\n- [.get_options()](IterableAttrs::get_options)\n- [.get_stats()](IterableAttrs::get_stats)\n- [.get_xstats()](IterableAttrs::get_xstats)\n- [.get_rate()](IterableAttrs::get_rate)\n- [.get_fcnt()](IterableAttrs::get_fcnt)\n- [.get_stats2()](IterableAttrs::get_stats2)\n- [.get_stab()](IterableAttrs::get_stab)\n- [.get_chain()](IterableAttrs::get_chain)\n- [.get_ingress_block()](IterableAttrs::get_ingress_block)\n- [.get_egress_block()](IterableAttrs::get_egress_block)\n\n"]
pub fn op_getqdisc_dump(self, header: &Tcmsg) -> OpGetqdiscDump<'buf> {
let mut res = OpGetqdiscDump::new(self, header);
res.request
.do_writeback(res.protocol(), "op-getqdisc-dump", OpGetqdiscDump::lookup);
res
}
#[doc = "Get / dump tc qdisc information.\n\nRequest attributes:\n- [.push_dump_invisible()](PushAttrs::push_dump_invisible)\n\nReply attributes:\n- [.get_kind()](IterableAttrs::get_kind)\n- [.get_options()](IterableAttrs::get_options)\n- [.get_stats()](IterableAttrs::get_stats)\n- [.get_xstats()](IterableAttrs::get_xstats)\n- [.get_rate()](IterableAttrs::get_rate)\n- [.get_fcnt()](IterableAttrs::get_fcnt)\n- [.get_stats2()](IterableAttrs::get_stats2)\n- [.get_stab()](IterableAttrs::get_stab)\n- [.get_chain()](IterableAttrs::get_chain)\n- [.get_ingress_block()](IterableAttrs::get_ingress_block)\n- [.get_egress_block()](IterableAttrs::get_egress_block)\n\n"]
pub fn op_getqdisc_do(self, header: &Tcmsg) -> OpGetqdiscDo<'buf> {
let mut res = OpGetqdiscDo::new(self, header);
res.request
.do_writeback(res.protocol(), "op-getqdisc-do", OpGetqdiscDo::lookup);
res
}
#[doc = "Get / dump tc traffic class information.\n\nRequest attributes:\n- [.push_kind()](PushAttrs::push_kind)\n- [.nested_options_basic()](PushAttrs::nested_options_basic)\n- [.nested_options_bpf()](PushAttrs::nested_options_bpf)\n- [.nested_options_bfifo()](PushAttrs::nested_options_bfifo)\n- [.nested_options_cake()](PushAttrs::nested_options_cake)\n- [.nested_options_cbs()](PushAttrs::nested_options_cbs)\n- [.nested_options_cgroup()](PushAttrs::nested_options_cgroup)\n- [.nested_options_choke()](PushAttrs::nested_options_choke)\n- [.nested_options_clsact()](PushAttrs::nested_options_clsact)\n- [.nested_options_codel()](PushAttrs::nested_options_codel)\n- [.nested_options_drr()](PushAttrs::nested_options_drr)\n- [.nested_options_dualpi2()](PushAttrs::nested_options_dualpi2)\n- [.nested_options_etf()](PushAttrs::nested_options_etf)\n- [.nested_options_ets()](PushAttrs::nested_options_ets)\n- [.nested_options_flow()](PushAttrs::nested_options_flow)\n- [.nested_options_flower()](PushAttrs::nested_options_flower)\n- [.nested_options_fq()](PushAttrs::nested_options_fq)\n- [.nested_options_fq_codel()](PushAttrs::nested_options_fq_codel)\n- [.nested_options_fq_pie()](PushAttrs::nested_options_fq_pie)\n- [.nested_options_fw()](PushAttrs::nested_options_fw)\n- [.nested_options_gred()](PushAttrs::nested_options_gred)\n- [.nested_options_hfsc()](PushAttrs::nested_options_hfsc)\n- [.nested_options_hhf()](PushAttrs::nested_options_hhf)\n- [.nested_options_htb()](PushAttrs::nested_options_htb)\n- [.nested_options_ingress()](PushAttrs::nested_options_ingress)\n- [.nested_options_matchall()](PushAttrs::nested_options_matchall)\n- [.nested_options_mq()](PushAttrs::nested_options_mq)\n- [.nested_options_mqprio()](PushAttrs::nested_options_mqprio)\n- [.nested_options_multiq()](PushAttrs::nested_options_multiq)\n- [.nested_options_netem()](PushAttrs::nested_options_netem)\n- [.nested_options_pfifo()](PushAttrs::nested_options_pfifo)\n- [.nested_options_pfifo_fast()](PushAttrs::nested_options_pfifo_fast)\n- [.nested_options_pfifo_head_drop()](PushAttrs::nested_options_pfifo_head_drop)\n- [.nested_options_pie()](PushAttrs::nested_options_pie)\n- [.nested_options_plug()](PushAttrs::nested_options_plug)\n- [.nested_options_prio()](PushAttrs::nested_options_prio)\n- [.nested_options_qfq()](PushAttrs::nested_options_qfq)\n- [.nested_options_red()](PushAttrs::nested_options_red)\n- [.nested_options_route()](PushAttrs::nested_options_route)\n- [.nested_options_sfb()](PushAttrs::nested_options_sfb)\n- [.nested_options_sfq()](PushAttrs::nested_options_sfq)\n- [.nested_options_taprio()](PushAttrs::nested_options_taprio)\n- [.nested_options_tbf()](PushAttrs::nested_options_tbf)\n- [.nested_options_u32()](PushAttrs::nested_options_u32)\n- [.push_rate()](PushAttrs::push_rate)\n- [.push_chain()](PushAttrs::push_chain)\n- [.push_ingress_block()](PushAttrs::push_ingress_block)\n- [.push_egress_block()](PushAttrs::push_egress_block)\n\n"]
pub fn op_newtclass_do(self, header: &Tcmsg) -> OpNewtclassDo<'buf> {
let mut res = OpNewtclassDo::new(self, header);
res.request
.do_writeback(res.protocol(), "op-newtclass-do", OpNewtclassDo::lookup);
res
}
#[doc = "Get / dump tc traffic class information.\n\n"]
pub fn op_deltclass_do(self, header: &Tcmsg) -> OpDeltclassDo<'buf> {
let mut res = OpDeltclassDo::new(self, header);
res.request
.do_writeback(res.protocol(), "op-deltclass-do", OpDeltclassDo::lookup);
res
}
#[doc = "Get / dump tc traffic class information.\n\nReply attributes:\n- [.get_kind()](IterableAttrs::get_kind)\n- [.get_options()](IterableAttrs::get_options)\n- [.get_stats()](IterableAttrs::get_stats)\n- [.get_xstats()](IterableAttrs::get_xstats)\n- [.get_rate()](IterableAttrs::get_rate)\n- [.get_fcnt()](IterableAttrs::get_fcnt)\n- [.get_stats2()](IterableAttrs::get_stats2)\n- [.get_stab()](IterableAttrs::get_stab)\n- [.get_chain()](IterableAttrs::get_chain)\n- [.get_ingress_block()](IterableAttrs::get_ingress_block)\n- [.get_egress_block()](IterableAttrs::get_egress_block)\n\n"]
pub fn op_gettclass_do(self, header: &Tcmsg) -> OpGettclassDo<'buf> {
let mut res = OpGettclassDo::new(self, header);
res.request
.do_writeback(res.protocol(), "op-gettclass-do", OpGettclassDo::lookup);
res
}
#[doc = "Get / dump tc filter information.\n\nRequest attributes:\n- [.push_kind()](PushAttrs::push_kind)\n- [.nested_options_basic()](PushAttrs::nested_options_basic)\n- [.nested_options_bpf()](PushAttrs::nested_options_bpf)\n- [.nested_options_bfifo()](PushAttrs::nested_options_bfifo)\n- [.nested_options_cake()](PushAttrs::nested_options_cake)\n- [.nested_options_cbs()](PushAttrs::nested_options_cbs)\n- [.nested_options_cgroup()](PushAttrs::nested_options_cgroup)\n- [.nested_options_choke()](PushAttrs::nested_options_choke)\n- [.nested_options_clsact()](PushAttrs::nested_options_clsact)\n- [.nested_options_codel()](PushAttrs::nested_options_codel)\n- [.nested_options_drr()](PushAttrs::nested_options_drr)\n- [.nested_options_dualpi2()](PushAttrs::nested_options_dualpi2)\n- [.nested_options_etf()](PushAttrs::nested_options_etf)\n- [.nested_options_ets()](PushAttrs::nested_options_ets)\n- [.nested_options_flow()](PushAttrs::nested_options_flow)\n- [.nested_options_flower()](PushAttrs::nested_options_flower)\n- [.nested_options_fq()](PushAttrs::nested_options_fq)\n- [.nested_options_fq_codel()](PushAttrs::nested_options_fq_codel)\n- [.nested_options_fq_pie()](PushAttrs::nested_options_fq_pie)\n- [.nested_options_fw()](PushAttrs::nested_options_fw)\n- [.nested_options_gred()](PushAttrs::nested_options_gred)\n- [.nested_options_hfsc()](PushAttrs::nested_options_hfsc)\n- [.nested_options_hhf()](PushAttrs::nested_options_hhf)\n- [.nested_options_htb()](PushAttrs::nested_options_htb)\n- [.nested_options_ingress()](PushAttrs::nested_options_ingress)\n- [.nested_options_matchall()](PushAttrs::nested_options_matchall)\n- [.nested_options_mq()](PushAttrs::nested_options_mq)\n- [.nested_options_mqprio()](PushAttrs::nested_options_mqprio)\n- [.nested_options_multiq()](PushAttrs::nested_options_multiq)\n- [.nested_options_netem()](PushAttrs::nested_options_netem)\n- [.nested_options_pfifo()](PushAttrs::nested_options_pfifo)\n- [.nested_options_pfifo_fast()](PushAttrs::nested_options_pfifo_fast)\n- [.nested_options_pfifo_head_drop()](PushAttrs::nested_options_pfifo_head_drop)\n- [.nested_options_pie()](PushAttrs::nested_options_pie)\n- [.nested_options_plug()](PushAttrs::nested_options_plug)\n- [.nested_options_prio()](PushAttrs::nested_options_prio)\n- [.nested_options_qfq()](PushAttrs::nested_options_qfq)\n- [.nested_options_red()](PushAttrs::nested_options_red)\n- [.nested_options_route()](PushAttrs::nested_options_route)\n- [.nested_options_sfb()](PushAttrs::nested_options_sfb)\n- [.nested_options_sfq()](PushAttrs::nested_options_sfq)\n- [.nested_options_taprio()](PushAttrs::nested_options_taprio)\n- [.nested_options_tbf()](PushAttrs::nested_options_tbf)\n- [.nested_options_u32()](PushAttrs::nested_options_u32)\n- [.push_rate()](PushAttrs::push_rate)\n- [.push_chain()](PushAttrs::push_chain)\n- [.push_ingress_block()](PushAttrs::push_ingress_block)\n- [.push_egress_block()](PushAttrs::push_egress_block)\n\n"]
pub fn op_newtfilter_do(self, header: &Tcmsg) -> OpNewtfilterDo<'buf> {
let mut res = OpNewtfilterDo::new(self, header);
res.request
.do_writeback(res.protocol(), "op-newtfilter-do", OpNewtfilterDo::lookup);
res
}
#[doc = "Get / dump tc filter information.\n\nRequest attributes:\n- [.push_kind()](PushAttrs::push_kind)\n- [.push_chain()](PushAttrs::push_chain)\n\n"]
pub fn op_deltfilter_do(self, header: &Tcmsg) -> OpDeltfilterDo<'buf> {
let mut res = OpDeltfilterDo::new(self, header);
res.request
.do_writeback(res.protocol(), "op-deltfilter-do", OpDeltfilterDo::lookup);
res
}
#[doc = "Get / dump tc filter information.\n\nRequest attributes:\n- [.push_chain()](PushAttrs::push_chain)\n- [.push_dump_flags()](PushAttrs::push_dump_flags)\n\nReply attributes:\n- [.get_kind()](IterableAttrs::get_kind)\n- [.get_options()](IterableAttrs::get_options)\n- [.get_stats()](IterableAttrs::get_stats)\n- [.get_xstats()](IterableAttrs::get_xstats)\n- [.get_rate()](IterableAttrs::get_rate)\n- [.get_fcnt()](IterableAttrs::get_fcnt)\n- [.get_stats2()](IterableAttrs::get_stats2)\n- [.get_stab()](IterableAttrs::get_stab)\n- [.get_chain()](IterableAttrs::get_chain)\n- [.get_ingress_block()](IterableAttrs::get_ingress_block)\n- [.get_egress_block()](IterableAttrs::get_egress_block)\n\n"]
pub fn op_gettfilter_dump(self, header: &Tcmsg) -> OpGettfilterDump<'buf> {
let mut res = OpGettfilterDump::new(self, header);
res.request.do_writeback(
res.protocol(),
"op-gettfilter-dump",
OpGettfilterDump::lookup,
);
res
}
#[doc = "Get / dump tc filter information.\n\nRequest attributes:\n- [.push_kind()](PushAttrs::push_kind)\n- [.push_chain()](PushAttrs::push_chain)\n\nReply attributes:\n- [.get_kind()](IterableAttrs::get_kind)\n- [.get_options()](IterableAttrs::get_options)\n- [.get_stats()](IterableAttrs::get_stats)\n- [.get_xstats()](IterableAttrs::get_xstats)\n- [.get_rate()](IterableAttrs::get_rate)\n- [.get_fcnt()](IterableAttrs::get_fcnt)\n- [.get_stats2()](IterableAttrs::get_stats2)\n- [.get_stab()](IterableAttrs::get_stab)\n- [.get_chain()](IterableAttrs::get_chain)\n- [.get_ingress_block()](IterableAttrs::get_ingress_block)\n- [.get_egress_block()](IterableAttrs::get_egress_block)\n\n"]
pub fn op_gettfilter_do(self, header: &Tcmsg) -> OpGettfilterDo<'buf> {
let mut res = OpGettfilterDo::new(self, header);
res.request
.do_writeback(res.protocol(), "op-gettfilter-do", OpGettfilterDo::lookup);
res
}
#[doc = "Get / dump tc chain information.\n\nRequest attributes:\n- [.push_kind()](PushAttrs::push_kind)\n- [.nested_options_basic()](PushAttrs::nested_options_basic)\n- [.nested_options_bpf()](PushAttrs::nested_options_bpf)\n- [.nested_options_bfifo()](PushAttrs::nested_options_bfifo)\n- [.nested_options_cake()](PushAttrs::nested_options_cake)\n- [.nested_options_cbs()](PushAttrs::nested_options_cbs)\n- [.nested_options_cgroup()](PushAttrs::nested_options_cgroup)\n- [.nested_options_choke()](PushAttrs::nested_options_choke)\n- [.nested_options_clsact()](PushAttrs::nested_options_clsact)\n- [.nested_options_codel()](PushAttrs::nested_options_codel)\n- [.nested_options_drr()](PushAttrs::nested_options_drr)\n- [.nested_options_dualpi2()](PushAttrs::nested_options_dualpi2)\n- [.nested_options_etf()](PushAttrs::nested_options_etf)\n- [.nested_options_ets()](PushAttrs::nested_options_ets)\n- [.nested_options_flow()](PushAttrs::nested_options_flow)\n- [.nested_options_flower()](PushAttrs::nested_options_flower)\n- [.nested_options_fq()](PushAttrs::nested_options_fq)\n- [.nested_options_fq_codel()](PushAttrs::nested_options_fq_codel)\n- [.nested_options_fq_pie()](PushAttrs::nested_options_fq_pie)\n- [.nested_options_fw()](PushAttrs::nested_options_fw)\n- [.nested_options_gred()](PushAttrs::nested_options_gred)\n- [.nested_options_hfsc()](PushAttrs::nested_options_hfsc)\n- [.nested_options_hhf()](PushAttrs::nested_options_hhf)\n- [.nested_options_htb()](PushAttrs::nested_options_htb)\n- [.nested_options_ingress()](PushAttrs::nested_options_ingress)\n- [.nested_options_matchall()](PushAttrs::nested_options_matchall)\n- [.nested_options_mq()](PushAttrs::nested_options_mq)\n- [.nested_options_mqprio()](PushAttrs::nested_options_mqprio)\n- [.nested_options_multiq()](PushAttrs::nested_options_multiq)\n- [.nested_options_netem()](PushAttrs::nested_options_netem)\n- [.nested_options_pfifo()](PushAttrs::nested_options_pfifo)\n- [.nested_options_pfifo_fast()](PushAttrs::nested_options_pfifo_fast)\n- [.nested_options_pfifo_head_drop()](PushAttrs::nested_options_pfifo_head_drop)\n- [.nested_options_pie()](PushAttrs::nested_options_pie)\n- [.nested_options_plug()](PushAttrs::nested_options_plug)\n- [.nested_options_prio()](PushAttrs::nested_options_prio)\n- [.nested_options_qfq()](PushAttrs::nested_options_qfq)\n- [.nested_options_red()](PushAttrs::nested_options_red)\n- [.nested_options_route()](PushAttrs::nested_options_route)\n- [.nested_options_sfb()](PushAttrs::nested_options_sfb)\n- [.nested_options_sfq()](PushAttrs::nested_options_sfq)\n- [.nested_options_taprio()](PushAttrs::nested_options_taprio)\n- [.nested_options_tbf()](PushAttrs::nested_options_tbf)\n- [.nested_options_u32()](PushAttrs::nested_options_u32)\n- [.push_rate()](PushAttrs::push_rate)\n- [.push_chain()](PushAttrs::push_chain)\n- [.push_ingress_block()](PushAttrs::push_ingress_block)\n- [.push_egress_block()](PushAttrs::push_egress_block)\n\n"]
pub fn op_newchain_do(self, header: &Tcmsg) -> OpNewchainDo<'buf> {
let mut res = OpNewchainDo::new(self, header);
res.request
.do_writeback(res.protocol(), "op-newchain-do", OpNewchainDo::lookup);
res
}
#[doc = "Get / dump tc chain information.\n\nRequest attributes:\n- [.push_chain()](PushAttrs::push_chain)\n\n"]
pub fn op_delchain_do(self, header: &Tcmsg) -> OpDelchainDo<'buf> {
let mut res = OpDelchainDo::new(self, header);
res.request
.do_writeback(res.protocol(), "op-delchain-do", OpDelchainDo::lookup);
res
}
#[doc = "Get / dump tc chain information.\n\nRequest attributes:\n- [.push_chain()](PushAttrs::push_chain)\n\nReply attributes:\n- [.get_kind()](IterableAttrs::get_kind)\n- [.get_options()](IterableAttrs::get_options)\n- [.get_stats()](IterableAttrs::get_stats)\n- [.get_xstats()](IterableAttrs::get_xstats)\n- [.get_rate()](IterableAttrs::get_rate)\n- [.get_fcnt()](IterableAttrs::get_fcnt)\n- [.get_stats2()](IterableAttrs::get_stats2)\n- [.get_stab()](IterableAttrs::get_stab)\n- [.get_chain()](IterableAttrs::get_chain)\n- [.get_ingress_block()](IterableAttrs::get_ingress_block)\n- [.get_egress_block()](IterableAttrs::get_egress_block)\n\n"]
pub fn op_getchain_do(self, header: &Tcmsg) -> OpGetchainDo<'buf> {
let mut res = OpGetchainDo::new(self, header);
res.request
.do_writeback(res.protocol(), "op-getchain-do", OpGetchainDo::lookup);
res
}
}
#[cfg(test)]
mod generated_tests {
use super::*;
#[test]
fn tests() {
let _ = IterableAttrs::get_chain;
let _ = IterableAttrs::get_egress_block;
let _ = IterableAttrs::get_fcnt;
let _ = IterableAttrs::get_ingress_block;
let _ = IterableAttrs::get_kind;
let _ = IterableAttrs::get_options;
let _ = IterableAttrs::get_rate;
let _ = IterableAttrs::get_stab;
let _ = IterableAttrs::get_stats2;
let _ = IterableAttrs::get_stats;
let _ = IterableAttrs::get_xstats;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_basic;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_bfifo;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_bpf;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_cake;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_cbs;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_cgroup;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_choke;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_clsact;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_codel;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_drr;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_dualpi2;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_etf;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_ets;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_flow;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_flower;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_fq;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_fq_codel;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_fq_pie;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_fw;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_gred;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_hfsc;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_hhf;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_htb;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_ingress;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_matchall;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_mq;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_mqprio;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_multiq;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_netem;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_pfifo;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_pfifo_fast;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_pfifo_head_drop;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_pie;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_plug;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_prio;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_qfq;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_red;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_route;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_sfb;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_sfq;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_taprio;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_tbf;
let _ = PushAttrs::<&mut Vec<u8>>::nested_options_u32;
let _ = PushAttrs::<&mut Vec<u8>>::push_chain;
let _ = PushAttrs::<&mut Vec<u8>>::push_dump_flags;
let _ = PushAttrs::<&mut Vec<u8>>::push_dump_invisible;
let _ = PushAttrs::<&mut Vec<u8>>::push_egress_block;
let _ = PushAttrs::<&mut Vec<u8>>::push_ingress_block;
let _ = PushAttrs::<&mut Vec<u8>>::push_kind;
let _ = PushAttrs::<&mut Vec<u8>>::push_rate;
}
}