Skip to main content

nv_redfish/
ethernet_interface.rs

1// SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2// SPDX-License-Identifier: Apache-2.0
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16//! Ethernet interfaces
17//!
18
19use crate::schema::redfish::ethernet_interface::EthernetInterface as EthernetInterfaceSchema;
20use crate::schema::redfish::ethernet_interface_collection::EthernetInterfaceCollection as EthernetInterfaceCollectionSchema;
21use crate::Error;
22use crate::NvBmc;
23use crate::Resource;
24use crate::ResourceSchema;
25use nv_redfish_core::Bmc;
26use nv_redfish_core::NavProperty;
27use std::marker::PhantomData;
28use std::sync::Arc;
29use tagged_types::TaggedType;
30
31#[doc(inline)]
32pub use crate::schema::redfish::ethernet_interface::LinkStatus;
33
34/// Ethernet interfaces collection.
35///
36/// Provides functions to access collection members.
37pub struct EthernetInterfaceCollection<B: Bmc> {
38    bmc: NvBmc<B>,
39    collection: Arc<EthernetInterfaceCollectionSchema>,
40}
41
42impl<B: Bmc> EthernetInterfaceCollection<B> {
43    /// Create a new manager collection handle.
44    pub(crate) async fn new(
45        bmc: &NvBmc<B>,
46        nav: &NavProperty<EthernetInterfaceCollectionSchema>,
47    ) -> Result<Self, Error<B>> {
48        let collection = bmc.expand_property(nav).await?;
49        Ok(Self {
50            bmc: bmc.clone(),
51            collection,
52        })
53    }
54
55    /// List all managers available in this BMC.
56    ///
57    /// # Errors
58    ///
59    /// Returns an error if fetching manager data fails.
60    pub async fn members(&self) -> Result<Vec<EthernetInterface<B>>, Error<B>> {
61        let mut members = Vec::new();
62        for m in &self.collection.members {
63            members.push(EthernetInterface::new(&self.bmc, m).await?);
64        }
65        Ok(members)
66    }
67}
68
69/// Mac address of the ethernet interface.
70///
71/// Nv-redfish keeps open underlying type for `MacAddress` because it
72/// can be converted to `mac_address::MacAddress`.
73pub type MacAddress<T> = TaggedType<T, MacAddressTag>;
74#[doc(hidden)]
75#[derive(tagged_types::Tag)]
76#[implement(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
77#[transparent(Debug, Display, FromStr, Serialize, Deserialize)]
78#[capability(inner_access)]
79pub enum MacAddressTag {}
80
81/// Uefi device path for the interface.
82///
83/// Nv-redfish keeps open underlying type for `UefiDevicePath` because it
84/// can really be represented by any implementation of UEFI's device path.
85pub type UefiDevicePath<T> = TaggedType<T, UefiDevicePathTag>;
86#[doc(hidden)]
87#[derive(tagged_types::Tag)]
88#[implement(Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
89#[transparent(Debug, Display, FromStr, Serialize, Deserialize)]
90#[capability(inner_access)]
91pub enum UefiDevicePathTag {}
92
93/// Ethernet Interface.
94///
95/// Provides functions to access ethernet interface.
96pub struct EthernetInterface<B: Bmc> {
97    data: Arc<EthernetInterfaceSchema>,
98    _marker: PhantomData<B>,
99}
100
101impl<B: Bmc> EthernetInterface<B> {
102    /// Create a new log service handle.
103    pub(crate) async fn new(
104        bmc: &NvBmc<B>,
105        nav: &NavProperty<EthernetInterfaceSchema>,
106    ) -> Result<Self, Error<B>> {
107        nav.get(bmc.as_ref())
108            .await
109            .map_err(crate::Error::Bmc)
110            .map(|data| Self {
111                data,
112                _marker: PhantomData,
113            })
114    }
115
116    /// Get the raw schema data for this ethernet interface.
117    #[must_use]
118    pub fn raw(&self) -> Arc<EthernetInterfaceSchema> {
119        self.data.clone()
120    }
121
122    /// State of the interface. `None` means that BMC hasn't reported
123    /// interface state or reported null.
124    #[must_use]
125    pub fn interface_enabled(&self) -> Option<bool> {
126        self.data
127            .interface_enabled
128            .as_ref()
129            .and_then(Option::as_ref)
130            .copied()
131    }
132
133    /// Link status of the interface.
134    #[must_use]
135    pub fn link_status(&self) -> Option<LinkStatus> {
136        self.data
137            .link_status
138            .as_ref()
139            .and_then(Option::as_ref)
140            .copied()
141    }
142
143    /// MAC address of the interface.
144    #[must_use]
145    pub fn mac_address(&self) -> Option<MacAddress<&str>> {
146        self.data
147            .mac_address
148            .as_ref()
149            .and_then(Option::as_ref)
150            .map(String::as_str)
151            .map(MacAddress::new)
152    }
153
154    /// UEFI device path for the interface.
155    #[must_use]
156    pub fn uefi_device_path(&self) -> Option<UefiDevicePath<&str>> {
157        self.data
158            .uefi_device_path
159            .as_ref()
160            .and_then(Option::as_ref)
161            .map(String::as_str)
162            .map(UefiDevicePath::new)
163    }
164}
165
166impl<B: Bmc> Resource for EthernetInterface<B> {
167    fn resource_ref(&self) -> &ResourceSchema {
168        &self.data.as_ref().base
169    }
170}