* [PATCH proxmox 1/2] fix #8227: network api: support encapsulated bond hash policies
2026-10-25 19:57 [PATCH proxmox,widget-toolkit 0/2] fix #8227: support encapsulated bond hash policies i
@ 2026-10-25 19:58 ` i
2026-10-25 19:58 ` [PATCH widget-toolkit 2/2] fix #8227: ui: offer encapsulated bond transmit " i
1 sibling, 0 replies; 3+ messages in thread
From: i @ 2026-10-25 19:58 UTC (permalink / raw)
To: pbs-devel
From: Leask Wong <i@leaskh.com>
Linux and ifupdown2 accept encap2+3 and encap3+4, but the shared
network API rejects both while reading interfaces configuration. This
prevents PBS from loading its complete network configuration page.
Extend the enum, generated schema and Display implementation without
changing existing serialized values. Add serde/schema validation and
configuration round-trip coverage for both bond modes and spellings.
The regression tests fail against the previous enum. With the fix,
all 30 network API library tests pass on Linux with the impl feature.
Signed-off-by: Leask Wong <i@leaskh.com>
---
proxmox-network-api/src/api_types.rs | 48 ++++++++++++++++++++
proxmox-network-api/src/config/parser.rs | 58 ++++++++++++++++++++++++
2 files changed, 106 insertions(+)
diff --git a/proxmox-network-api/src/api_types.rs
b/proxmox-network-api/src/api_types.rs
index f2467f1..9e392bc 100644
--- a/proxmox-network-api/src/api_types.rs
+++ b/proxmox-network-api/src/api_types.rs
@@ -92,6 +92,12 @@ pub enum BondXmitHashPolicy {
/// Layer 3+4
#[serde(rename = "layer3+4")]
Layer3_4 = 2,
+ /// Encapsulated Layer 2+3
+ #[serde(rename = "encap2+3")]
+ Encap2_3 = 3,
+ /// Encapsulated Layer 3+4
+ #[serde(rename = "encap3+4")]
+ Encap3_4 = 4,
}
impl fmt::Display for BondXmitHashPolicy {
@@ -100,10 +106,52 @@ impl fmt::Display for BondXmitHashPolicy {
BondXmitHashPolicy::Layer2 => "layer2",
BondXmitHashPolicy::Layer2_3 => "layer2+3",
BondXmitHashPolicy::Layer3_4 => "layer3+4",
+ BondXmitHashPolicy::Encap2_3 => "encap2+3",
+ BondXmitHashPolicy::Encap3_4 => "encap3+4",
})
}
}
+#[cfg(test)]
+mod bond_hash_policy_tests {
+ use super::*;
+ use proxmox_schema::ApiType;
+
+ #[test]
+ fn bond_hash_policy_schema_and_serde_round_trip() -> Result<(), Error> {
+ for name in ["layer2", "layer2+3", "layer3+4", "encap2+3",
"encap3+4"] {
+ let value = serde_json::Value::String(name.to_string());
+ let policy: BondXmitHashPolicy =
serde_json::from_value(value.clone())?;
+
+ assert_eq!(policy.to_string(), name);
+ assert_eq!(serde_json::to_value(policy)?, value);
+ assert_eq!(
+ BondXmitHashPolicy::API_SCHEMA.parse_simple_value(name)?,
+ value
+ );
+ }
+
+ Ok(())
+ }
+
+ #[test]
+ fn bond_hash_policy_rejects_invalid_values() {
+ for name in ["encap3-4", "encap5+6", "", "4"] {
+ assert!(
+
serde_json::from_value::<BondXmitHashPolicy>(serde_json::Value::String(
+ name.to_string()
+ ))
+ .is_err()
+ );
+ assert!(
+ BondXmitHashPolicy::API_SCHEMA
+ .parse_simple_value(name)
+ .is_err()
+ );
+ }
+ }
+}
+
#[api()]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
diff --git a/proxmox-network-api/src/config/parser.rs
b/proxmox-network-api/src/config/parser.rs
index 71c9ec0..2851b8c 100644
--- a/proxmox-network-api/src/config/parser.rs
+++ b/proxmox-network-api/src/config/parser.rs
@@ -657,6 +657,64 @@ mod test {
use super::*;
+ #[test]
+ fn test_bond_hash_policy_config_round_trip() -> Result<(), Error> {
+ for mode in ["802.3ad", "balance-xor"] {
+ for keyword in ["bond-xmit-hash-policy", "bond_xmit_hash_policy"] {
+ for policy in ["layer2", "layer2+3", "layer3+4",
"encap2+3", "encap3+4"] {
+ let input = format!(
+ "iface enp1s0 inet manual\n\n\
+ iface enp2s0 inet manual\n\n\
+ iface bond0 inet manual\n\
+ \tbond-mode {mode}\n\
+ \tbond-slaves enp1s0 enp2s0\n\
+ \t{keyword} {policy}\n\n\
+ iface vmbr0 inet manual\n\
+ \tbridge-ports bond0\n"
+ );
+ let mut parser = NetworkParser::new(input.as_bytes());
+ let config = parser.parse_interfaces(None)?;
+ let bond = config.lookup("bond0")?;
+ let expected = bond.bond_xmit_hash_policy;
+
+ assert_eq!(expected.unwrap().to_string(), policy);
+ assert_eq!(
+ config.lookup("vmbr0")?.interface_type,
+ NetworkInterfaceType::Bridge
+ );
+
+ let output = String::try_from(config)?;
+ let mut parser = NetworkParser::new(output.as_bytes());
+ let restored = parser.parse_interfaces(None)?;
+
+
assert_eq!(restored.lookup("bond0")?.bond_xmit_hash_policy, expected);
+ assert_eq!(
+ restored.lookup("vmbr0")?.bridge_ports,
+ Some(vec!["bond0".into()])
+ );
+ assert_eq!(String::try_from(restored)?, output);
+ }
+ }
+ }
+
+ Ok(())
+ }
+
+ #[test]
+ fn test_invalid_bond_hash_policy_reports_line() {
+ let input = "iface bond0 inet manual\n\
+ \tbond-mode 802.3ad\n\
+ \tbond-xmit-hash-policy encap5+6\n";
+ let mut parser = NetworkParser::new(input.as_bytes());
+ let error = parser.parse_interfaces(None).unwrap_err().to_string();
+
+ assert!(error.contains("line 3:"), "{error}");
+ assert!(
+ error.contains("invalid bond_xmit_hash_policy 'encap5+6'"),
+ "{error}"
+ );
+ }
+
#[test]
fn test_network_config_create_lo_1() -> Result<(), Error> {
let input = "";
--
2.56.0
On Sun, 25 Oct 2026 14:57:50 -0500, i@leaskh.com wrote:
> Hi,
>
> This series fixes PBS bug #8227:
> https://bugzilla.proxmox.com/show_bug.cgi?id=8227
>
> An operational Linux 802.3ad bond using encap3+4 makes PBS reject
> /etc/network/interfaces and prevents the Network Interfaces list from
> loading. Linux and ifupdown2 support the policy; the shared Rust API's
> enum and the shared UI selector currently list only the three layer*
> policies.
>
> Patch 1/2 targets proxmox.git and adds encap2+3 and encap3+4 to the enum,
> generated schema and Display implementation. It includes validation and
> configuration round-trip regression tests. Existing values and invalid
> name validation are preserved.
>
> Patch 2/2 targets proxmox-widget-toolkit.git and exposes the two policies
> in the shared selector. It is the companion UI change to patch 1/2.
>
> Validation:
> - Native Linux x86_64: all 30 network API library tests pass with the
> impl feature. Against the old enum, the two new acceptance/round-trip
> tests fail with the expected policy rejection.
> - Round trips cover five policies, both 802.3ad/balance-xor modes and
> both keyword spellings, including an unrelated following bridge.
> - JavaScript syntax and selector-definition runtime checks pass.
> - Rust formatting, whitespace and patch application checks pass.
>
> The Linux build used a disposable workspace restricted to ten local
> crates, including the network API, omitting non-target dev resolution.
> The build setup did not alter library sources. Dependencies came from
> crates.io and OpenSSL headers were unpacked privately. This is not a
> full Debian package build or an end-to-end GUI test, and no running
> host's network configuration was changed.
>
> I emailed my Individual CLA privately to office@proxmox.com today,
> identifying Leask Wong <i@leaskh.com> as my Git author identity.
> CLA registration has not yet been verified.
>
> The existing Bugzilla attachments contain the same code changes:
> https://bugzilla.proxmox.com/attachment.cgi?id=2193
> https://bugzilla.proxmox.com/attachment.cgi?id=2194
> These mail patches additionally include the requested sign-off trailer.
>
> Please review, and let me know if any changes are needed.
>
> Thanks,
> Leask
^ permalink raw reply related [flat|nested] 3+ messages in thread* [PATCH widget-toolkit 2/2] fix #8227: ui: offer encapsulated bond transmit hash policies
2026-10-25 19:57 [PATCH proxmox,widget-toolkit 0/2] fix #8227: support encapsulated bond hash policies i
2026-10-25 19:58 ` [PATCH proxmox 1/2] fix #8227: network api: " i
@ 2026-10-25 19:58 ` i
1 sibling, 0 replies; 3+ messages in thread
From: i @ 2026-10-25 19:58 UTC (permalink / raw)
To: pbs-devel
From: Leask Wong <i@leaskh.com>
Add encap2+3 and encap3+4 to the shared policy selector, matching
the accompanying proxmox-network-api extension. Keep the existing
policy values, labels and default ordering.
JavaScript syntax and a runtime selector-definition check pass.
Signed-off-by: Leask Wong <i@leaskh.com>
---
src/form/BondModeSelector.js | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/form/BondModeSelector.js b/src/form/BondModeSelector.js
index cb87f81..2c24bbd 100644
--- a/src/form/BondModeSelector.js
+++ b/src/form/BondModeSelector.js
@@ -37,5 +37,7 @@ Ext.define('Proxmox.form.BondPolicySelector', {
['layer2', 'layer2'],
['layer2+3', 'layer2+3'],
['layer3+4', 'layer3+4'],
+ ['encap2+3', 'encap2+3'],
+ ['encap3+4', 'encap3+4'],
],
});
--
2.56.0
On Sun, 25 Oct 2026 14:57:50 -0500, i@leaskh.com wrote:
> Hi,
>
> This series fixes PBS bug #8227:
> https://bugzilla.proxmox.com/show_bug.cgi?id=8227
>
> An operational Linux 802.3ad bond using encap3+4 makes PBS reject
> /etc/network/interfaces and prevents the Network Interfaces list from
> loading. Linux and ifupdown2 support the policy; the shared Rust API's
> enum and the shared UI selector currently list only the three layer*
> policies.
>
> Patch 1/2 targets proxmox.git and adds encap2+3 and encap3+4 to the enum,
> generated schema and Display implementation. It includes validation and
> configuration round-trip regression tests. Existing values and invalid
> name validation are preserved.
>
> Patch 2/2 targets proxmox-widget-toolkit.git and exposes the two policies
> in the shared selector. It is the companion UI change to patch 1/2.
>
> Validation:
> - Native Linux x86_64: all 30 network API library tests pass with the
> impl feature. Against the old enum, the two new acceptance/round-trip
> tests fail with the expected policy rejection.
> - Round trips cover five policies, both 802.3ad/balance-xor modes and
> both keyword spellings, including an unrelated following bridge.
> - JavaScript syntax and selector-definition runtime checks pass.
> - Rust formatting, whitespace and patch application checks pass.
>
> The Linux build used a disposable workspace restricted to ten local
> crates, including the network API, omitting non-target dev resolution.
> The build setup did not alter library sources. Dependencies came from
> crates.io and OpenSSL headers were unpacked privately. This is not a
> full Debian package build or an end-to-end GUI test, and no running
> host's network configuration was changed.
>
> I emailed my Individual CLA privately to office@proxmox.com today,
> identifying Leask Wong <i@leaskh.com> as my Git author identity.
> CLA registration has not yet been verified.
>
> The existing Bugzilla attachments contain the same code changes:
> https://bugzilla.proxmox.com/attachment.cgi?id=2193
> https://bugzilla.proxmox.com/attachment.cgi?id=2194
> These mail patches additionally include the requested sign-off trailer.
>
> Please review, and let me know if any changes are needed.
>
> Thanks,
> Leask
^ permalink raw reply related [flat|nested] 3+ messages in thread