all lists on lists.proxmox.com
 help / color / mirror / Atom feed
From: Dominik Csapak <d.csapak@proxmox.com>
To: pbs-devel@lists.proxmox.com
Subject: [pbs-devel] [PATCH proxmox-backup 2/2] fix #2942: implement lacp bond mode and bond_xmit_hash_policy
Date: Wed, 16 Sep 2020 14:12:30 +0200	[thread overview]
Message-ID: <20200916121230.12906-2-d.csapak@proxmox.com> (raw)
In-Reply-To: <20200916121230.12906-1-d.csapak@proxmox.com>

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





  reply	other threads:[~2020-09-16 12:12 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
2020-09-17  6:37 ` [pbs-devel] applied: " Dietmar Maurer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200916121230.12906-2-d.csapak@proxmox.com \
    --to=d.csapak@proxmox.com \
    --cc=pbs-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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