Skip to main content

starnix_core/vfs/socket/socket_generic_netlink/
messages.rs

1// Copyright 2022 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use netlink_packet_core::{NetlinkDeserializable, NetlinkHeader, NetlinkSerializable};
6use netlink_packet_generic::GenlMessage;
7use netlink_packet_generic::constants::GENL_ID_CTRL;
8use netlink_packet_generic::ctrl::GenlCtrl;
9use netlink_packet_generic::message::EmptyDeserializeOptions;
10use netlink_packet_utils::DecodeError;
11
12#[derive(Clone, Debug)]
13pub enum GenericMessage {
14    /// The default supported Netlink Control protocol.
15    Ctrl(GenlMessage<GenlCtrl>),
16    /// Any other Netlink protocol. Netlink family servers should perform their own
17    /// parsing on the given payload, likely also using GenlMessage/GenlFamily.
18    Other { family: u16, payload: Vec<u8> },
19}
20
21impl NetlinkDeserializable for GenericMessage {
22    type DeserializeOptions = EmptyDeserializeOptions;
23    type Error = DecodeError;
24
25    fn deserialize(
26        header: &NetlinkHeader,
27        payload: &[u8],
28        options: EmptyDeserializeOptions,
29    ) -> Result<Self, Self::Error> {
30        match header.message_type {
31            GENL_ID_CTRL => GenlMessage::<GenlCtrl>::deserialize(header, payload, options)
32                .map(GenericMessage::Ctrl),
33            family => Ok(GenericMessage::Other { family, payload: payload.to_vec() }),
34        }
35    }
36}
37
38impl NetlinkSerializable for GenericMessage {
39    fn message_type(&self) -> u16 {
40        match self {
41            GenericMessage::Ctrl(c) => NetlinkSerializable::message_type(c),
42            GenericMessage::Other { family, .. } => *family,
43        }
44    }
45    fn buffer_len(&self) -> usize {
46        match self {
47            GenericMessage::Ctrl(c) => NetlinkSerializable::buffer_len(c),
48            GenericMessage::Other { payload, .. } => payload.len(),
49        }
50    }
51    fn serialize(&self, buffer: &mut [u8]) {
52        match self {
53            GenericMessage::Ctrl(c) => NetlinkSerializable::serialize(c, buffer),
54            GenericMessage::Other { payload, .. } => buffer.copy_from_slice(&payload[..]),
55        }
56    }
57}