nmstate/query_apply/
inter_ifaces.rs1use crate::{
4 ErrorKind, Interface, InterfaceType, Interfaces, MergedInterfaces,
5 NmstateError,
6 state::{gen_diff_json_value, merge_json_value},
7};
8
9impl Interfaces {
10 pub(crate) fn has_up_ovs_iface(&self) -> bool {
11 self.iter().any(|i| {
12 i.iface_type() == InterfaceType::OvsBridge
13 || i.iface_type() == InterfaceType::OvsInterface
14 })
15 }
16
17 pub fn update(&mut self, other: &Self) {
18 let mut new_ifaces: Vec<Interface> = Vec::new();
19 let other_ifaces = other.to_vec();
20 for other_iface in other_ifaces {
21 let self_iface = if other_iface.is_userspace() {
22 self.get_iface_mut(other_iface.name(), other_iface.iface_type())
23 } else {
24 self.kernel_ifaces.get_mut(other_iface.name())
25 };
26 match self_iface {
27 Some(self_iface) => {
28 if self_iface.iface_type() == InterfaceType::Tun
31 && other_iface.iface_type()
32 == InterfaceType::OvsInterface
33 {
34 if let Interface::OvsInterface(other_ovs_iface) =
35 other_iface
36 {
37 let mut new_iface = other_ovs_iface.clone();
38 new_iface.base = self_iface.base_iface().clone();
39 new_iface.base.state = other_ovs_iface.base.state;
40 new_iface.base.iface_type =
41 InterfaceType::OvsInterface;
42 new_iface
43 .base
44 .controller
45 .clone_from(&other_ovs_iface.base.controller);
46 new_iface.base.controller_type.clone_from(
47 &other_ovs_iface.base.controller_type,
48 );
49 let mut new_iface =
50 Interface::OvsInterface(new_iface);
51 new_iface.update(other_iface);
52 new_ifaces.push(new_iface);
53 }
54 } else {
55 self_iface.update(other_iface);
56 }
57 }
58 None => {
59 new_ifaces.push(other_iface.clone());
60 }
61 }
62 }
63 for new_iface in new_ifaces {
64 self.push(new_iface);
65 }
66 }
67
68 fn remove_unknown_type_port(&mut self) {
69 let mut pending_actions: Vec<(String, InterfaceType, String)> =
70 Vec::new();
71 for iface in
72 self.kernel_ifaces.values().chain(self.user_ifaces.values())
73 {
74 if !iface.is_controller() {
75 continue;
76 }
77 for port_name in find_unknown_type_port(iface, self) {
78 pending_actions.push((
79 iface.name().to_string(),
80 iface.iface_type(),
81 port_name.to_string(),
82 ));
83 }
84 }
85
86 for (ctrl_name, ctrl_type, port_name) in pending_actions {
87 if ctrl_type.is_userspace() {
88 if let Some(iface) =
89 self.user_ifaces.get_mut(&(ctrl_name, ctrl_type))
90 {
91 iface.remove_port(&port_name)
92 }
93 } else if let Some(iface) = self.kernel_ifaces.get_mut(&ctrl_name) {
94 iface.remove_port(&port_name)
95 }
96 }
97 }
98}
99
100fn find_unknown_type_port<'a>(
101 iface: &'a Interface,
102 cur_ifaces: &Interfaces,
103) -> Vec<&'a str> {
104 let mut ret: Vec<&str> = Vec::new();
105 if let Some(port_names) = iface.ports() {
106 for port_name in port_names {
107 if let Some(port_iface) =
108 cur_ifaces.get_iface(port_name, InterfaceType::Unknown)
109 {
110 if port_iface.iface_type() == InterfaceType::Unknown {
111 ret.push(port_name);
112 }
113 } else {
114 ret.push(port_name);
116 }
117 }
118 }
119 ret
120}
121
122fn verify_desire_absent_but_found_in_current(
123 des_iface: &Interface,
124 cur_iface: &Interface,
125) -> Result<(), NmstateError> {
126 if cur_iface.is_virtual() {
127 let e = NmstateError::new(
129 ErrorKind::VerificationError,
130 format!(
131 "Absent/Down interface {}/{} still found as {:?}",
132 des_iface.name(),
133 des_iface.iface_type(),
134 cur_iface
135 ),
136 );
137 log::error!("{e}");
138 Err(e)
139 } else {
140 Ok(())
142 }
143}
144
145impl MergedInterfaces {
146 pub(crate) fn gen_diff(&self) -> Result<Interfaces, NmstateError> {
147 let mut ret = Interfaces::default();
148 for merged_iface in self
149 .kernel_ifaces
150 .values()
151 .chain(self.user_ifaces.values())
152 .filter(|i| i.is_desired() && i.desired != i.current)
153 {
154 let des_iface = if let Some(i) = merged_iface.for_apply.as_ref() {
155 i
156 } else {
157 continue;
158 };
159 let cur_iface = if let Some(i) = merged_iface.current.as_ref() {
160 let mut cur_iface = i.clone();
161 cur_iface.sanitize(false).ok();
162 cur_iface
163 } else {
164 if let Some(origin_des_iface) = &merged_iface.desired {
165 ret.push(origin_des_iface.clone());
166 } else {
167 ret.push(des_iface.clone());
169 }
170 continue;
171 };
172 let desired_value = serde_json::to_value(des_iface)?;
173 let current_value = serde_json::to_value(&cur_iface)?;
174 if let Some(diff_value) =
175 gen_diff_json_value(&desired_value, ¤t_value)
176 {
177 let mut new_iface = des_iface.clone_name_type_only();
178 new_iface.base_iface_mut().state = des_iface.base_iface().state;
179 new_iface.include_diff_context(des_iface, &cur_iface);
180 let mut new_iface_value = serde_json::to_value(&new_iface)?;
181 merge_json_value(&mut new_iface_value, &diff_value);
182 let new_iface =
183 serde_json::from_value::<Interface>(new_iface_value)?;
184 ret.push(new_iface);
185 }
186 }
187 Ok(ret)
188 }
189
190 pub(crate) fn verify(
191 &self,
192 current: &Interfaces,
193 ) -> Result<(), NmstateError> {
194 let mut merged = self.clone();
195 let mut current = current.clone();
196 current.remove_ignored_ifaces(self.ignored_ifaces.as_slice());
197 current.remove_unknown_type_port();
198 merged.process_allow_extra_ovs_patch_ports_for_verify(&mut current);
199
200 for iface in current
201 .kernel_ifaces
202 .values_mut()
203 .chain(current.user_ifaces.values_mut())
204 {
205 iface.sanitize(false).ok();
206 iface.sanitize_current_for_verify();
207 }
208
209 for des_iface in merged.iter_mut().filter(|i| i.is_desired()) {
210 let iface = if let Some(i) = des_iface.for_verify.as_mut() {
211 i
212 } else {
213 continue;
214 };
215 iface.sanitize(false).ok();
216 iface.sanitize_desired_for_verify();
217 }
218
219 for des_iface in merged.iter_mut().filter(|i| i.is_desired()) {
220 let iface = if let Some(i) = des_iface.for_verify.as_mut() {
221 i
222 } else {
223 continue;
224 };
225 if iface.is_absent() || (iface.is_virtual() && iface.is_down()) {
226 if let Some(cur_iface) =
227 current.get_iface(iface.name(), iface.iface_type())
228 {
229 verify_desire_absent_but_found_in_current(
230 iface, cur_iface,
231 )?;
232 }
233 } else if let Some(cur_iface) =
234 current.get_iface(iface.name(), iface.iface_type())
235 {
236 if iface.is_up() {
238 iface.verify(cur_iface)?;
239 if let Interface::Ethernet(eth_iface) = iface
240 && eth_iface.sriov_is_enabled()
241 {
242 eth_iface.verify_sriov(¤t)?;
243 }
244 }
245 } else if iface.is_up() {
246 return Err(NmstateError::new(
247 ErrorKind::VerificationError,
248 format!(
249 "Failed to find desired interface {} {:?}",
250 iface.name(),
251 iface.iface_type()
252 ),
253 ));
254 }
255 }
256 Ok(())
257 }
258}