yggdrasil/lib/abi/src/net/netconfig.rs

202 lines
5.6 KiB
Rust

//! Network configuration service messages
use core::net::IpAddr;
use abi_serde::{
des::{DeserializeError, Deserializer},
ser::Serializer,
Deserialize, Serialize,
};
use alloc::boxed::Box;
use super::{MacAddress, SocketInterfaceQuery, SubnetAddr};
/// Describes the binding between interfaces and their IDs
#[derive(Clone, Debug, PartialEq)]
pub struct InterfaceBinding {
/// Name of the interface
pub name: Box<str>,
/// Interface ID
pub id: u32,
}
abi_serde::impl_struct_serde!(InterfaceBinding: [
name,
id
]);
/// Describes a single route
#[derive(Clone, Debug, PartialEq)]
// #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct RouteInfo {
/// Interface textual name (unique)
pub interface_name: Box<str>,
/// Interface unique ID number
pub interface_id: u32,
/// Subnetwork this route is related to
pub subnet: SubnetAddr,
/// Gateway this route should be reached through
pub gateway: Option<IpAddr>,
}
abi_serde::impl_struct_serde!(RouteInfo: [
interface_name,
interface_id,
subnet,
gateway
]);
/// Describes routing information about some address
#[derive(Clone, Debug, PartialEq)]
pub struct RoutingInfo {
/// Interface textual name (unique)
pub interface_name: Box<str>,
/// Interface unique ID number
pub interface_id: u32,
/// Gateway this route should be reached through
pub gateway: Option<IpAddr>,
/// Real destination which should be used
pub destination: IpAddr,
/// IP address used as a source when sending through this route
pub source: Option<IpAddr>,
/// Interface MAC address
pub source_mac: MacAddress,
}
abi_serde::impl_struct_serde!(RoutingInfo: [
interface_name,
interface_id,
gateway,
destination,
source,
source_mac
]);
/// Describes a single interface
#[derive(Clone, Debug, PartialEq)]
pub struct InterfaceInfo {
/// Interface textual name (unique)
pub interface_name: Box<str>,
/// Interface unique ID number
pub interface_id: u32,
/// Interface IP address
pub address: Option<IpAddr>,
/// Interface hardware address
pub mac: MacAddress,
}
abi_serde::impl_struct_serde!(InterfaceInfo: [
interface_name,
interface_id,
address,
mac
]);
/// Describes a request to add a route to an interface
#[derive(Clone, Debug, PartialEq)]
pub struct AddRouteRequest<'a> {
/// Interface to which the action applies
pub interface: SocketInterfaceQuery<'a>,
/// Optional gateway to reach the route through
pub gateway: Option<IpAddr>,
/// Subnetwork of the route
pub subnet: SubnetAddr,
}
abi_serde::impl_struct_serde!(AddRouteRequest<'de>: [
interface,
gateway,
subnet
]);
/// Describes a request to assign a network address to an interface
#[derive(Clone, Debug, PartialEq)]
pub struct SetNetworkAddressRequest<'a> {
/// Interface to which the action applies
pub interface: SocketInterfaceQuery<'a>,
/// Address to assign
pub address: IpAddr,
}
abi_serde::impl_struct_serde!(SetNetworkAddressRequest<'de>: [
interface,
address
]);
/// Describes a request to perform an ARP query
#[derive(Clone, Debug, PartialEq)]
pub struct ArpQueryRequest<'a> {
/// Interface to which the action applies
pub interface: SocketInterfaceQuery<'a>,
/// Address to query
pub address: IpAddr,
/// Whether to actually send any requests, or just lookup the cached result
pub cache_only: bool,
}
abi_serde::impl_struct_serde!(ArpQueryRequest<'de>: [
interface,
address,
cache_only
]);
/// kernel-netconf interface request
#[derive(Clone, Debug, PartialEq)]
pub enum NetConfigRequest<'a> {
/// List all routes
ListRoutes(()),
/// List all interfaces
ListInterfaces(()),
/// Describe routes related to a single interface
DescribeRoutes(SocketInterfaceQuery<'a>),
/// Describe a single interface
DescribeInterface(SocketInterfaceQuery<'a>),
/// Add a route
AddRoute(AddRouteRequest<'a>),
/// Set interface's IP address
SetNetworkAddress(SetNetworkAddressRequest<'a>),
/// Clear interface's IP address
ClearNetworkAddress(SocketInterfaceQuery<'a>),
/// Query a route and return routing information
QueryRoute(IpAddr),
/// Query the MAC address of the specified IP
ArpQuery(ArpQueryRequest<'a>),
}
abi_serde::impl_enum_serde!(NetConfigRequest<'de>: [
ListRoutes => 1,
ListInterfaces => 2,
DescribeRoutes => 3,
DescribeInterface => 4,
AddRoute => 5,
SetNetworkAddress => 6,
ClearNetworkAddress => 7,
QueryRoute => 8,
ArpQuery => 9,
]);
/// Wrapper to provide error status in replies
#[derive(Clone, Debug, PartialEq)]
pub enum NetConfigResult<'a, T> {
/// Success
Ok(T),
/// Error
Err(&'a str),
}
impl<T: Serialize> Serialize for NetConfigResult<'_, T> {
fn serialize<S: Serializer>(&self, serializer: &mut S) -> Result<(), S::Error> {
match self {
Self::Ok(value) => {
serializer.write_enum_variant(0)?;
value.serialize(serializer)
}
Self::Err(error) => {
serializer.write_enum_variant(1)?;
error.serialize(serializer)
}
}
}
}
impl<'de, T: Deserialize<'de>> Deserialize<'de> for NetConfigResult<'de, T> {
fn deserialize<D: Deserializer<'de>>(deserializer: &mut D) -> Result<Self, D::Error> {
match deserializer.read_enum_variant()? {
0 => T::deserialize(deserializer).map(Self::Ok),
1 => <&str>::deserialize(deserializer).map(Self::Err),
_ => Err(D::Error::INVALID_ENUM_VARIANT),
}
}
}