nmstate/ifaces/
mac_vtap.rs1use serde::{Deserialize, Serialize};
4
5use crate::{BaseInterface, ErrorKind, InterfaceType, NmstateError};
6
7#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
8#[non_exhaustive]
9pub struct MacVtapInterface {
23 #[serde(flatten)]
24 pub base: BaseInterface,
25 #[serde(skip_serializing_if = "Option::is_none", rename = "mac-vtap")]
26 pub mac_vtap: Option<MacVtapConfig>,
28}
29
30impl Default for MacVtapInterface {
31 fn default() -> Self {
32 Self {
33 base: BaseInterface {
34 iface_type: InterfaceType::MacVtap,
35 ..Default::default()
36 },
37 mac_vtap: None,
38 }
39 }
40}
41
42impl MacVtapInterface {
43 pub fn new() -> Self {
44 Self::default()
45 }
46
47 pub(crate) fn sanitize(
48 &self,
49 is_desired: bool,
50 ) -> Result<(), NmstateError> {
51 if is_desired {
52 if let Some(conf) = &self.mac_vtap {
53 if conf.accept_all_mac == Some(false)
54 && conf.mode != MacVtapMode::Passthru
55 {
56 let e = NmstateError::new(
57 ErrorKind::InvalidArgument,
58 "Disable accept-all-mac-addresses(promiscuous) is \
59 only allowed on passthru mode"
60 .to_string(),
61 );
62 log::error!("{e}");
63 return Err(e);
64 }
65 }
66 }
67 Ok(())
68 }
69
70 pub(crate) fn parent(&self) -> Option<&str> {
71 self.mac_vtap.as_ref().map(|cfg| cfg.base_iface.as_str())
72 }
73
74 pub(crate) fn change_parent_name(&mut self, name: &str) {
75 if let Some(mac_vtap_conf) = self.mac_vtap.as_mut() {
76 mac_vtap_conf.base_iface = name.to_string();
77 }
78 }
79}
80
81#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
82#[serde(rename_all = "kebab-case", deny_unknown_fields)]
83#[non_exhaustive]
84pub struct MacVtapConfig {
85 pub base_iface: String,
86 pub mode: MacVtapMode,
87 #[serde(
88 skip_serializing_if = "Option::is_none",
89 rename = "promiscuous",
90 alias = "accept-all-mac",
91 default,
92 deserialize_with = "crate::deserializer::option_bool_or_string"
93 )]
94 pub accept_all_mac: Option<bool>,
97}
98
99#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
100#[serde(rename_all = "kebab-case")]
101#[non_exhaustive]
102#[derive(Default)]
103pub enum MacVtapMode {
104 Vepa,
106 Bridge,
108 Private,
110 Passthru,
112 Source,
114 #[default]
115 Unknown,
116}
117
118impl From<MacVtapMode> for u32 {
119 fn from(v: MacVtapMode) -> u32 {
120 match v {
121 MacVtapMode::Unknown => 0,
122 MacVtapMode::Vepa => 1,
123 MacVtapMode::Bridge => 2,
124 MacVtapMode::Private => 3,
125 MacVtapMode::Passthru => 4,
126 MacVtapMode::Source => 5,
127 }
128 }
129}