1
1
// SPDX-License-Identifier: MIT
2
2
3
- use std:: { fmt, io, mem:: size_of, num :: NonZeroI32 } ;
3
+ use std:: { fmt, io, mem:: size_of} ;
4
4
5
5
use byteorder:: { ByteOrder , NativeEndian } ;
6
6
use netlink_packet_utils:: DecodeError ;
@@ -46,14 +46,10 @@ impl<T: AsRef<[u8]>> ErrorBuffer<T> {
46
46
}
47
47
}
48
48
49
- /// Return the error code.
50
- ///
51
- /// Returns `None` when there is no error to report (the message is an ACK),
52
- /// or a `Some(e)` if there is a non-zero error code `e` to report (the
53
- /// message is a NACK).
54
- pub fn code ( & self ) -> Option < NonZeroI32 > {
49
+ /// Return the error code
50
+ pub fn code ( & self ) -> i32 {
55
51
let data = self . buffer . as_ref ( ) ;
56
- NonZeroI32 :: new ( NativeEndian :: read_i32 ( & data[ CODE ] ) )
52
+ NativeEndian :: read_i32 ( & data[ CODE ] )
57
53
}
58
54
}
59
55
@@ -81,36 +77,22 @@ impl<T: AsRef<[u8]> + AsMut<[u8]>> ErrorBuffer<T> {
81
77
}
82
78
}
83
79
84
- /// An `NLMSG_ERROR` message.
85
- ///
86
- /// Per [RFC 3549 section 2.3.2.2], this message carries the return code for a
87
- /// request which will indicate either success (an ACK) or failure (a NACK).
88
- ///
89
- /// [RFC 3549 section 2.3.2.2]: https://datatracker.ietf.org/doc/html/rfc3549#section-2.3.2.2
90
80
#[ derive( Debug , Default , Clone , PartialEq , Eq ) ]
91
81
#[ non_exhaustive]
92
82
pub struct ErrorMessage {
93
- /// The error code.
94
- ///
95
- /// Holds `None` when there is no error to report (the message is an ACK),
96
- /// or a `Some(e)` if there is a non-zero error code `e` to report (the
97
- /// message is a NACK).
98
- ///
99
- /// See [Netlink message types] for details.
100
- ///
101
- /// [Netlink message types]: https://kernel.org/doc/html/next/userspace-api/netlink/intro.html#netlink-message-types
102
- pub code : Option < NonZeroI32 > ,
103
- /// The original request's header.
83
+ pub code : i32 ,
104
84
pub header : Vec < u8 > ,
105
85
}
106
86
87
+ pub type AckMessage = ErrorMessage ;
88
+
107
89
impl Emitable for ErrorMessage {
108
90
fn buffer_len ( & self ) -> usize {
109
91
size_of :: < i32 > ( ) + self . header . len ( )
110
92
}
111
93
fn emit ( & self , buffer : & mut [ u8 ] ) {
112
94
let mut buffer = ErrorBuffer :: new ( buffer) ;
113
- buffer. set_code ( self . raw_code ( ) ) ;
95
+ buffer. set_code ( self . code ) ;
114
96
buffer. payload_mut ( ) . copy_from_slice ( & self . header )
115
97
}
116
98
}
@@ -137,18 +119,13 @@ impl<'buffer, T: AsRef<[u8]> + 'buffer> Parseable<ErrorBuffer<&'buffer T>>
137
119
}
138
120
139
121
impl ErrorMessage {
140
- /// Returns the raw error code.
141
- pub fn raw_code ( & self ) -> i32 {
142
- self . code . map_or ( 0 , NonZeroI32 :: get)
143
- }
144
-
145
122
/// According to [`netlink(7)`](https://linux.die.net/man/7/netlink)
146
123
/// the `NLMSG_ERROR` return Negative errno or 0 for acknowledgements.
147
124
///
148
125
/// convert into [`std::io::Error`](https://doc.rust-lang.org/std/io/struct.Error.html)
149
126
/// using the absolute value from errno code
150
127
pub fn to_io ( & self ) -> io:: Error {
151
- io:: Error :: from_raw_os_error ( self . raw_code ( ) . abs ( ) )
128
+ io:: Error :: from_raw_os_error ( self . code . abs ( ) )
152
129
}
153
130
}
154
131
@@ -172,7 +149,7 @@ mod tests {
172
149
fn into_io_error ( ) {
173
150
let io_err = io:: Error :: from_raw_os_error ( 95 ) ;
174
151
let err_msg = ErrorMessage {
175
- code : NonZeroI32 :: new ( -95 ) ,
152
+ code : -95 ,
176
153
header : vec ! [ ] ,
177
154
} ;
178
155
@@ -181,40 +158,4 @@ mod tests {
181
158
assert_eq ! ( err_msg. to_string( ) , io_err. to_string( ) ) ;
182
159
assert_eq ! ( to_io. raw_os_error( ) , io_err. raw_os_error( ) ) ;
183
160
}
184
-
185
- #[ test]
186
- fn parse_ack ( ) {
187
- let bytes = vec ! [ 0 , 0 , 0 , 0 ] ;
188
- let msg = ErrorBuffer :: new_checked ( & bytes)
189
- . and_then ( |buf| ErrorMessage :: parse ( & buf) )
190
- . expect ( "failed to parse NLMSG_ERROR" ) ;
191
- assert_eq ! (
192
- ErrorMessage {
193
- code: None ,
194
- header: Vec :: new( )
195
- } ,
196
- msg
197
- ) ;
198
- assert_eq ! ( msg. raw_code( ) , 0 ) ;
199
- }
200
-
201
- #[ test]
202
- fn parse_nack ( ) {
203
- // SAFETY: value is non-zero.
204
- const ERROR_CODE : NonZeroI32 =
205
- unsafe { NonZeroI32 :: new_unchecked ( -1234 ) } ;
206
- let mut bytes = vec ! [ 0 , 0 , 0 , 0 ] ;
207
- NativeEndian :: write_i32 ( & mut bytes, ERROR_CODE . get ( ) ) ;
208
- let msg = ErrorBuffer :: new_checked ( & bytes)
209
- . and_then ( |buf| ErrorMessage :: parse ( & buf) )
210
- . expect ( "failed to parse NLMSG_ERROR" ) ;
211
- assert_eq ! (
212
- ErrorMessage {
213
- code: Some ( ERROR_CODE ) ,
214
- header: Vec :: new( )
215
- } ,
216
- msg
217
- ) ;
218
- assert_eq ! ( msg. raw_code( ) , ERROR_CODE . get( ) ) ;
219
- }
220
161
}
0 commit comments