Skip to content

Commit 0e486c3

Browse files
committed
Revert "Merge NetlinkPayload::{Ack,Error}"
This reverts commit 52732b3. Signed-off-by: Gris Ge <[email protected]>
1 parent 52732b3 commit 0e486c3

File tree

3 files changed

+22
-104
lines changed

3 files changed

+22
-104
lines changed

src/error.rs

Lines changed: 10 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// SPDX-License-Identifier: MIT
22

3-
use std::{fmt, io, mem::size_of, num::NonZeroI32};
3+
use std::{fmt, io, mem::size_of};
44

55
use byteorder::{ByteOrder, NativeEndian};
66
use netlink_packet_utils::DecodeError;
@@ -46,14 +46,10 @@ impl<T: AsRef<[u8]>> ErrorBuffer<T> {
4646
}
4747
}
4848

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 {
5551
let data = self.buffer.as_ref();
56-
NonZeroI32::new(NativeEndian::read_i32(&data[CODE]))
52+
NativeEndian::read_i32(&data[CODE])
5753
}
5854
}
5955

@@ -81,36 +77,22 @@ impl<T: AsRef<[u8]> + AsMut<[u8]>> ErrorBuffer<T> {
8177
}
8278
}
8379

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
9080
#[derive(Debug, Default, Clone, PartialEq, Eq)]
9181
#[non_exhaustive]
9282
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,
10484
pub header: Vec<u8>,
10585
}
10686

87+
pub type AckMessage = ErrorMessage;
88+
10789
impl Emitable for ErrorMessage {
10890
fn buffer_len(&self) -> usize {
10991
size_of::<i32>() + self.header.len()
11092
}
11193
fn emit(&self, buffer: &mut [u8]) {
11294
let mut buffer = ErrorBuffer::new(buffer);
113-
buffer.set_code(self.raw_code());
95+
buffer.set_code(self.code);
11496
buffer.payload_mut().copy_from_slice(&self.header)
11597
}
11698
}
@@ -137,18 +119,13 @@ impl<'buffer, T: AsRef<[u8]> + 'buffer> Parseable<ErrorBuffer<&'buffer T>>
137119
}
138120

139121
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-
145122
/// According to [`netlink(7)`](https://linux.die.net/man/7/netlink)
146123
/// the `NLMSG_ERROR` return Negative errno or 0 for acknowledgements.
147124
///
148125
/// convert into [`std::io::Error`](https://doc.rust-lang.org/std/io/struct.Error.html)
149126
/// using the absolute value from errno code
150127
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())
152129
}
153130
}
154131

@@ -172,7 +149,7 @@ mod tests {
172149
fn into_io_error() {
173150
let io_err = io::Error::from_raw_os_error(95);
174151
let err_msg = ErrorMessage {
175-
code: NonZeroI32::new(-95),
152+
code: -95,
176153
header: vec![],
177154
};
178155

@@ -181,40 +158,4 @@ mod tests {
181158
assert_eq!(err_msg.to_string(), io_err.to_string());
182159
assert_eq!(to_io.raw_os_error(), io_err.raw_os_error());
183160
}
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-
}
220161
}

src/message.rs

Lines changed: 9 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use netlink_packet_utils::DecodeError;
77

88
use crate::{
99
payload::{NLMSG_DONE, NLMSG_ERROR, NLMSG_NOOP, NLMSG_OVERRUN},
10-
DoneBuffer, DoneMessage, Emitable, ErrorBuffer, ErrorMessage,
10+
AckMessage, DoneBuffer, DoneMessage, Emitable, ErrorBuffer, ErrorMessage,
1111
NetlinkBuffer, NetlinkDeserializable, NetlinkHeader, NetlinkPayload,
1212
NetlinkSerializable, Parseable,
1313
};
@@ -101,7 +101,11 @@ where
101101
let msg = ErrorBuffer::new_checked(&bytes)
102102
.and_then(|buf| ErrorMessage::parse(&buf))
103103
.context("failed to parse NLMSG_ERROR")?;
104-
Error(msg)
104+
if msg.code >= 0 {
105+
Ack(msg as AckMessage)
106+
} else {
107+
Error(msg)
108+
}
105109
}
106110
NLMSG_NOOP => Noop,
107111
NLMSG_DONE => {
@@ -134,6 +138,7 @@ where
134138
Done(ref msg) => msg.buffer_len(),
135139
Overrun(ref bytes) => bytes.len(),
136140
Error(ref msg) => msg.buffer_len(),
141+
Ack(ref msg) => msg.buffer_len(),
137142
InnerMessage(ref msg) => msg.buffer_len(),
138143
};
139144

@@ -152,6 +157,7 @@ where
152157
Done(ref msg) => msg.emit(buffer),
153158
Overrun(ref bytes) => buffer.copy_from_slice(bytes),
154159
Error(ref msg) => msg.emit(buffer),
160+
Ack(ref msg) => msg.emit(buffer),
155161
InnerMessage(ref msg) => msg.serialize(buffer),
156162
}
157163
}
@@ -173,7 +179,7 @@ where
173179
mod tests {
174180
use super::*;
175181

176-
use std::{convert::Infallible, mem::size_of, num::NonZeroI32};
182+
use std::{convert::Infallible, mem::size_of};
177183

178184
#[derive(Clone, Debug, Default, PartialEq)]
179185
struct FakeNetlinkInnerMessage;
@@ -234,34 +240,4 @@ mod tests {
234240
let got = NetlinkMessage::parse(&NetlinkBuffer::new(&buf)).unwrap();
235241
assert_eq!(got, want);
236242
}
237-
238-
#[test]
239-
fn test_error() {
240-
// SAFETY: value is non-zero.
241-
const ERROR_CODE: NonZeroI32 =
242-
unsafe { NonZeroI32::new_unchecked(-8765) };
243-
244-
let header = NetlinkHeader::default();
245-
let error_msg = ErrorMessage {
246-
code: Some(ERROR_CODE),
247-
header: vec![],
248-
};
249-
let mut want = NetlinkMessage::new(
250-
header,
251-
NetlinkPayload::<FakeNetlinkInnerMessage>::Error(error_msg.clone()),
252-
);
253-
want.finalize();
254-
255-
let len = want.buffer_len();
256-
assert_eq!(len, header.buffer_len() + error_msg.buffer_len());
257-
258-
let mut buf = vec![1; len];
259-
want.emit(&mut buf);
260-
261-
let error_buf = ErrorBuffer::new(&buf[header.buffer_len()..]);
262-
assert_eq!(error_buf.code(), error_msg.code);
263-
264-
let got = NetlinkMessage::parse(&NetlinkBuffer::new(&buf)).unwrap();
265-
assert_eq!(got, want);
266-
}
267243
}

src/payload.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
use std::fmt::Debug;
44

5-
use crate::{DoneMessage, ErrorMessage, NetlinkSerializable};
5+
use crate::{AckMessage, DoneMessage, ErrorMessage, NetlinkSerializable};
66

77
/// The message is ignored.
88
pub const NLMSG_NOOP: u16 = 1;
@@ -20,6 +20,7 @@ pub const NLMSG_ALIGNTO: u16 = 4;
2020
pub enum NetlinkPayload<I> {
2121
Done(DoneMessage),
2222
Error(ErrorMessage),
23+
Ack(AckMessage),
2324
Noop,
2425
Overrun(Vec<u8>),
2526
InnerMessage(I),
@@ -32,7 +33,7 @@ where
3233
pub fn message_type(&self) -> u16 {
3334
match self {
3435
NetlinkPayload::Done(_) => NLMSG_DONE,
35-
NetlinkPayload::Error(_) => NLMSG_ERROR,
36+
NetlinkPayload::Error(_) | NetlinkPayload::Ack(_) => NLMSG_ERROR,
3637
NetlinkPayload::Noop => NLMSG_NOOP,
3738
NetlinkPayload::Overrun(_) => NLMSG_OVERRUN,
3839
NetlinkPayload::InnerMessage(message) => message.message_type(),

0 commit comments

Comments
 (0)