nmstate/ifaces/
ip_tunnel.rs1use std::net::IpAddr;
4
5use serde::{Deserialize, Serialize};
6
7use crate::{BaseInterface, ErrorKind, InterfaceType, NmstateError};
8
9#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
10#[serde(rename_all = "kebab-case")]
11#[non_exhaustive]
12pub struct IpTunnelInterface {
27 #[serde(flatten)]
28 pub base: BaseInterface,
29 #[serde(skip_serializing_if = "Option::is_none")]
30 pub ip_tunnel: Option<IpTunnelConfig>,
32}
33
34impl Default for IpTunnelInterface {
35 fn default() -> Self {
36 Self {
37 base: BaseInterface {
38 iface_type: InterfaceType::IpTunnel,
39 ..Default::default()
40 },
41 ip_tunnel: None,
42 }
43 }
44}
45
46impl IpTunnelInterface {
47 pub fn new() -> Self {
48 Self::default()
49 }
50
51 pub(crate) fn sanitize(
52 &mut self,
53 is_desired: bool,
54 ) -> Result<(), NmstateError> {
55 if is_desired
56 && let Some(conf) = &mut self.ip_tunnel
57 && let Some(flow_label) = conf.flow_label
58 && flow_label > 0xFFFFF
59 {
60 return Err(NmstateError::new(
61 ErrorKind::InvalidArgument,
62 "Flow label must be less than 0xFFFFF".to_string(),
63 ));
64 }
65
66 Ok(())
67 }
68}
69
70#[derive(
71 Serialize, Deserialize, Debug, Default, PartialEq, Eq, Clone, Copy,
72)]
73#[serde(rename_all = "kebab-case")]
74#[non_exhaustive]
75pub enum IpTunnelMode {
76 #[default]
77 Unknown,
78 Ipip,
79 Sit,
80 Ip6ip6,
81 Ipip6,
82}
83
84#[derive(
85 Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy,
86)]
87#[serde(rename_all = "kebab-case")]
88#[non_exhaustive]
89pub enum Ip6TunnelFlag {
90 IgnEncapLimit,
91 UseOrigTclass,
92 UseOrigFlowlabel,
93 Mip6Dev,
94 RcvDscpCopy,
95 UseOrigFwMark,
96 AllowLocalRemote,
97 CapXmit,
98 CapRcv,
99 CapPerPacket,
100}
101
102#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
103#[serde(rename_all = "kebab-case")]
104#[non_exhaustive]
105#[derive(Default)]
106pub struct IpTunnelConfig {
107 pub mode: Option<IpTunnelMode>,
109
110 #[serde(skip_serializing_if = "Option::is_none")]
112 pub base_iface: Option<String>,
113
114 #[serde(skip_serializing_if = "Option::is_none")]
115 pub local: Option<IpAddr>,
116
117 #[serde(skip_serializing_if = "Option::is_none")]
118 pub remote: Option<IpAddr>,
119
120 #[serde(skip_serializing_if = "Option::is_none")]
121 pub ttl: Option<u8>,
122
123 #[serde(skip_serializing_if = "Option::is_none")]
124 pub tos: Option<u8>,
125
126 #[serde(skip_serializing_if = "Option::is_none")]
127 pub flow_label: Option<u32>,
128
129 #[serde(skip_serializing_if = "Option::is_none")]
131 pub ip6tun_flags: Option<Vec<Ip6TunnelFlag>>,
132
133 #[serde(skip_serializing_if = "Option::is_none")]
135 pub pmtu_disc: Option<bool>,
136
137 #[serde(skip_serializing_if = "Option::is_none")]
138 pub encap_limit: Option<u8>,
139
140 #[serde(skip_serializing_if = "Option::is_none")]
141 pub fwmark: Option<u32>,
142}