neli icon indicating copy to clipboard operation
neli copied to clipboard

Using neli to retrieve `qdisc` information

Open mmynk opened this issue 1 year ago • 7 comments

Is this a question about neli specifically? If so, please describe. I'm trying to use neli to retrieve qdisc information similar to the tc binary, basically receive something similar to the output of this command:

tc -s qdisc show

I used strace to debug the netlink commands and was trying to implement the same using neli. However, I couldn't really get it to work.

strace -s 100 -f -o out -x tc -s qdisc show

Output: https://gist.github.com/mmynk/ca4327d659956405bf1a0302ab7fd182#file-tc-strace-log

Here's what I have so far: https://gist.github.com/mmynk/ca4327d659956405bf1a0302ab7fd182#file-tc_neli-rs

However, it runs into an error:

Application error was returned by netlink: Nlmsgerr { error: -2, nlmsg: NlmsghdrErr { nl_len: 36, nl_type: GenlId(Pmcraid), nl_flags: NlmF(769), nl_seq: 0, nl_pid: 58092, nl_payload: Ifinfomsg { ifi_family: Unspecified, padding: 0, ifi_type: Netrom, ifi_index: 0, ifi_flags: Iff(0), ifi_change: Iff(0), rtattrs: RtBuffer([Rtattr { rta_len: 4, rta_type: ExtMask, rta_payload: Buffer }]) } }, ext_ack: GenlBuffer([]) }

mmynk avatar Sep 07 '23 19:09 mmynk

Looks like I was using the wrong protocol to connect: NETLINK_GENERIC instead of NETLINK_ROUTE. I receive two messages now but I do not know how to parse them.

msg: Nlmsghdr { nl_len: 1404, nl_type: GenlId(Ctrl), nl_flags: NlmF(2), nl_seq: 0, nl_pid: 58517, nl_payload: Payload(Ifinfomsg { ifi_family: Unspecified, padding: 0, ifi_type: Loopback, ifi_index: 1, ifi_flags: Iff(65609), ifi_change: Iff(0), rtattrs: RtBuffer([Rtattr { rta_len: 7, rta_type: Ifname, rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: Txqlen, rta_payload: Buffer }, Rtattr { rta_len: 5, rta_type: Operstate, rta_payload: Buffer }, Rtattr { rta_len: 5, rta_type: Linkmode, rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: Mtu, rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: MinMtu, rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: MaxMtu, rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: Group, rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: Promiscuity, rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: UnrecognizedConst(61), rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: NumTxQueues, rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: GsoMaxSegs, rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: GsoMaxSize, rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: UnrecognizedConst(58), rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: UnrecognizedConst(59), rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: UnrecognizedConst(60), rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: NumRxQueues, rta_payload: Buffer }, Rtattr { rta_len: 5, rta_type: Carrier, rta_payload: Buffer }, Rtattr { rta_len: 12, rta_type: Qdisc, rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: CarrierChanges, rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: CarrierUpCount, rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: CarrierDownCount, rta_payload: Buffer }, Rtattr { rta_len: 5, rta_type: ProtoDown, rta_payload: Buffer }, Rtattr { rta_len: 36, rta_type: Map, rta_payload: Buffer }, Rtattr { rta_len: 10, rta_type: Address, rta_payload: Buffer }, Rtattr { rta_len: 10, rta_type: Broadcast, rta_payload: Buffer }, Rtattr { rta_len: 204, rta_type: Stats64, rta_payload: Buffer }, Rtattr { rta_len: 100, rta_type: Stats, rta_payload: Buffer }, Rtattr { rta_len: 12, rta_type: Xdp, rta_payload: Buffer }, Rtattr { rta_len: 804, rta_type: AfSpec, rta_payload: Buffer }, Rtattr { rta_len: 4, rta_type: UnrecognizedConst(32830), rta_payload: Buffer }]) }) }


msg: Nlmsghdr { nl_len: 1432, nl_type: GenlId(Ctrl), nl_flags: NlmF(2), nl_seq: 0, nl_pid: 58517, nl_payload: Payload(Ifinfomsg { ifi_family: Unspecified, padding: 0, ifi_type: Ether, ifi_index: 2, ifi_flags: Iff(69699), ifi_change: Iff(0), rtattrs: RtBuffer([Rtattr { rta_len: 9, rta_type: Ifname, rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: Txqlen, rta_payload: Buffer }, Rtattr { rta_len: 5, rta_type: Operstate, rta_payload: Buffer }, Rtattr { rta_len: 5, rta_type: Linkmode, rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: Mtu, rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: MinMtu, rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: MaxMtu, rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: Group, rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: Promiscuity, rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: UnrecognizedConst(61), rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: NumTxQueues, rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: GsoMaxSegs, rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: GsoMaxSize, rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: UnrecognizedConst(58), rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: UnrecognizedConst(59), rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: UnrecognizedConst(60), rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: NumRxQueues, rta_payload: Buffer }, Rtattr { rta_len: 5, rta_type: Carrier, rta_payload: Buffer }, Rtattr { rta_len: 7, rta_type: Qdisc, rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: CarrierChanges, rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: CarrierUpCount, rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: CarrierDownCount, rta_payload: Buffer }, Rtattr { rta_len: 5, rta_type: ProtoDown, rta_payload: Buffer }, Rtattr { rta_len: 36, rta_type: Map, rta_payload: Buffer }, Rtattr { rta_len: 10, rta_type: Address, rta_payload: Buffer }, Rtattr { rta_len: 10, rta_type: Broadcast, rta_payload: Buffer }, Rtattr { rta_len: 204, rta_type: Stats64, rta_payload: Buffer }, Rtattr { rta_len: 100, rta_type: Stats, rta_payload: Buffer }, Rtattr { rta_len: 12, rta_type: Xdp, rta_payload: Buffer }, Rtattr { rta_len: 10, rta_type: PermAddress, rta_payload: Buffer }, Rtattr { rta_len: 792, rta_type: AfSpec, rta_payload: Buffer }, Rtattr { rta_len: 17, rta_type: UnrecognizedConst(56), rta_payload: Buffer }, Rtattr { rta_len: 8, rta_type: UnrecognizedConst(57), rta_payload: Buffer }, Rtattr { rta_len: 4, rta_type: UnrecognizedConst(32830), rta_payload: Buffer }]) }) }
=====================

mmynk avatar Sep 07 '23 20:09 mmynk

Does neli have decoding support similar to pyroute2:decoder.py?

mmynk avatar Sep 07 '23 21:09 mmynk

What information are you looking to get out of the message? Are you looking to parse the route attributes?

jbaublitz avatar Sep 08 '23 04:09 jbaublitz

Thanks for the reply. That’s exactly what I’m trying to do, yes.

mmynk avatar Sep 08 '23 11:09 mmynk

Please see the examples directory for an example of how to use the API for route netlink. route-list.rs has some pretty involved usage in terms of how to get attributes from a routing message.

jbaublitz avatar Sep 09 '23 17:09 jbaublitz

Those examples use IpAddr for parsing the buffer. How do I parse, say Ifla::Stats or Ifla::Stats64?

// for stats64
let mut bytes = [0u8; 200];
buf.read_exact(&mut bytes);
// TODO: ???

Do I need to define the entire data structure of Stats for parsing this?

mmynk avatar Sep 11 '23 19:09 mmynk

Yes, you would need to define the data structure, implementing ToBytes and FromBytes to handle the conversion.

jbaublitz avatar Nov 03 '23 18:11 jbaublitz