nmstate/ifaces/
vxlan.rs

1// SPDX-License-Identifier: Apache-2.0
2
3use serde::{Deserialize, Serialize};
4
5use crate::{BaseInterface, InterfaceType};
6
7#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
8#[non_exhaustive]
9/// Linux kernel VxLAN interface. The example yaml output of
10/// [crate::NetworkState] with a VxLAN interface would be:
11/// ```yml
12/// interfaces:
13/// - name: eth1.102
14///   type: vxlan
15///   state: up
16///   mac-address: 0E:00:95:53:19:55
17///   mtu: 1450
18///   min-mtu: 68
19///   max-mtu: 65535
20///   vxlan:
21///     base-iface: eth1
22///     id: 102
23///     remote: 239.1.1.1
24///     destination-port: 1235
25/// ```
26pub struct VxlanInterface {
27    #[serde(flatten)]
28    pub base: BaseInterface,
29    #[serde(skip_serializing_if = "Option::is_none")]
30    pub vxlan: Option<VxlanConfig>,
31}
32
33impl Default for VxlanInterface {
34    fn default() -> Self {
35        Self {
36            base: BaseInterface {
37                iface_type: InterfaceType::Vxlan,
38                ..Default::default()
39            },
40            vxlan: None,
41        }
42    }
43}
44
45impl VxlanInterface {
46    pub fn new() -> Self {
47        Self::default()
48    }
49
50    pub(crate) fn parent(&self) -> Option<&str> {
51        self.vxlan.as_ref().and_then(|cfg| {
52            if cfg.base_iface.is_empty() {
53                None
54            } else {
55                Some(cfg.base_iface.as_str())
56            }
57        })
58    }
59
60    pub(crate) fn change_parent_name(&mut self, name: &str) {
61        if let Some(vxlan_conf) = self.vxlan.as_mut() {
62            vxlan_conf.base_iface = name.to_string();
63        }
64    }
65}
66
67#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
68#[serde(rename_all = "kebab-case", deny_unknown_fields)]
69#[non_exhaustive]
70pub struct VxlanConfig {
71    #[serde(default, skip_serializing_if = "String::is_empty")]
72    pub base_iface: String,
73    #[serde(deserialize_with = "crate::deserializer::u32_or_string")]
74    pub id: u32,
75    #[serde(skip_serializing_if = "Option::is_none")]
76    pub learning: Option<bool>,
77    #[serde(skip_serializing_if = "Option::is_none")]
78    pub local: Option<std::net::IpAddr>,
79    #[serde(skip_serializing_if = "Option::is_none")]
80    pub remote: Option<std::net::IpAddr>,
81    #[serde(
82        rename = "destination-port",
83        default,
84        deserialize_with = "crate::deserializer::option_u16_or_string",
85        skip_serializing_if = "Option::is_none"
86    )]
87    /// Deserialize and serialize from/to `destination-port`.
88    pub dst_port: Option<u16>,
89}