From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [45.144.208.40]) by lore.proxmox.com (Postfix) with ESMTPS id 6175B1FF0AE for ; Tue, 27 Oct 2026 09:56:47 +0100 (CET) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 54E41216D6; Tue, 27 Oct 2026 09:56:16 +0100 (CET) From: Hannes Laimer To: pve-devel@lists.proxmox.com Subject: [PATCH proxmox-ve-rs v3 11/45] ve-config: firewall: expose protocol, icmp type and code numbers Date: Tue, 27 Oct 2026 09:54:53 +0100 Message-ID: <20261027085527.702738-12-h.laimer@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20261027085527.702738-1-h.laimer@proxmox.com> References: <20261027085527.702738-1-h.laimer@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1793091345252 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.340 Adjusted score from AWL reputation of From: address DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: SPQIRVIIUDJKFQH3W5H563I5ZWFKUAYH X-Message-ID-Hash: SPQIRVIIUDJKFQH3W5H563I5ZWFKUAYH X-MailFrom: h.laimer@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: A packet carries its protocol, ICMP type and code as numbers, while an ICMP type or code may be given by name. The tables that map those names to numbers are private. Expose the numbers, so a caller does not need its own copy of the tables. Signed-off-by: Hannes Laimer --- .../src/firewall/types/rule_match.rs | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/proxmox-ve-config/src/firewall/types/rule_match.rs b/proxmox-ve-config/src/firewall/types/rule_match.rs index 8e9c0c69efe8..e408b68a3b1a 100644 --- a/proxmox-ve-config/src/firewall/types/rule_match.rs +++ b/proxmox-ve-config/src/firewall/types/rule_match.rs @@ -327,6 +327,20 @@ impl Protocol { })) } + pub fn number(&self) -> Option { + match self { + Self::Dccp(_) => Some(33), + Self::Sctp(_) => Some(132), + Self::Tcp(_) => Some(6), + Self::Udp(_) => Some(17), + Self::UdpLite(_) => Some(136), + Self::Icmp(_) => Some(1), + Self::Icmpv6(_) => Some(58), + Self::Named(_) => None, + Self::Numeric(number) => Some(*number), + } + } + pub fn family(&self) -> Option { match self { Self::Icmp(_) => Some(Family::V4), @@ -580,6 +594,23 @@ const ICMP_TYPES: [(&str, u8); 15] = sorted!([ ("timestamp-request", 13), ]); +fn table_number(table: &[(&str, u8)], name: &str) -> u8 { + let index = table + .binary_search_by(|v| v.0.cmp(name)) + .expect("every named type and code is built from a name in its table"); + table[index].1 +} + +impl IcmpType { + pub fn number(&self) -> Option { + match self { + IcmpType::Numeric(ty) => Some(*ty), + IcmpType::Named(name) => Some(table_number(&ICMP_TYPES, name)), + IcmpType::Any => None, + } + } +} + impl std::str::FromStr for IcmpType { type Err = Error; @@ -628,6 +659,15 @@ const ICMP_CODES: [(&str, u8); 7] = sorted!([ ("prot-unreachable", 2), ]); +impl IcmpCode { + pub fn number(&self) -> u8 { + match self { + IcmpCode::Numeric(code) => *code, + IcmpCode::Named(name) => table_number(&ICMP_CODES, name), + } + } +} + impl std::str::FromStr for IcmpCode { type Err = Error; @@ -800,6 +840,16 @@ const ICMPV6_TYPES: [(&str, u8); 19] = sorted!([ ("time-exceeded", 3), ]); +impl Icmpv6Type { + pub fn number(&self) -> Option { + match self { + Icmpv6Type::Numeric(ty) => Some(*ty), + Icmpv6Type::Named(name) => Some(table_number(&ICMPV6_TYPES, name)), + Icmpv6Type::Any => None, + } + } +} + impl std::str::FromStr for Icmpv6Type { type Err = Error; @@ -847,6 +897,15 @@ const ICMPV6_CODES: [(&str, u8); 6] = sorted!([ ("reject-route", 6), ]); +impl Icmpv6Code { + pub fn number(&self) -> u8 { + match self { + Icmpv6Code::Numeric(code) => *code, + Icmpv6Code::Named(name) => table_number(&ICMPV6_CODES, name), + } + } +} + impl std::str::FromStr for Icmpv6Code { type Err = Error; -- 2.47.3