202 lines
5.6 KiB
Rust
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),
|
|
}
|
|
}
|
|
}
|