nell 0.0.2

Linux netlink API access
Documentation
// Copyright (C) 2018 - Will Glozer. All rights reserved.

use std::mem::size_of;
use std::os::raw::c_int;
use eui48::MacAddress;
use ffi::*;
use ffi::netlink_family::*;
use sys::*;

#[derive(Default, Debug)]
pub struct Link {
    pub index: u32,
    pub name:  String,
    pub flags: u32,
    pub mac:   MacAddress,
    pub mtu:   u32,
    pub xdp:   Xdp,
}

#[derive(Default, Debug)]
pub struct Xdp {
    pub fd:       u32,
    pub attached: bool,
    pub flags:    u32,
    pub prog_id:  u32,
}

pub fn links() -> Result<Vec<Link>, Error> {
    let sock = Socket::new(NETLINK_ROUTE)?;

    #[repr(C)]
    #[derive(Default, Debug)]
    struct Request {
        hdr: nlmsghdr,
        req: rtgenmsg,
    }

    let mut req = Request::default();
    req.hdr.nlmsg_len    = nlmsg_length(size_of::<rtgenmsg>() as u32);
    req.hdr.nlmsg_type   = RTM_GETLINK;
    req.hdr.nlmsg_flags  = NLM_F_REQUEST | NLM_F_DUMP;
    req.req.rtgen_family = AF_UNSPEC;

    sock.send(&mut [as_iovec(&mut req)])?;
    sock.recv(|data: &ifinfomsg, mut tail: Attrs| {
        let mut link = Link::default();

        link.index = data.ifi_index as u32;
        link.flags = data.ifi_flags as u32;

        while let Some((head, data)) = tail.next::<rtattr>() {
            match head.rta_type {
                IFLA_IFNAME  => link.name  = data.string(),
                IFLA_ADDRESS => link.mac   = MacAddress::new(*data.cast()),
                IFLA_MTU     => link.mtu   = *data.cast(),
                IFLA_XDP     => link.xdp   = xdp(data.attrs()),
                _            => (),
            }
        }

        Ok(link)
    })
}

fn xdp(mut attrs: Attrs) -> Xdp {
    let mut xdp = Xdp::default();
    while let Some((head, data)) = attrs.next::<nlattr>() {
        match head.nla_type {
            IFLA_XDP_FD       => xdp.fd       = *data.cast::<c_int>() as u32,
            IFLA_XDP_ATTACHED => xdp.attached = *data.cast::<u8>() == 1,
            IFLA_XDP_FLAGS    => xdp.flags    = *data.cast(),
            IFLA_XDP_PROG_ID  => xdp.prog_id  = *data.cast(),
            _                 => ()
        }
    }
    xdp
}