* [pbs-devel] [PATCH proxmox-backup 1/2] api2/network: add bond-primary parameter
@ 2020-09-16 12:12 Dominik Csapak
2020-09-16 12:12 ` [pbs-devel] [PATCH proxmox-backup 2/2] fix #2942: implement lacp bond mode and bond_xmit_hash_policy Dominik Csapak
2020-09-17 6:37 ` [pbs-devel] applied: [PATCH proxmox-backup 1/2] api2/network: add bond-primary parameter Dietmar Maurer
0 siblings, 2 replies; 3+ messages in thread
From: Dominik Csapak @ 2020-09-16 12:12 UTC (permalink / raw)
To: pbs-devel
needed for 'active-backup' bond mode
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
this needs my previous patches for the api-macro (and a bump)
src/api2/node/network.rs | 34 ++++++++++++++++++++++++++++++++--
src/api2/types/mod.rs | 9 ++++++++-
src/config/network.rs | 6 ++++++
src/config/network/lexer.rs | 4 +++-
src/config/network/parser.rs | 6 ++++++
5 files changed, 55 insertions(+), 4 deletions(-)
diff --git a/src/api2/node/network.rs b/src/api2/node/network.rs
index 7266da05..4de12ef2 100644
--- a/src/api2/node/network.rs
+++ b/src/api2/node/network.rs
@@ -198,6 +198,10 @@ pub fn read_interface(iface: String) -> Result<Value, Error> {
type: LinuxBondMode,
optional: true,
},
+ "bond-primary": {
+ schema: NETWORK_INTERFACE_NAME_SCHEMA,
+ optional: true,
+ },
slaves: {
schema: NETWORK_INTERFACE_LIST_SCHEMA,
optional: true,
@@ -224,6 +228,7 @@ pub fn create_interface(
bridge_ports: Option<String>,
bridge_vlan_aware: Option<bool>,
bond_mode: Option<LinuxBondMode>,
+ bond_primary: Option<String>,
slaves: Option<String>,
param: Value,
) -> Result<(), Error> {
@@ -284,7 +289,15 @@ pub fn create_interface(
if bridge_vlan_aware.is_some() { interface.bridge_vlan_aware = bridge_vlan_aware; }
}
NetworkInterfaceType::Bond => {
- if bond_mode.is_some() { interface.bond_mode = bond_mode; }
+ if let Some(mode) = bond_mode {
+ interface.bond_mode = bond_mode;
+ if bond_primary.is_some() {
+ if mode != LinuxBondMode::active_backup {
+ bail!("bond-primary is only valid with Active/Backup mode");
+ }
+ interface.bond_primary = bond_primary;
+ }
+ }
if let Some(slaves) = slaves {
let slaves = split_interface_list(&slaves)?;
interface.set_bond_slaves(slaves)?;
@@ -343,6 +356,9 @@ pub enum DeletableProperty {
bridge_vlan_aware,
/// Delete bond-slaves (set to 'none')
slaves,
+ /// Delete bond-primary
+ #[serde(rename = "bond-primary")]
+ bond_primary,
}
@@ -420,6 +436,10 @@ pub enum DeletableProperty {
type: LinuxBondMode,
optional: true,
},
+ "bond-primary": {
+ schema: NETWORK_INTERFACE_NAME_SCHEMA,
+ optional: true,
+ },
slaves: {
schema: NETWORK_INTERFACE_LIST_SCHEMA,
optional: true,
@@ -458,6 +478,7 @@ pub fn update_interface(
bridge_ports: Option<String>,
bridge_vlan_aware: Option<bool>,
bond_mode: Option<LinuxBondMode>,
+ bond_primary: Option<String>,
slaves: Option<String>,
delete: Option<Vec<DeletableProperty>>,
digest: Option<String>,
@@ -501,6 +522,7 @@ pub fn update_interface(
DeletableProperty::bridge_ports => { interface.set_bridge_ports(Vec::new())?; }
DeletableProperty::bridge_vlan_aware => { interface.bridge_vlan_aware = None; }
DeletableProperty::slaves => { interface.set_bond_slaves(Vec::new())?; }
+ DeletableProperty::bond_primary => { interface.bond_primary = None; }
}
}
}
@@ -518,7 +540,15 @@ pub fn update_interface(
let slaves = split_interface_list(&slaves)?;
interface.set_bond_slaves(slaves)?;
}
- if bond_mode.is_some() { interface.bond_mode = bond_mode; }
+ if let Some(mode) = bond_mode {
+ interface.bond_mode = bond_mode;
+ if bond_primary.is_some() {
+ if mode != LinuxBondMode::active_backup {
+ bail!("bond-primary is only valid with Active/Backup mode");
+ }
+ interface.bond_primary = bond_primary;
+ }
+ }
if let Some(cidr) = cidr {
let (_, _, is_v6) = network::parse_cidr(&cidr)?;
diff --git a/src/api2/types/mod.rs b/src/api2/types/mod.rs
index 5495d693..e2eb08aa 100644
--- a/src/api2/types/mod.rs
+++ b/src/api2/types/mod.rs
@@ -812,7 +812,11 @@ pub const NETWORK_INTERFACE_LIST_SCHEMA: Schema = StringSchema::new(
bond_mode: {
type: LinuxBondMode,
optional: true,
- }
+ },
+ "bond-primary": {
+ schema: NETWORK_INTERFACE_NAME_SCHEMA,
+ optional: true,
+ },
}
)]
#[derive(Debug, Serialize, Deserialize)]
@@ -869,6 +873,9 @@ pub struct Interface {
pub slaves: Option<Vec<String>>,
#[serde(skip_serializing_if="Option::is_none")]
pub bond_mode: Option<LinuxBondMode>,
+ #[serde(skip_serializing_if="Option::is_none")]
+ #[serde(rename = "bond-primary")]
+ pub bond_primary: Option<String>,
}
// Regression tests
diff --git a/src/config/network.rs b/src/config/network.rs
index 53693283..6e3b9ea1 100644
--- a/src/config/network.rs
+++ b/src/config/network.rs
@@ -67,6 +67,7 @@ impl Interface {
bridge_vlan_aware: None,
slaves: None,
bond_mode: None,
+ bond_primary: None,
}
}
@@ -169,6 +170,11 @@ impl Interface {
NetworkInterfaceType::Bond => {
let mode = self.bond_mode.unwrap_or(LinuxBondMode::balance_rr);
writeln!(w, "\tbond-mode {}", bond_mode_to_str(mode))?;
+ if let Some(primary) = &self.bond_primary {
+ if mode == LinuxBondMode::active_backup {
+ writeln!(w, "\tbond-primary {}", primary)?;
+ }
+ }
let slaves = self.slaves.as_ref().unwrap_or(&EMPTY_LIST);
if slaves.is_empty() {
diff --git a/src/config/network/lexer.rs b/src/config/network/lexer.rs
index c050745f..c29d4f37 100644
--- a/src/config/network/lexer.rs
+++ b/src/config/network/lexer.rs
@@ -26,6 +26,7 @@ pub enum Token {
BridgeVlanAware,
BondSlaves,
BondMode,
+ BondPrimary,
EOF,
}
@@ -51,7 +52,8 @@ lazy_static! {
map.insert("bond-slaves", Token::BondSlaves);
map.insert("bond_slaves", Token::BondSlaves);
map.insert("bond-mode", Token::BondMode);
- map.insert("bond_mode", Token::BondMode);
+ map.insert("bond-primary", Token::BondPrimary);
+ map.insert("bond_primary", Token::BondPrimary);
map
};
}
diff --git a/src/config/network/parser.rs b/src/config/network/parser.rs
index a97d0f79..b9b7ddc3 100644
--- a/src/config/network/parser.rs
+++ b/src/config/network/parser.rs
@@ -243,6 +243,12 @@ impl <R: BufRead> NetworkParser<R> {
interface.bond_mode = Some(bond_mode_from_str(&mode)?);
self.eat(Token::Newline)?;
}
+ Token::BondPrimary => {
+ self.eat(Token::BondPrimary)?;
+ let primary = self.next_text()?;
+ interface.bond_primary = Some(primary);
+ self.eat(Token::Newline)?;
+ }
Token::Netmask => bail!("netmask is deprecated and no longer supported"),
_ => { // parse addon attributes
--
2.20.1
^ permalink raw reply [flat|nested] 3+ messages in thread
* [pbs-devel] [PATCH proxmox-backup 2/2] fix #2942: implement lacp bond mode and bond_xmit_hash_policy
2020-09-16 12:12 [pbs-devel] [PATCH proxmox-backup 1/2] api2/network: add bond-primary parameter Dominik Csapak
@ 2020-09-16 12:12 ` Dominik Csapak
2020-09-17 6:37 ` [pbs-devel] applied: [PATCH proxmox-backup 1/2] api2/network: add bond-primary parameter Dietmar Maurer
1 sibling, 0 replies; 3+ messages in thread
From: Dominik Csapak @ 2020-09-16 12:12 UTC (permalink / raw)
To: pbs-devel
this was not yet implemented, should be compatible with pve and the gui
Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
src/api2/node/network.rs | 29 +++++++++++++++++++++++++++++
src/api2/types/mod.rs | 24 +++++++++++++++++++++++-
src/config/network.rs | 24 +++++++++++++++++++++++-
src/config/network/lexer.rs | 3 +++
src/config/network/parser.rs | 8 +++++++-
5 files changed, 85 insertions(+), 3 deletions(-)
diff --git a/src/api2/node/network.rs b/src/api2/node/network.rs
index 4de12ef2..b125a8af 100644
--- a/src/api2/node/network.rs
+++ b/src/api2/node/network.rs
@@ -202,6 +202,10 @@ pub fn read_interface(iface: String) -> Result<Value, Error> {
schema: NETWORK_INTERFACE_NAME_SCHEMA,
optional: true,
},
+ bond_xmit_hash_policy: {
+ type: BondXmitHashPolicy,
+ optional: true,
+ },
slaves: {
schema: NETWORK_INTERFACE_LIST_SCHEMA,
optional: true,
@@ -229,6 +233,7 @@ pub fn create_interface(
bridge_vlan_aware: Option<bool>,
bond_mode: Option<LinuxBondMode>,
bond_primary: Option<String>,
+ bond_xmit_hash_policy: Option<BondXmitHashPolicy>,
slaves: Option<String>,
param: Value,
) -> Result<(), Error> {
@@ -297,6 +302,14 @@ pub fn create_interface(
}
interface.bond_primary = bond_primary;
}
+ if bond_xmit_hash_policy.is_some() {
+ if mode != LinuxBondMode::ieee802_3ad &&
+ mode != LinuxBondMode::balance_xor
+ {
+ bail!("bond_xmit_hash_policy is only valid with LACP(802.3ad) or balance-xor mode");
+ }
+ interface.bond_xmit_hash_policy = bond_xmit_hash_policy;
+ }
}
if let Some(slaves) = slaves {
let slaves = split_interface_list(&slaves)?;
@@ -359,6 +372,8 @@ pub enum DeletableProperty {
/// Delete bond-primary
#[serde(rename = "bond-primary")]
bond_primary,
+ /// Delete bond transmit hash policy
+ bond_xmit_hash_policy,
}
@@ -440,6 +455,10 @@ pub enum DeletableProperty {
schema: NETWORK_INTERFACE_NAME_SCHEMA,
optional: true,
},
+ bond_xmit_hash_policy: {
+ type: BondXmitHashPolicy,
+ optional: true,
+ },
slaves: {
schema: NETWORK_INTERFACE_LIST_SCHEMA,
optional: true,
@@ -479,6 +498,7 @@ pub fn update_interface(
bridge_vlan_aware: Option<bool>,
bond_mode: Option<LinuxBondMode>,
bond_primary: Option<String>,
+ bond_xmit_hash_policy: Option<BondXmitHashPolicy>,
slaves: Option<String>,
delete: Option<Vec<DeletableProperty>>,
digest: Option<String>,
@@ -523,6 +543,7 @@ pub fn update_interface(
DeletableProperty::bridge_vlan_aware => { interface.bridge_vlan_aware = None; }
DeletableProperty::slaves => { interface.set_bond_slaves(Vec::new())?; }
DeletableProperty::bond_primary => { interface.bond_primary = None; }
+ DeletableProperty::bond_xmit_hash_policy => { interface.bond_xmit_hash_policy = None }
}
}
}
@@ -548,6 +569,14 @@ pub fn update_interface(
}
interface.bond_primary = bond_primary;
}
+ if bond_xmit_hash_policy.is_some() {
+ if mode != LinuxBondMode::ieee802_3ad &&
+ mode != LinuxBondMode::balance_xor
+ {
+ bail!("bond_xmit_hash_policy is only valid with LACP(802.3ad) or balance-xor mode");
+ }
+ interface.bond_xmit_hash_policy = bond_xmit_hash_policy;
+ }
}
if let Some(cidr) = cidr {
diff --git a/src/api2/types/mod.rs b/src/api2/types/mod.rs
index e2eb08aa..a2211adc 100644
--- a/src/api2/types/mod.rs
+++ b/src/api2/types/mod.rs
@@ -699,7 +699,7 @@ pub enum LinuxBondMode {
/// Broadcast policy
broadcast = 3,
/// IEEE 802.3ad Dynamic link aggregation
- //#[serde(rename = "802.3ad")]
+ #[serde(rename = "802.3ad")]
ieee802_3ad = 4,
/// Adaptive transmit load balancing
balance_tlb = 5,
@@ -707,6 +707,23 @@ pub enum LinuxBondMode {
balance_alb = 6,
}
+#[api()]
+#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
+#[serde(rename_all = "kebab-case")]
+#[allow(non_camel_case_types)]
+#[repr(u8)]
+/// Bond Transmit Hash Policy for LACP (802.3ad)
+pub enum BondXmitHashPolicy {
+ /// Layer 2
+ layer2 = 0,
+ /// Layer 2+3
+ #[serde(rename = "layer2+3")]
+ layer2_3 = 1,
+ /// Layer 3+4
+ #[serde(rename = "layer3+4")]
+ layer3_4 = 2,
+}
+
#[api()]
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
@@ -817,6 +834,10 @@ pub const NETWORK_INTERFACE_LIST_SCHEMA: Schema = StringSchema::new(
schema: NETWORK_INTERFACE_NAME_SCHEMA,
optional: true,
},
+ bond_xmit_hash_policy: {
+ type: BondXmitHashPolicy,
+ optional: true,
+ },
}
)]
#[derive(Debug, Serialize, Deserialize)]
@@ -876,6 +897,7 @@ pub struct Interface {
#[serde(skip_serializing_if="Option::is_none")]
#[serde(rename = "bond-primary")]
pub bond_primary: Option<String>,
+ pub bond_xmit_hash_policy: Option<BondXmitHashPolicy>,
}
// Regression tests
diff --git a/src/config/network.rs b/src/config/network.rs
index 6e3b9ea1..98313442 100644
--- a/src/config/network.rs
+++ b/src/config/network.rs
@@ -17,7 +17,7 @@ pub use lexer::*;
mod parser;
pub use parser::*;
-use crate::api2::types::{Interface, NetworkConfigMethod, NetworkInterfaceType, LinuxBondMode};
+use crate::api2::types::{Interface, NetworkConfigMethod, NetworkInterfaceType, LinuxBondMode, BondXmitHashPolicy};
lazy_static!{
static ref PHYSICAL_NIC_REGEX: Regex = Regex::new(r"^(?:eth\d+|en[^:.]+|ib\d+)$").unwrap();
@@ -44,6 +44,19 @@ pub fn bond_mode_to_str(mode: LinuxBondMode) -> &'static str {
}
}
+pub fn bond_xmit_hash_policy_from_str(s: &str) -> Result<BondXmitHashPolicy, Error> {
+ BondXmitHashPolicy::deserialize(s.into_deserializer())
+ .map_err(|_: value::Error| format_err!("invalid bond_xmit_hash_policy '{}'", s))
+}
+
+pub fn bond_xmit_hash_policy_to_str(policy: &BondXmitHashPolicy) -> &'static str {
+ match policy {
+ BondXmitHashPolicy::layer2 => "layer2",
+ BondXmitHashPolicy::layer2_3 => "layer2+3",
+ BondXmitHashPolicy::layer3_4 => "layer3+4",
+ }
+}
+
impl Interface {
pub fn new(name: String) -> Self {
@@ -68,6 +81,7 @@ impl Interface {
slaves: None,
bond_mode: None,
bond_primary: None,
+ bond_xmit_hash_policy: None,
}
}
@@ -176,6 +190,14 @@ impl Interface {
}
}
+ if let Some(xmit_policy) = &self.bond_xmit_hash_policy {
+ if mode == LinuxBondMode::ieee802_3ad ||
+ mode == LinuxBondMode::balance_xor
+ {
+ writeln!(w, "\tbond_xmit_hash_policy {}", bond_xmit_hash_policy_to_str(xmit_policy))?;
+ }
+ }
+
let slaves = self.slaves.as_ref().unwrap_or(&EMPTY_LIST);
if slaves.is_empty() {
writeln!(w, "\tbond-slaves none")?;
diff --git a/src/config/network/lexer.rs b/src/config/network/lexer.rs
index c29d4f37..d63312c5 100644
--- a/src/config/network/lexer.rs
+++ b/src/config/network/lexer.rs
@@ -27,6 +27,7 @@ pub enum Token {
BondSlaves,
BondMode,
BondPrimary,
+ BondXmitHashPolicy,
EOF,
}
@@ -54,6 +55,8 @@ lazy_static! {
map.insert("bond-mode", Token::BondMode);
map.insert("bond-primary", Token::BondPrimary);
map.insert("bond_primary", Token::BondPrimary);
+ map.insert("bond_xmit_hash_policy", Token::BondXmitHashPolicy);
+ map.insert("bond-xmit-hash-policy", Token::BondXmitHashPolicy);
map
};
}
diff --git a/src/config/network/parser.rs b/src/config/network/parser.rs
index b9b7ddc3..7c9c69f1 100644
--- a/src/config/network/parser.rs
+++ b/src/config/network/parser.rs
@@ -9,7 +9,7 @@ use regex::Regex;
use super::helper::*;
use super::lexer::*;
-use super::{NetworkConfig, NetworkOrderEntry, Interface, NetworkConfigMethod, NetworkInterfaceType, bond_mode_from_str};
+use super::{NetworkConfig, NetworkOrderEntry, Interface, NetworkConfigMethod, NetworkInterfaceType, bond_mode_from_str, bond_xmit_hash_policy_from_str};
pub struct NetworkParser<R: BufRead> {
input: Peekable<Lexer<R>>,
@@ -249,6 +249,12 @@ impl <R: BufRead> NetworkParser<R> {
interface.bond_primary = Some(primary);
self.eat(Token::Newline)?;
}
+ Token::BondXmitHashPolicy => {
+ self.eat(Token::BondXmitHashPolicy)?;
+ let policy = bond_xmit_hash_policy_from_str(&self.next_text()?)?;
+ interface.bond_xmit_hash_policy = Some(policy);
+ self.eat(Token::Newline)?;
+ }
Token::Netmask => bail!("netmask is deprecated and no longer supported"),
_ => { // parse addon attributes
--
2.20.1
^ permalink raw reply [flat|nested] 3+ messages in thread
* [pbs-devel] applied: [PATCH proxmox-backup 1/2] api2/network: add bond-primary parameter
2020-09-16 12:12 [pbs-devel] [PATCH proxmox-backup 1/2] api2/network: add bond-primary parameter Dominik Csapak
2020-09-16 12:12 ` [pbs-devel] [PATCH proxmox-backup 2/2] fix #2942: implement lacp bond mode and bond_xmit_hash_policy Dominik Csapak
@ 2020-09-17 6:37 ` Dietmar Maurer
1 sibling, 0 replies; 3+ messages in thread
From: Dietmar Maurer @ 2020-09-17 6:37 UTC (permalink / raw)
To: Proxmox Backup Server development discussion, Dominik Csapak
applied both patches
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2020-09-17 6:38 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-16 12:12 [pbs-devel] [PATCH proxmox-backup 1/2] api2/network: add bond-primary parameter Dominik Csapak
2020-09-16 12:12 ` [pbs-devel] [PATCH proxmox-backup 2/2] fix #2942: implement lacp bond mode and bond_xmit_hash_policy Dominik Csapak
2020-09-17 6:37 ` [pbs-devel] applied: [PATCH proxmox-backup 1/2] api2/network: add bond-primary parameter Dietmar Maurer
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal