From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: <pve-devel-bounces@lists.proxmox.com> Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id 0536D1FF16E for <inbox@lore.proxmox.com>; Mon, 17 Mar 2025 15:18:05 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id DDB135402; Mon, 17 Mar 2025 15:17:31 +0100 (CET) From: Christoph Heiss <c.heiss@proxmox.com> To: pve-devel@lists.proxmox.com Date: Mon, 17 Mar 2025 15:11:39 +0100 Message-ID: <20250317141152.1247324-3-c.heiss@proxmox.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250317141152.1247324-1-c.heiss@proxmox.com> References: <20250317141152.1247324-1-c.heiss@proxmox.com> MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.026 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment RCVD_IN_VALIDITY_CERTIFIED_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_RPBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_SAFE_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [expression.rs, statement.rs, firewall.rs] Subject: [pve-devel] [PATCH proxmox-firewall 02/14] firewall: add connmark rule with VMID to all guest chains X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion <pve-devel.lists.proxmox.com> List-Unsubscribe: <https://lists.proxmox.com/cgi-bin/mailman/options/pve-devel>, <mailto:pve-devel-request@lists.proxmox.com?subject=unsubscribe> List-Archive: <http://lists.proxmox.com/pipermail/pve-devel/> List-Post: <mailto:pve-devel@lists.proxmox.com> List-Help: <mailto:pve-devel-request@lists.proxmox.com?subject=help> List-Subscribe: <https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel>, <mailto:pve-devel-request@lists.proxmox.com?subject=subscribe> Reply-To: Proxmox VE development discussion <pve-devel@lists.proxmox.com> Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pve-devel-bounces@lists.proxmox.com Sender: "pve-devel" <pve-devel-bounces@lists.proxmox.com> Adds a connmark attribute with the VMID inside to anything flowing in/out the guest, which are also carried over to all conntrack entries. This enables differentiating conntrack entries between VMs for live-migration. Signed-off-by: Christoph Heiss <c.heiss@proxmox.com> --- Depends on patch #1 being applied first to proxmox-ve-rs & a appropriate crate bump. proxmox-firewall/src/firewall.rs | 14 ++- .../integration_tests__firewall.snap | 85 ++++++++++++++++++- proxmox-nftables/src/expression.rs | 9 ++ proxmox-nftables/src/statement.rs | 10 ++- 4 files changed, 114 insertions(+), 4 deletions(-) diff --git a/proxmox-firewall/src/firewall.rs b/proxmox-firewall/src/firewall.rs index 88fb460..9f7df56 100644 --- a/proxmox-firewall/src/firewall.rs +++ b/proxmox-firewall/src/firewall.rs @@ -6,7 +6,9 @@ use anyhow::{bail, Error}; use proxmox_nftables::command::{Add, Commands, Delete, Flush}; use proxmox_nftables::expression::{Meta, Payload}; use proxmox_nftables::helper::NfVec; -use proxmox_nftables::statement::{AnonymousLimit, Log, LogLevel, Match, Set, SetOperation}; +use proxmox_nftables::statement::{ + AnonymousLimit, Log, LogLevel, Mangle, Match, Set, SetOperation, +}; use proxmox_nftables::types::{ AddElement, AddRule, ChainPart, MapValue, RateTimescale, SetName, TableFamily, TableName, TablePart, Verdict, @@ -934,7 +936,15 @@ impl Firewall { vmid: Some(vmid), }; - commands.reserve(config.rules().len()); + commands.reserve(config.rules().len() + 1); + + // Add a connmark to anything in/out the guest, to be able to later + // track/filter per guest, e.g. in the pve-conntrack-tool. + // Need to be first, such that it is always applied. + commands.push(Add::rule(AddRule::from_statement( + chain.clone(), + Mangle::ct_mark(vmid), + ))); for config_rule in config.rules() { for rule in NftRule::from_config_rule(config_rule, &env)? { diff --git a/proxmox-firewall/tests/snapshots/integration_tests__firewall.snap b/proxmox-firewall/tests/snapshots/integration_tests__firewall.snap index 9194fc6..aa29e6e 100644 --- a/proxmox-firewall/tests/snapshots/integration_tests__firewall.snap +++ b/proxmox-firewall/tests/snapshots/integration_tests__firewall.snap @@ -1,7 +1,6 @@ --- source: proxmox-firewall/tests/integration_tests.rs expression: "firewall.full_host_fw().expect(\"firewall can be generated\")" -snapshot_kind: text --- { "nftables": [ @@ -4373,6 +4372,27 @@ snapshot_kind: text } } }, + { + "add": { + "rule": { + "family": "bridge", + "table": "proxmox-firewall-guests", + "chain": "guest-100-in", + "expr": [ + { + "mangle": { + "key": { + "ct": { + "key": "mark" + } + }, + "value": 100 + } + } + ] + } + } + }, { "add": { "rule": { @@ -4648,6 +4668,27 @@ snapshot_kind: text } } }, + { + "add": { + "rule": { + "family": "bridge", + "table": "proxmox-firewall-guests", + "chain": "guest-100-out", + "expr": [ + { + "mangle": { + "key": { + "ct": { + "key": "mark" + } + }, + "value": 100 + } + } + ] + } + } + }, { "add": { "rule": { @@ -5034,6 +5075,27 @@ snapshot_kind: text } } }, + { + "add": { + "rule": { + "family": "bridge", + "table": "proxmox-firewall-guests", + "chain": "guest-101-in", + "expr": [ + { + "mangle": { + "key": { + "ct": { + "key": "mark" + } + }, + "value": 101 + } + } + ] + } + } + }, { "add": { "rule": { @@ -5096,6 +5158,27 @@ snapshot_kind: text } } }, + { + "add": { + "rule": { + "family": "bridge", + "table": "proxmox-firewall-guests", + "chain": "guest-101-out", + "expr": [ + { + "mangle": { + "key": { + "ct": { + "key": "mark" + } + }, + "value": 101 + } + } + ] + } + } + }, { "add": { "rule": { diff --git a/proxmox-nftables/src/expression.rs b/proxmox-nftables/src/expression.rs index e9ef94f..cbafe85 100644 --- a/proxmox-nftables/src/expression.rs +++ b/proxmox-nftables/src/expression.rs @@ -12,6 +12,8 @@ use proxmox_ve_config::firewall::types::port::{PortEntry, PortList}; use proxmox_ve_config::firewall::types::rule_match::{IcmpCode, IcmpType, Icmpv6Code, Icmpv6Type}; #[cfg(feature = "config-ext")] use proxmox_ve_config::firewall::types::Cidr; +#[cfg(feature = "config-ext")] +use proxmox_ve_config::guest::types::Vmid; #[derive(Clone, Debug, Deserialize, Serialize)] #[serde(rename_all = "lowercase")] @@ -267,6 +269,13 @@ impl From<&BridgeName> for Expression { } } +#[cfg(feature = "config-ext")] +impl From<Vmid> for Expression { + fn from(value: Vmid) -> Self { + Expression::Number(value.raw_value().into()) + } +} + #[derive(Clone, Debug, Deserialize, Serialize)] pub struct Meta { key: String, diff --git a/proxmox-nftables/src/statement.rs b/proxmox-nftables/src/statement.rs index 5483368..3264e6c 100644 --- a/proxmox-nftables/src/statement.rs +++ b/proxmox-nftables/src/statement.rs @@ -10,6 +10,7 @@ use proxmox_ve_config::firewall::types::rule::Verdict as ConfigVerdict; #[cfg(feature = "config-ext")] use proxmox_ve_config::guest::types::Vmid; +use crate::expression::Ct; use crate::expression::Meta; use crate::helper::{NfVec, Null}; use crate::types::{RateTimescale, RateUnit, Verdict}; @@ -370,12 +371,19 @@ pub struct Mangle { } impl Mangle { - pub fn set_mark(value: impl Into<Expression>) -> Self { + pub fn meta_mark(value: impl Into<Expression>) -> Self { Self { key: Meta::new("mark").into(), value: value.into(), } } + + pub fn ct_mark(value: impl Into<Expression>) -> Self { + Self { + key: Ct::new("mark", None).into(), + value: value.into(), + } + } } #[derive(Clone, Copy, Debug, Deserialize, Serialize)] -- 2.48.1 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel