33use anyhow:: Context ;
44use log:: warn;
55use netlink_packet_utils:: {
6- nla:: NlasIterator , parsers:: parse_string, DecodeError ,
6+ nla:: NlasIterator ,
7+ parsers:: { parse_string, parse_u32} ,
8+ DecodeError ,
79} ;
810
911const ETHTOOL_A_BITSET_BITS : u16 = 3 ;
@@ -14,9 +16,16 @@ const ETHTOOL_A_BITSET_BIT_INDEX: u16 = 1;
1416const ETHTOOL_A_BITSET_BIT_NAME : u16 = 2 ;
1517const ETHTOOL_A_BITSET_BIT_VALUE : u16 = 3 ;
1618
19+ #[ derive( Debug , PartialEq , Eq , Clone , Default ) ]
20+ pub ( crate ) struct EthtoolBitSet {
21+ pub ( crate ) index : u32 ,
22+ pub ( crate ) name : String ,
23+ pub ( crate ) value : bool ,
24+ }
25+
1726pub ( crate ) fn parse_bitset_bits_nlas (
1827 raw : & [ u8 ] ,
19- ) -> Result < Vec < String > , DecodeError > {
28+ ) -> Result < Vec < EthtoolBitSet > , DecodeError > {
2029 let error_msg = "failed to parse mode bit sets" ;
2130 for nla in NlasIterator :: new ( raw) {
2231 let nla = & nla. context ( error_msg) ?;
@@ -27,28 +36,55 @@ pub(crate) fn parse_bitset_bits_nlas(
2736 Err ( "No ETHTOOL_A_BITSET_BITS NLA found" . into ( ) )
2837}
2938
30- fn parse_bitset_bits_nla ( raw : & [ u8 ] ) -> Result < Vec < String > , DecodeError > {
31- let mut modes = Vec :: new ( ) ;
39+ pub ( crate ) fn parse_bitset_bits_string_nlas (
40+ raw : & [ u8 ] ,
41+ ) -> Result < Vec < String > , DecodeError > {
42+ let error_msg = "failed to parse mode bit sets" ;
43+ for nla in NlasIterator :: new ( raw) {
44+ let nla = & nla. context ( error_msg) ?;
45+ if nla. kind ( ) == ETHTOOL_A_BITSET_BITS {
46+ let bits = parse_bitset_bits_nla ( nla. value ( ) ) ?;
47+
48+ return Ok ( bits
49+ . into_iter ( )
50+ . filter_map ( |b| if b. value { Some ( b. name ) } else { None } )
51+ . collect :: < Vec < String > > ( ) ) ;
52+ }
53+ }
54+ Err ( "No ETHTOOL_A_BITSET_BITS NLA found" . into ( ) )
55+ }
56+
57+ fn parse_bitset_bits_nla (
58+ raw : & [ u8 ] ,
59+ ) -> Result < Vec < EthtoolBitSet > , DecodeError > {
60+ let mut bit_sets = Vec :: new ( ) ;
3261 let error_msg = "Failed to parse ETHTOOL_A_BITSET_BITS attributes" ;
3362 for bit_nla in NlasIterator :: new ( raw) {
3463 let bit_nla = & bit_nla. context ( error_msg) ?;
3564 match bit_nla. kind ( ) {
3665 ETHTOOL_A_BITSET_BITS_BIT => {
3766 let error_msg =
3867 "Failed to parse ETHTOOL_A_BITSET_BITS_BIT attributes" ;
68+ let mut bit_set = EthtoolBitSet :: default ( ) ;
3969 let nlas = NlasIterator :: new ( bit_nla. value ( ) ) ;
4070 for nla in nlas {
4171 let nla = & nla. context ( error_msg) ?;
4272 let payload = nla. value ( ) ;
4373 match nla. kind ( ) {
44- ETHTOOL_A_BITSET_BIT_INDEX
45- | ETHTOOL_A_BITSET_BIT_VALUE => {
46- // ignored
74+ ETHTOOL_A_BITSET_BIT_INDEX => {
75+ bit_set. index =
76+ parse_u32 ( payload) . context ( format ! (
77+ "Invalid ETHTOOL_A_BITSET_BIT_INDEX \
78+ value {payload:?}"
79+ ) ) ?;
80+ }
81+ ETHTOOL_A_BITSET_BIT_VALUE => {
82+ bit_set. value = true ;
4783 }
4884 ETHTOOL_A_BITSET_BIT_NAME => {
49- modes . push ( parse_string ( payload) . context (
85+ bit_set . name = parse_string ( payload) . context (
5086 "Invald ETHTOOL_A_BITSET_BIT_NAME value" ,
51- ) ?) ;
87+ ) ?;
5288 }
5389 _ => {
5490 warn ! (
@@ -59,6 +95,7 @@ fn parse_bitset_bits_nla(raw: &[u8]) -> Result<Vec<String>, DecodeError> {
5995 }
6096 }
6197 }
98+ bit_sets. push ( bit_set) ;
6299 }
63100 _ => {
64101 warn ! (
@@ -69,5 +106,5 @@ fn parse_bitset_bits_nla(raw: &[u8]) -> Result<Vec<String>, DecodeError> {
69106 }
70107 } ;
71108 }
72- Ok ( modes )
109+ Ok ( bit_sets )
73110}
0 commit comments