1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// Copyright (C) 2018 - Will Glozer. All rights reserved.

use std::convert::TryFrom;
use crate::err::Invalid;
use crate::ffi::link::*;
use crate::ffi::route::*;
use crate::sys::Cursor;

#[derive(Debug, Eq, PartialEq)]
pub enum IFLA<'a> {
    Address(&'a [u8]),
    Broadcast(&'a [u8]),
    IFName(&'a str),
    MTU(u32),
    Link(u32),
    QDisc(&'a str),
    Stats(rtnl_link_stats),
    Cost(u32),
    Priority(u32),
    Master(u32),
    Wireless(u32),
    ProtInfo(u32),
    TXQLen(u32),
    Weight(u32),
    Operstate(u8),
    LinkMode(u8),
    NetNSPID(u32),
    IFAlias(&'a str),
    Stats64(rtnl_link_stats64),
    NetNSFD(u32),
    ExtMask(u32),
    Promiscuity(u32),
    NumTXQueues(u32),
    NumRXQueues(u32),
    Carrier(u8),
    LinkNetNSID(u32),
    XDP(Cursor<'a>),
    Unsupported(rtattr, Cursor<'a>),
}

impl<'a> TryFrom<(rtattr, Cursor<'a>)> for IFLA<'a> {
    type Error = Invalid;

    fn try_from((attr, tail): (rtattr, Cursor<'a>)) -> Result<IFLA<'a>, Self::Error> {
        Ok(match attr.rta_type {
            IFLA_ADDRESS       => IFLA::Address(tail.bytes()),
            IFLA_BROADCAST     => IFLA::Broadcast(tail.bytes()),
            IFLA_IFNAME        => IFLA::IFName(tail.asciiz()?),
            IFLA_MTU           => IFLA::MTU(tail.copy()),
            IFLA_LINK          => IFLA::Link(tail.copy()),
            IFLA_QDISC         => IFLA::QDisc(tail.asciiz()?),
            IFLA_STATS         => IFLA::Stats(tail.copy()),
            IFLA_COST          => IFLA::Cost(tail.copy()),
            IFLA_PRIORITY      => IFLA::Priority(tail.copy()),
            IFLA_MASTER        => IFLA::Master(tail.copy()),
            IFLA_WIRELESS      => IFLA::Wireless(tail.copy()),
            IFLA_PROTINFO      => IFLA::ProtInfo(tail.copy()),
            IFLA_TXQLEN        => IFLA::TXQLen(tail.copy()),
            IFLA_WEIGHT        => IFLA::Weight(tail.copy()),
            IFLA_OPERSTATE     => IFLA::Operstate(tail.copy()),
            IFLA_LINKMODE      => IFLA::LinkMode(tail.copy()),
            IFLA_NET_NS_PID    => IFLA::NetNSPID(tail.copy()),
            IFLA_IFALIAS       => IFLA::IFAlias(tail.asciiz()?),
            IFLA_STATS64       => IFLA::Stats64(tail.copy()),
            IFLA_NET_NS_FD     => IFLA::NetNSFD(tail.copy()),
            IFLA_EXT_MASK      => IFLA::ExtMask(tail.copy()),
            IFLA_PROMISCUITY   => IFLA::Promiscuity(tail.copy()),
            IFLA_NUM_TX_QUEUES => IFLA::NumTXQueues(tail.copy()),
            IFLA_NUM_RX_QUEUES => IFLA::NumRXQueues(tail.copy()),
            IFLA_CARRIER       => IFLA::Carrier(tail.copy()),
            IFLA_LINK_NETNSID  => IFLA::LinkNetNSID(tail.copy()),
            IFLA_XDP           => IFLA::XDP(tail),
            _                  => IFLA::Unsupported(attr, tail),
        })
    }
}