From 9de99cea90fff29fba8860c9541aaa6c05850609 Mon Sep 17 00:00:00 2001 From: Gris Ge Date: Tue, 21 Jan 2025 09:25:10 +0800 Subject: [PATCH] New function to forward ACK/DONE/NOOP message to handler Introducing these public functions to allow forwarding ACK/DONE/NOOP message to handler: * `Connection::set_forward_noop()` * `Connection::set_forward_done()` * `Connection::set_forward_ack()` By default, we still drop these messages, so rtnetlink/ethtool crates will not be impacted. If any protocol require the handle of ACK/DONE/NOOP in handler, please invoke these functions during connection setup( e.g. rtnetlink has function `new_connection()`). Signed-off-by: Gris Ge --- src/connection.rs | 51 ++++++++++++++++++++++++++++++++++++----------- src/handle.rs | 3 +-- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/src/connection.rs b/src/connection.rs index 692f632..2dc648f 100644 --- a/src/connection.rs +++ b/src/connection.rs @@ -50,6 +50,10 @@ where Option, SocketAddr)>>, socket_closed: bool, + + forward_noop: bool, + forward_done: bool, + forward_ack: bool, } impl Connection @@ -73,9 +77,27 @@ where requests_rx: Some(requests_rx), unsolicited_messages_tx: Some(unsolicited_messages_tx), socket_closed: false, + forward_noop: false, + forward_done: false, + forward_ack: false, }) } + /// Whether [NetlinkPayload::Noop] should forwared to handler + pub fn set_forward_noop(&mut self, value: bool) { + self.forward_noop = value; + } + + /// Whether [NetlinkPayload::Done] should forwared to handler + pub fn set_forward_done(&mut self, value: bool) { + self.forward_done = value; + } + + /// Whether [NetlinkPayload::Ack] should forwared to handler + pub fn set_forward_ack(&mut self, value: bool) { + self.forward_ack = value; + } + pub fn socket_mut(&mut self) -> &mut S { self.socket.get_mut() } @@ -218,7 +240,7 @@ where || self .unsolicited_messages_tx .as_ref() - .map_or(true, |x| x.is_closed()) + .is_none_or(|x| x.is_closed()) { // The channel is closed so we can drop the sender. let _ = self.unsolicited_messages_tx.take(); @@ -242,6 +264,12 @@ where if done { use NetlinkPayload::*; match &message.payload { + Noop => { + if !self.forward_noop { + trace!("Not forwarding Noop message to the handle"); + continue; + } + } // Since `self.protocol` set the `done` flag here, // we know it has already dropped the request and // its associated metadata, ie the UnboundedSender @@ -250,12 +278,11 @@ where // dropping the last instance of that sender, // hence closing the channel and signaling the // handle that no more messages are expected. - Noop | Done(_) => { - trace!( - "not forwarding Noop/Ack/Done message to \ - the handle" - ); - continue; + Done(_) => { + if !self.forward_done { + trace!("Not forwarding Done message to the handle"); + continue; + } } // I'm not sure how we should handle overrun messages Overrun(_) => unimplemented!("overrun is not handled yet"), @@ -264,11 +291,8 @@ where // because only the user knows how they want to // handle them. Error(err_msg) => { - if err_msg.code.is_none() { - trace!( - "not forwarding Noop/Ack/Done message to \ - the handle" - ); + if err_msg.code.is_none() && !self.forward_ack { + trace!("Not forwarding Ack message to the handle"); continue; } } @@ -314,6 +338,9 @@ where requests_rx: Some(requests_rx), unsolicited_messages_tx: Some(unsolicited_messages_tx), socket_closed: false, + forward_noop: false, + forward_done: false, + forward_ack: false, } } } diff --git a/src/handle.rs b/src/handle.rs index 7155444..2ef97f3 100644 --- a/src/handle.rs +++ b/src/handle.rs @@ -32,8 +32,7 @@ where /// - **acknowledgements**: when an acknowledgement is received, the stream /// is closed /// - **end of dump messages**: similarly, upon receiving an "end of dump" - /// message, the stream is - /// closed + /// message, the stream is closed pub fn request( &self, message: NetlinkMessage,