src/config/network/parser.rs: parse MTU settings

This commit is contained in:
Dietmar Maurer 2020-04-22 13:28:26 +02:00
parent f8e7ac686a
commit 3fce3bc36e
5 changed files with 70 additions and 4 deletions

View File

@ -91,6 +91,10 @@ pub enum DeletableProperty {
method_v4, method_v4,
/// Delete the whole IPv6 configuration entry. /// Delete the whole IPv6 configuration entry.
method_v6, method_v6,
/// Delete mtu for IPv4.
mtu_v4,
/// Delete mtu IPv6.
mtu_v6,
} }
#[api( #[api(
@ -116,6 +120,18 @@ pub enum DeletableProperty {
schema: IP_SCHEMA, schema: IP_SCHEMA,
optional: true, 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: { delete: {
description: "List of properties to delete.", description: "List of properties to delete.",
type: Array, type: Array,
@ -141,6 +157,8 @@ pub fn update_interface(
method_v6: Option<NetworkConfigMethod>, method_v6: Option<NetworkConfigMethod>,
address: Option<String>, address: Option<String>,
gateway: Option<String>, gateway: Option<String>,
mtu_v4: Option<u64>,
mtu_v6: Option<u64>,
delete: Option<Vec<DeletableProperty>>, delete: Option<Vec<DeletableProperty>>,
digest: Option<String>, digest: Option<String>,
) -> Result<(), Error> { ) -> Result<(), Error> {
@ -165,12 +183,16 @@ pub fn update_interface(
DeletableProperty::gateway_v6 => { interface.gateway_v6 = None; }, DeletableProperty::gateway_v6 => { interface.gateway_v6 = None; },
DeletableProperty::method_v4 => { interface.method_v4 = None; }, DeletableProperty::method_v4 => { interface.method_v4 = None; },
DeletableProperty::method_v6 => { interface.method_v6 = 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_v4.is_some() { interface.method_v4 = method_v4; }
if method_v6.is_some() { interface.method_v6 = method_v6; } 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 { if let Some(address) = address {
let (_, _, is_v6) = network::parse_cidr(&address)?; let (_, _, is_v6) = network::parse_cidr(&address)?;

View File

@ -585,6 +585,14 @@ pub struct Interface {
#[serde(skip_serializing_if="Option::is_none")] #[serde(skip_serializing_if="Option::is_none")]
/// IPv6 gateway /// IPv6 gateway
pub gateway_v6: Option<String>, 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")] #[serde(skip_serializing_if="Vec::is_empty")]
pub options_v4: Vec<String>, pub options_v4: Vec<String>,
#[serde(skip_serializing_if="Vec::is_empty")] #[serde(skip_serializing_if="Vec::is_empty")]

View File

@ -30,6 +30,8 @@ impl Interface {
gateway_v4: None, gateway_v4: None,
cidr_v6: None, cidr_v6: None,
gateway_v6: None, gateway_v6: None,
mtu_v4: None,
mtu_v6: None,
options_v4: Vec::new(), options_v4: Vec::new(),
options_v6: 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 { for option in &self.options_v4 {
writeln!(w, " {}", option)?; 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 { for option in &self.options_v6 {
writeln!(w, " {}", option)?; writeln!(w, " {}", option)?;
} }
@ -148,7 +158,10 @@ impl Interface {
writeln!(w, "auto {}", self.name)?; 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 { if let Some(method) = self.method_v4 {
writeln!(w, "iface {} {}", self.name, method_to_str(method))?; writeln!(w, "iface {} {}", self.name, method_to_str(method))?;
self.write_iface_attributes_v4(w, method)?; self.write_iface_attributes_v4(w, method)?;

View File

@ -21,6 +21,7 @@ pub enum Token {
Netmask, Netmask,
Static, Static,
Attribute, Attribute,
MTU,
EOF, EOF,
} }
@ -38,6 +39,7 @@ lazy_static! {
map.insert("manual", Token::Manual); map.insert("manual", Token::Manual);
map.insert("netmask", Token::Netmask); map.insert("netmask", Token::Netmask);
map.insert("static", Token::Static); map.insert("static", Token::Static);
map.insert("mtu", Token::MTU);
map map
}; };
} }

View File

@ -121,6 +121,22 @@ impl <R: BufRead> NetworkParser<R> {
Ok(()) 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> { fn parse_to_eol(&mut self) -> Result<String, Error> {
let mut line = String::new(); let mut line = String::new();
loop { loop {
@ -140,7 +156,7 @@ impl <R: BufRead> NetworkParser<R> {
Ok(()) 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 { loop {
match self.peek()? { match self.peek()? {
@ -152,6 +168,11 @@ impl <R: BufRead> NetworkParser<R> {
match self.peek()? { match self.peek()? {
Token::Address => self.parse_iface_address(interface)?, Token::Address => self.parse_iface_address(interface)?,
Token::Gateway => self.parse_iface_gateway(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"), Token::Netmask => bail!("netmask is deprecated and no longer supported"),
_ => { _ => {
self.parse_iface_addon_attribute(interface)?; self.parse_iface_addon_attribute(interface)?;
@ -200,7 +221,7 @@ impl <R: BufRead> NetworkParser<R> {
interface.set_method_v6(config_method)?; 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 { } else {
let mut interface = Interface::new(iface.clone()); let mut interface = Interface::new(iface.clone());
if address_family_v4 { if address_family_v4 {
@ -210,7 +231,7 @@ impl <R: BufRead> NetworkParser<R> {
interface.set_method_v6(config_method)?; 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); config.interfaces.insert(interface.name.clone(), interface);