]> git.proxmox.com Git - proxmox-backup.git/commitdiff
src/config/network/parser.rs: parse MTU settings
authorDietmar Maurer <dietmar@proxmox.com>
Wed, 22 Apr 2020 11:28:26 +0000 (13:28 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Wed, 22 Apr 2020 11:44:51 +0000 (13:44 +0200)
src/api2/config/network.rs
src/api2/types.rs
src/config/network.rs
src/config/network/lexer.rs
src/config/network/parser.rs

index 26a660382be6954c477577e2caa85d156b0a4016..cfb82980bea5db561ae5e1c5478454eccfac2984 100644 (file)
@@ -91,6 +91,10 @@ pub enum DeletableProperty {
     method_v4,
     /// Delete the whole IPv6 configuration entry.
     method_v6,
+    /// Delete mtu for IPv4.
+    mtu_v4,
+    /// Delete mtu IPv6.
+    mtu_v6,
 }
 
 #[api(
@@ -116,6 +120,18 @@ pub enum DeletableProperty {
                 schema: IP_SCHEMA,
                 optional: true,
             },
+            mtu_v4: {
+                description: "Maximum Transmission Unit for IPv4.",
+                optional: true,
+                minimum: 46,
+                maximum: 65535,
+            },
+            mtu_v6: {
+                description: "Maximum Transmission Unit for IPv6.",
+                optional: true,
+                minimum: 46,
+                maximum: 65535,
+            },
             delete: {
                 description: "List of properties to delete.",
                 type: Array,
@@ -141,6 +157,8 @@ pub fn update_interface(
     method_v6: Option<NetworkConfigMethod>,
     address: Option<String>,
     gateway: Option<String>,
+    mtu_v4: Option<u64>,
+    mtu_v6: Option<u64>,
     delete: Option<Vec<DeletableProperty>>,
     digest: Option<String>,
 ) -> Result<(), Error> {
@@ -165,12 +183,16 @@ pub fn update_interface(
                 DeletableProperty::gateway_v6 => { interface.gateway_v6 = None; },
                 DeletableProperty::method_v4 => { interface.method_v4 = None; },
                 DeletableProperty::method_v6 => { interface.method_v6 = None; },
+                DeletableProperty::mtu_v4 => { interface.mtu_v4 = None; },
+                DeletableProperty::mtu_v6 => { interface.mtu_v6 = None; },
             }
         }
     }
 
     if method_v4.is_some() { interface.method_v4 = method_v4; }
     if method_v6.is_some() { interface.method_v6 = method_v6; }
+    if mtu_v4.is_some() { interface.mtu_v4 = mtu_v4; }
+    if mtu_v6.is_some() { interface.mtu_v6 = mtu_v6; }
 
     if let Some(address) = address {
         let (_, _, is_v6) = network::parse_cidr(&address)?;
index 580ed911280cc17e060df6899e8b789a85e7731b..9385008daf07ad4ba68a3389d9dab3beaba4dddf 100644 (file)
@@ -585,6 +585,14 @@ pub struct Interface {
     #[serde(skip_serializing_if="Option::is_none")]
     /// IPv6 gateway
     pub gateway_v6: Option<String>,
+
+    #[serde(skip_serializing_if="Option::is_none")]
+    /// Maximum Transmission Unit for IPv4
+    pub mtu_v4: Option<u64>,
+    #[serde(skip_serializing_if="Option::is_none")]
+    /// Maximum Transmission Unit for IPv6
+    pub mtu_v6: Option<u64>,
+
     #[serde(skip_serializing_if="Vec::is_empty")]
     pub options_v4: Vec<String>,
     #[serde(skip_serializing_if="Vec::is_empty")]
index 82be5de2741fe36f8094d0f59c485221afead287..fb0c6d836aa112015e635f149f6d3daebf0f44ca 100644 (file)
@@ -30,6 +30,8 @@ impl Interface {
             gateway_v4: None,
             cidr_v6: None,
             gateway_v6: None,
+            mtu_v4: None,
+            mtu_v6: None,
             options_v4: Vec::new(),
             options_v6: Vec::new(),
         }
@@ -107,6 +109,10 @@ impl Interface {
             }
         }
 
+        if let Some(mtu) = &self.mtu_v4 {
+            writeln!(w, "    mtu {}", mtu)?;
+        }
+
         for option in &self.options_v4 {
             writeln!(w, "    {}", option)?;
         }
@@ -124,6 +130,10 @@ impl Interface {
             }
         }
 
+        if let Some(mtu) = &self.mtu_v6 {
+            writeln!(w, "    mtu {}", mtu)?;
+        }
+
         for option in &self.options_v6 {
             writeln!(w, "    {}", option)?;
         }
@@ -148,7 +158,10 @@ impl Interface {
             writeln!(w, "auto {}", self.name)?;
         }
 
-        if self.method_v4 == self.method_v6 {
+        if self.method_v4 == self.method_v6
+            && self.mtu_v4 == self.mtu_v6
+            && self.options_v4.is_empty() == self.options_v6.is_empty()
+        {
             if let Some(method) = self.method_v4 {
                 writeln!(w, "iface {} {}", self.name, method_to_str(method))?;
                 self.write_iface_attributes_v4(w, method)?;
index c897d464ce585042e3e7b7f3433902ed268e047d..93d3b36f4ec7c41dd879b36c76ab59c4974aa111 100644 (file)
@@ -21,6 +21,7 @@ pub enum Token {
     Netmask,
     Static,
     Attribute,
+    MTU,
     EOF,
 }
 
@@ -38,6 +39,7 @@ lazy_static! {
         map.insert("manual", Token::Manual);
         map.insert("netmask", Token::Netmask);
         map.insert("static", Token::Static);
+        map.insert("mtu", Token::MTU);
         map
     };
 }
index 4f24ed2a70956068245067d96e9f96cd621808b8..3ecae114492cb4fe425f316652869f9cf3632f59 100644 (file)
@@ -121,6 +121,22 @@ impl <R: BufRead> NetworkParser<R> {
         Ok(())
     }
 
+    fn parse_iface_mtu(&mut self) -> Result<u64, Error> {
+        self.eat(Token::MTU)?;
+
+        let mtu = self.next_text()?;
+        let mtu = match u64::from_str_radix(&mtu, 10) {
+            Ok(mtu) => mtu,
+            Err(err) => {
+                bail!("unable to parse mtu value '{}' - {}", mtu, err);
+            }
+        };
+
+        self.eat(Token::Newline)?;
+
+        Ok(mtu)
+    }
+
     fn parse_to_eol(&mut self) -> Result<String, Error> {
         let mut line = String::new();
         loop {
@@ -140,7 +156,7 @@ impl <R: BufRead> NetworkParser<R> {
         Ok(())
     }
 
-    fn parse_iface_attributes(&mut self, interface: &mut Interface) -> Result<(), Error> {
+    fn parse_iface_attributes(&mut self, interface: &mut Interface, family_v4: bool, family_v6: bool) -> Result<(), Error> {
 
         loop {
             match self.peek()? {
@@ -152,6 +168,11 @@ impl <R: BufRead> NetworkParser<R> {
             match self.peek()? {
                 Token::Address => self.parse_iface_address(interface)?,
                 Token::Gateway => self.parse_iface_gateway(interface)?,
+                Token::MTU => {
+                    let mtu = self.parse_iface_mtu()?;
+                    if family_v4 { interface.mtu_v4 = Some(mtu); }
+                    if family_v6 { interface.mtu_v6 = Some(mtu); }
+                }
                 Token::Netmask => bail!("netmask is deprecated and no longer supported"),
                 _ => {
                     self.parse_iface_addon_attribute(interface)?;
@@ -200,7 +221,7 @@ impl <R: BufRead> NetworkParser<R> {
                 interface.set_method_v6(config_method)?;
             }
 
-            if has_attributes { self.parse_iface_attributes(&mut interface)?; }
+            if has_attributes { self.parse_iface_attributes(&mut interface, address_family_v4, address_family_v6)?; }
         } else {
             let mut interface = Interface::new(iface.clone());
             if address_family_v4 {
@@ -210,7 +231,7 @@ impl <R: BufRead> NetworkParser<R> {
                 interface.set_method_v6(config_method)?;
             }
 
-            if has_attributes { self.parse_iface_attributes(&mut interface)?; }
+            if has_attributes { self.parse_iface_attributes(&mut interface, address_family_v4, address_family_v6)?; }
 
             config.interfaces.insert(interface.name.clone(), interface);