public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [pve-devel] [PATCH proxmox{-ve-rs, -firewall} 0/4] Fix ipfilters in proxmox-firewall
@ 2025-09-25 10:05 Stefan Hanreich
  2025-09-25 10:05 ` [pve-devel] [PATCH proxmox-ve-rs 1/1] config: guest: store network devices in BTreeMap Stefan Hanreich
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Stefan Hanreich @ 2025-09-25 10:05 UTC (permalink / raw)
  To: pve-devel

This patch series addresses two issues with ipfilters:

* containers would have the wrong CIDR inserted into the auto-generated ipfilter
  ipsets
* The nomatch logic isn't working correctly, due to wrong inversion of logic,
  leading to ipfilters not working at all

Including the rustfmt patch here as well, instead of separately since we touch
some of the imports that get changed there - leading to conflicts on applying
otherwise.

proxmox-ve-rs:

Stefan Hanreich (1):
  config: guest: store network devices in BTreeMap

 proxmox-ve-config/src/guest/vm.rs | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)


proxmox-firewall:

Stefan Hanreich (3):
  run rustfmt
  ipfilter: fix wrong entries for containers
  fix #6336: fix ipfilter matching logic

 proxmox-firewall/src/config.rs                |   6 +-
 proxmox-firewall/src/firewall.rs              |  16 +-
 proxmox-firewall/src/object.rs                |   6 +-
 proxmox-firewall/src/rule.rs                  | 155 +++++--
 proxmox-firewall/tests/input/100.conf         |   1 +
 .../integration_tests__firewall.snap          | 416 ++++++++++++++++++
 6 files changed, 559 insertions(+), 41 deletions(-)


Summary over all repositories:
  7 files changed, 563 insertions(+), 45 deletions(-)

-- 
Generated by git-murpp 0.8.0

_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [pve-devel] [PATCH proxmox-ve-rs 1/1] config: guest: store network devices in BTreeMap
  2025-09-25 10:05 [pve-devel] [PATCH proxmox{-ve-rs, -firewall} 0/4] Fix ipfilters in proxmox-firewall Stefan Hanreich
@ 2025-09-25 10:05 ` Stefan Hanreich
  2025-09-25 10:05 ` [pve-devel] [PATCH proxmox-firewall 1/3] run rustfmt Stefan Hanreich
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Stefan Hanreich @ 2025-09-25 10:05 UTC (permalink / raw)
  To: pve-devel

Enables iterating over the network devices in order, without
performing any additional sorting at the call sites. This makes the
output in proxmox-firewall stable, which is useful for test cases as
well as for comparing the output of different proxmox-firewall runs.

Signed-off-by: Stefan Hanreich <s.hanreich@proxmox.com>
---
 proxmox-ve-config/src/guest/vm.rs | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/proxmox-ve-config/src/guest/vm.rs b/proxmox-ve-config/src/guest/vm.rs
index cc97781..baff1b8 100644
--- a/proxmox-ve-config/src/guest/vm.rs
+++ b/proxmox-ve-config/src/guest/vm.rs
@@ -1,4 +1,4 @@
-use std::collections::HashMap;
+use std::collections::BTreeMap;
 use std::io;
 use std::str::FromStr;
 
@@ -278,7 +278,7 @@ impl FromStr for NetworkDevice {
 #[derive(Debug, Default)]
 #[cfg_attr(test, derive(Eq, PartialEq))]
 pub struct NetworkConfig {
-    network_devices: HashMap<i64, NetworkDevice>,
+    network_devices: BTreeMap<i64, NetworkDevice>,
 }
 
 impl NetworkConfig {
@@ -300,12 +300,12 @@ impl NetworkConfig {
         bail!("No index found in net key string: {key}")
     }
 
-    pub fn network_devices(&self) -> &HashMap<i64, NetworkDevice> {
+    pub fn network_devices(&self) -> &BTreeMap<i64, NetworkDevice> {
         &self.network_devices
     }
 
     pub fn parse<R: io::BufRead>(input: R) -> Result<Self, Error> {
-        let mut network_devices = HashMap::new();
+        let mut network_devices = BTreeMap::new();
 
         for line in input.lines() {
             let line = line?;
-- 
2.47.3


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [pve-devel] [PATCH proxmox-firewall 1/3] run rustfmt
  2025-09-25 10:05 [pve-devel] [PATCH proxmox{-ve-rs, -firewall} 0/4] Fix ipfilters in proxmox-firewall Stefan Hanreich
  2025-09-25 10:05 ` [pve-devel] [PATCH proxmox-ve-rs 1/1] config: guest: store network devices in BTreeMap Stefan Hanreich
@ 2025-09-25 10:05 ` Stefan Hanreich
  2025-09-25 10:05 ` [pve-devel] [PATCH proxmox-firewall 2/3] ipfilter: fix wrong entries for containers Stefan Hanreich
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Stefan Hanreich @ 2025-09-25 10:05 UTC (permalink / raw)
  To: pve-devel

Signed-off-by: Stefan Hanreich <s.hanreich@proxmox.com>
---
 proxmox-firewall/src/config.rs   |  6 +++---
 proxmox-firewall/src/firewall.rs |  6 +++---
 proxmox-firewall/src/object.rs   |  6 +++---
 proxmox-firewall/src/rule.rs     | 30 ++++++++++++++----------------
 4 files changed, 23 insertions(+), 25 deletions(-)

diff --git a/proxmox-firewall/src/config.rs b/proxmox-firewall/src/config.rs
index d6a4df5..8bd9f2a 100644
--- a/proxmox-firewall/src/config.rs
+++ b/proxmox-firewall/src/config.rs
@@ -3,7 +3,7 @@ use std::default::Default;
 use std::fs::{self, DirEntry, File, ReadDir};
 use std::io::{self, BufReader};
 
-use anyhow::{bail, format_err, Context, Error};
+use anyhow::{Context, Error, bail, format_err};
 
 use proxmox_log as log;
 
@@ -17,10 +17,10 @@ use proxmox_ve_config::guest::types::Vmid;
 use proxmox_ve_config::guest::{GuestEntry, GuestMap};
 use proxmox_ve_config::host::types::BridgeName;
 
-use proxmox_network_api::{get_network_interfaces, AltnameMapping};
+use proxmox_network_api::{AltnameMapping, get_network_interfaces};
+use proxmox_nftables::NftClient;
 use proxmox_nftables::command::{CommandOutput, Commands, List, ListOutput};
 use proxmox_nftables::types::ListChain;
-use proxmox_nftables::NftClient;
 use proxmox_ve_config::sdn::{
     config::{RunningConfig, SdnConfig},
     ipam::{Ipam, IpamJson},
diff --git a/proxmox-firewall/src/firewall.rs b/proxmox-firewall/src/firewall.rs
index 8cac190..5012610 100644
--- a/proxmox-firewall/src/firewall.rs
+++ b/proxmox-firewall/src/firewall.rs
@@ -1,7 +1,7 @@
 use std::collections::BTreeMap;
 use std::fs;
 
-use anyhow::{Error, bail};
+use anyhow::{bail, Error};
 
 use proxmox_log as log;
 
@@ -25,17 +25,17 @@ use proxmox_ve_config::firewall::guest::Config as GuestConfig;
 use proxmox_ve_config::firewall::host::Config as HostConfig;
 
 use proxmox_network_types::ip_address::{Cidr, Ipv6Cidr};
-use proxmox_ve_config::firewall::types::Group;
 use proxmox_ve_config::firewall::types::ipset::{
     Ipfilter, Ipset, IpsetEntry, IpsetName, IpsetScope,
 };
 use proxmox_ve_config::firewall::types::log::{LogLevel as ConfigLogLevel, LogRateLimit};
 use proxmox_ve_config::firewall::types::rule::{Direction, Verdict as ConfigVerdict};
+use proxmox_ve_config::firewall::types::Group;
 use proxmox_ve_config::guest::types::Vmid;
 
 use crate::config::FirewallConfig;
 use crate::object::{NftObjectEnv, ToNftObjects};
-use crate::rule::{NftRule, NftRuleEnv, generate_verdict};
+use crate::rule::{generate_verdict, NftRule, NftRuleEnv};
 
 static CLUSTER_TABLE_NAME: &str = "proxmox-firewall";
 static HOST_TABLE_NAME: &str = "proxmox-firewall";
diff --git a/proxmox-firewall/src/object.rs b/proxmox-firewall/src/object.rs
index a7575bb..42423b9 100644
--- a/proxmox-firewall/src/object.rs
+++ b/proxmox-firewall/src/object.rs
@@ -1,19 +1,19 @@
-use anyhow::{Error, format_err};
+use anyhow::{format_err, Error};
 
 use proxmox_log as log;
 use proxmox_nftables::{
-    Command, Expression,
     command::{Add, Flush},
     expression::Prefix,
     types::{
         AddCtHelper, AddElement, CtHelperProtocol, ElementType, L3Protocol, SetConfig, SetFlag,
         SetName, TablePart,
     },
+    Command, Expression,
 };
 use proxmox_ve_config::{
     firewall::{
         ct_helper::CtHelperMacro,
-        types::{Alias, Ipset, alias::AliasName, ipset::IpsetAddress},
+        types::{alias::AliasName, ipset::IpsetAddress, Alias, Ipset},
     },
     guest::types::Vmid,
 };
diff --git a/proxmox-firewall/src/rule.rs b/proxmox-firewall/src/rule.rs
index 77bc6ea..2512537 100644
--- a/proxmox-firewall/src/rule.rs
+++ b/proxmox-firewall/src/rule.rs
@@ -1,20 +1,19 @@
 use std::ops::{Deref, DerefMut};
 
-use anyhow::{Error, bail, format_err};
+use anyhow::{bail, format_err, Error};
 
 use proxmox_log as log;
 use proxmox_nftables::{
-    Expression, Statement,
     expression::{Ct, IpFamily, Meta, Payload, Prefix},
     statement::{Log, LogLevel, Match, Operator},
     types::{AddRule, ChainPart, SetName, TableFamily, TablePart},
+    Expression, Statement,
 };
 use proxmox_ve_config::{
     firewall::{
         ct_helper::CtHelperMacro,
-        fw_macros::{FwMacro, get_macro},
+        fw_macros::{get_macro, FwMacro},
         types::{
-            Alias, Rule,
             alias::AliasName,
             ipset::{Ipfilter, IpsetName},
             log::LogRateLimit,
@@ -22,6 +21,7 @@ use proxmox_ve_config::{
             rule_match::{
                 Icmp, Icmpv6, IpAddrMatch, IpMatch, Ports, Protocol, RuleMatch, Sctp, Tcp, Udp,
             },
+            Alias, Rule,
         },
     },
     guest::types::Vmid,
@@ -691,18 +691,16 @@ impl ToNftRules for Ipfilter<'_> {
                 if env.contains_family(Family::V4) {
                     base_rule.set_family(Family::V4);
 
-                    base_rule.append(&mut vec![
-                        Match::new_ne(
-                            Payload::field("arp", "saddr ip"),
-                            Expression::set_name(&SetName::ipset_name(
-                                Family::V4,
-                                self.ipset().name(),
-                                env.vmid,
-                                false,
-                            )),
-                        )
-                        .into(),
-                    ]);
+                    base_rule.append(&mut vec![Match::new_ne(
+                        Payload::field("arp", "saddr ip"),
+                        Expression::set_name(&SetName::ipset_name(
+                            Family::V4,
+                            self.ipset().name(),
+                            env.vmid,
+                            false,
+                        )),
+                    )
+                    .into()]);
 
                     rules.push(base_rule);
                 }
-- 
2.47.3


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [pve-devel] [PATCH proxmox-firewall 2/3] ipfilter: fix wrong entries for containers
  2025-09-25 10:05 [pve-devel] [PATCH proxmox{-ve-rs, -firewall} 0/4] Fix ipfilters in proxmox-firewall Stefan Hanreich
  2025-09-25 10:05 ` [pve-devel] [PATCH proxmox-ve-rs 1/1] config: guest: store network devices in BTreeMap Stefan Hanreich
  2025-09-25 10:05 ` [pve-devel] [PATCH proxmox-firewall 1/3] run rustfmt Stefan Hanreich
@ 2025-09-25 10:05 ` Stefan Hanreich
  2025-09-25 10:05 ` [pve-devel] [PATCH proxmox-firewall 3/3] fix #6336: fix ipfilter matching logic Stefan Hanreich
  2025-09-25 12:22 ` [pve-devel] superseded: [PATCH proxmox{-ve-rs, -firewall} 0/4] Fix ipfilters in proxmox-firewall Stefan Hanreich
  4 siblings, 0 replies; 6+ messages in thread
From: Stefan Hanreich @ 2025-09-25 10:05 UTC (permalink / raw)
  To: pve-devel

The firewall used the CIDR from the container network configuration
for autogenerating the IP filter. If an IP of 192.0.2.1/24 was
configured, then the whole 192.0.2.0/24 range was allowed instead of
only 192.0.2.1 .

Signed-off-by: Stefan Hanreich <s.hanreich@proxmox.com>
---
 proxmox-firewall/src/firewall.rs              |  10 +-
 proxmox-firewall/tests/input/100.conf         |   1 +
 .../integration_tests__firewall.snap          | 316 ++++++++++++++++++
 3 files changed, 324 insertions(+), 3 deletions(-)

diff --git a/proxmox-firewall/src/firewall.rs b/proxmox-firewall/src/firewall.rs
index 5012610..ddf839b 100644
--- a/proxmox-firewall/src/firewall.rs
+++ b/proxmox-firewall/src/firewall.rs
@@ -24,7 +24,7 @@ use proxmox_ve_config::firewall::ct_helper::get_cthelper;
 use proxmox_ve_config::firewall::guest::Config as GuestConfig;
 use proxmox_ve_config::firewall::host::Config as HostConfig;
 
-use proxmox_network_types::ip_address::{Cidr, Ipv6Cidr};
+use proxmox_network_types::ip_address::{Cidr, Ipv4Cidr, Ipv6Cidr};
 use proxmox_ve_config::firewall::types::ipset::{
     Ipfilter, Ipset, IpsetEntry, IpsetName, IpsetScope,
 };
@@ -815,11 +815,15 @@ impl Firewall {
                     ipset.push(IpsetEntry::from(Cidr::from(cidr)));
 
                     if let Some(ip_address) = network_device.ip() {
-                        ipset.push(IpsetEntry::from(Cidr::from(ip_address)));
+                        ipset.push(IpsetEntry::from(Cidr::from(Ipv4Cidr::from(
+                            *ip_address.address(),
+                        ))));
                     }
 
                     if let Some(ip6_address) = network_device.ip6() {
-                        ipset.push(IpsetEntry::from(Cidr::from(ip6_address)));
+                        ipset.push(IpsetEntry::from(Cidr::from(Ipv6Cidr::from(
+                            *ip6_address.address(),
+                        ))));
                     }
 
                     commands.append(&mut ipset.to_nft_objects(&env)?);
diff --git a/proxmox-firewall/tests/input/100.conf b/proxmox-firewall/tests/input/100.conf
index cf9af7f..1f81186 100644
--- a/proxmox-firewall/tests/input/100.conf
+++ b/proxmox-firewall/tests/input/100.conf
@@ -5,6 +5,7 @@ hostname: host1
 memory: 512
 net1: name=eth0,bridge=simple1,firewall=1,hwaddr=BC:24:11:4D:B0:FF,ip=dhcp,ip6=fd80::1234/64,type=veth
 net2: name=eth0,bridge=simple1,hwaddr=BC:24:11:4D:B0:FF,ip=dhcp,ip6=fd80::1234/64,type=veth
+net3: name=eth0,bridge=simple2,firewall=1,hwaddr=BC:24:11:4D:B0:FE,ip=192.0.2.10/24,ip6=fd80::1235/64,type=veth
 ostype: debian
 rootfs: local-lvm:vm-90001-disk-0,size=2G
 swap: 512
diff --git a/proxmox-firewall/tests/snapshots/integration_tests__firewall.snap b/proxmox-firewall/tests/snapshots/integration_tests__firewall.snap
index e3db8ae..feeda5b 100644
--- a/proxmox-firewall/tests/snapshots/integration_tests__firewall.snap
+++ b/proxmox-firewall/tests/snapshots/integration_tests__firewall.snap
@@ -4384,6 +4384,306 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
         }
       }
     },
+    {
+      "add": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v4-guest-100/ipfilter-net3",
+          "type": "ipv4_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v4-guest-100/ipfilter-net3"
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v4-guest-100/ipfilter-net3-nomatch",
+          "type": "ipv4_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v4-guest-100/ipfilter-net3-nomatch"
+        }
+      }
+    },
+    {
+      "add": {
+        "element": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v4-guest-100/ipfilter-net3",
+          "elem": [
+            {
+              "prefix": {
+                "addr": "192.0.2.10",
+                "len": 32
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v6-guest-100/ipfilter-net3",
+          "type": "ipv6_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v6-guest-100/ipfilter-net3"
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v6-guest-100/ipfilter-net3-nomatch",
+          "type": "ipv6_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v6-guest-100/ipfilter-net3-nomatch"
+        }
+      }
+    },
+    {
+      "add": {
+        "element": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v6-guest-100/ipfilter-net3",
+          "elem": [
+            {
+              "prefix": {
+                "addr": "fe80::be24:11ff:fe4d:b0fe",
+                "len": 128
+              }
+            },
+            {
+              "prefix": {
+                "addr": "fd80::1235",
+                "len": 128
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "add": {
+        "rule": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "chain": "guest-100-in",
+          "expr": [
+            {
+              "match": {
+                "op": "==",
+                "left": {
+                  "meta": {
+                    "key": "oifname"
+                  }
+                },
+                "right": "veth100i3"
+              }
+            },
+            {
+              "match": {
+                "op": "!=",
+                "left": {
+                  "payload": {
+                    "protocol": "arp",
+                    "field": "daddr ip"
+                  }
+                },
+                "right": "@v4-guest-100/ipfilter-net3"
+              }
+            },
+            {
+              "drop": null
+            }
+          ]
+        }
+      }
+    },
+    {
+      "add": {
+        "rule": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "chain": "guest-100-out",
+          "expr": [
+            {
+              "match": {
+                "op": "==",
+                "left": {
+                  "meta": {
+                    "key": "iifname"
+                  }
+                },
+                "right": "veth100i3"
+              }
+            },
+            {
+              "match": {
+                "op": "!=",
+                "left": {
+                  "payload": {
+                    "protocol": "ip",
+                    "field": "saddr"
+                  }
+                },
+                "right": "@v4-guest-100/ipfilter-net3"
+              }
+            },
+            {
+              "match": {
+                "op": "==",
+                "left": {
+                  "payload": {
+                    "protocol": "ip",
+                    "field": "saddr"
+                  }
+                },
+                "right": "@v4-guest-100/ipfilter-net3-nomatch"
+              }
+            },
+            {
+              "drop": null
+            }
+          ]
+        }
+      }
+    },
+    {
+      "add": {
+        "rule": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "chain": "guest-100-out",
+          "expr": [
+            {
+              "match": {
+                "op": "==",
+                "left": {
+                  "meta": {
+                    "key": "iifname"
+                  }
+                },
+                "right": "veth100i3"
+              }
+            },
+            {
+              "match": {
+                "op": "!=",
+                "left": {
+                  "payload": {
+                    "protocol": "ip6",
+                    "field": "saddr"
+                  }
+                },
+                "right": "@v6-guest-100/ipfilter-net3"
+              }
+            },
+            {
+              "match": {
+                "op": "==",
+                "left": {
+                  "payload": {
+                    "protocol": "ip6",
+                    "field": "saddr"
+                  }
+                },
+                "right": "@v6-guest-100/ipfilter-net3-nomatch"
+              }
+            },
+            {
+              "drop": null
+            }
+          ]
+        }
+      }
+    },
+    {
+      "add": {
+        "rule": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "chain": "guest-100-out",
+          "expr": [
+            {
+              "match": {
+                "op": "==",
+                "left": {
+                  "meta": {
+                    "key": "iifname"
+                  }
+                },
+                "right": "veth100i3"
+              }
+            },
+            {
+              "match": {
+                "op": "!=",
+                "left": {
+                  "payload": {
+                    "protocol": "arp",
+                    "field": "saddr ip"
+                  }
+                },
+                "right": "@v4-guest-100/ipfilter-net3"
+              }
+            },
+            {
+              "drop": null
+            }
+          ]
+        }
+      }
+    },
     {
       "add": {
         "rule": {
@@ -4742,6 +5042,14 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
                   "target": "guest-100-in"
                 }
               }
+            ],
+            [
+              "veth100i3",
+              {
+                "goto": {
+                  "target": "guest-100-in"
+                }
+              }
             ]
           ]
         }
@@ -4886,6 +5194,14 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
                   "target": "guest-100-out"
                 }
               }
+            ],
+            [
+              "veth100i3",
+              {
+                "goto": {
+                  "target": "guest-100-out"
+                }
+              }
             ]
           ]
         }
-- 
2.47.3


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [pve-devel] [PATCH proxmox-firewall 3/3] fix #6336: fix ipfilter matching logic
  2025-09-25 10:05 [pve-devel] [PATCH proxmox{-ve-rs, -firewall} 0/4] Fix ipfilters in proxmox-firewall Stefan Hanreich
                   ` (2 preceding siblings ...)
  2025-09-25 10:05 ` [pve-devel] [PATCH proxmox-firewall 2/3] ipfilter: fix wrong entries for containers Stefan Hanreich
@ 2025-09-25 10:05 ` Stefan Hanreich
  2025-09-25 12:22 ` [pve-devel] superseded: [PATCH proxmox{-ve-rs, -firewall} 0/4] Fix ipfilters in proxmox-firewall Stefan Hanreich
  4 siblings, 0 replies; 6+ messages in thread
From: Stefan Hanreich @ 2025-09-25 10:05 UTC (permalink / raw)
  To: pve-devel

Matching on ipsets in the firewall generally works by matching on two
sets (one for match, one for nomatch):

  ip saddr @ipfilter ip saddr != @ipfilter-nomatch <verdict>

Ipfilters were created with the comparison operators simply inverted,
which leads to ipfilters with empty nomatch sets never working, since
the second expression always evaluates to false on empty sets:

  ip saddr != @ipfilter ip saddr = @ipfilter-nomatch drop

In order to properly invert the logic, two statements need to be
generated (analogous to negation in boolean logic):

  ip saddr != @ipfilter drop
  ip saddr = @ipfilter-nomatch drop

To avoid cluttering the existing set handling function and to clearly
separate the rule generation logic, introduce a completely new
function that handles ipfilters separately. This also allows the set
handling function to validate the name of ipsets in a later commit,
since it only operates on ipsets that have to exist in the firewall
config, whereas ipfilters do not necessarily exist in the firewall
configuration.

Signed-off-by: Stefan Hanreich <s.hanreich@proxmox.com>
---
 proxmox-firewall/src/rule.rs                  | 125 ++++++++-
 .../integration_tests__firewall.snap          | 238 +++++++++++++-----
 2 files changed, 281 insertions(+), 82 deletions(-)

diff --git a/proxmox-firewall/src/rule.rs b/proxmox-firewall/src/rule.rs
index 2512537..6332a74 100644
--- a/proxmox-firewall/src/rule.rs
+++ b/proxmox-firewall/src/rule.rs
@@ -283,12 +283,12 @@ impl ToNftRules for RuleMatch {
     }
 }
 
+/// Adds statements that evaluate to true if an element does match an IPSet
 fn handle_set(
     rules: &mut Vec<NftRule>,
     name: &IpsetName,
     field_name: &str,
     env: &NftRuleEnv,
-    contains: bool,
 ) -> Result<(), Error> {
     let mut new_rules = rules
         .drain(..)
@@ -303,7 +303,7 @@ fn handle_set(
 
                 rule.append(&mut vec![
                     Match::new(
-                        if contains { Operator::Eq } else { Operator::Ne },
+                        Operator::Eq,
                         field.clone(),
                         Expression::set_name(&SetName::ipset_name(
                             Family::V4,
@@ -314,7 +314,7 @@ fn handle_set(
                     )
                     .into(),
                     Match::new(
-                        if contains { Operator::Ne } else { Operator::Eq },
+                        Operator::Ne,
                         field,
                         Expression::set_name(&SetName::ipset_name(
                             Family::V4,
@@ -337,7 +337,7 @@ fn handle_set(
 
                 rule.append(&mut vec![
                     Match::new(
-                        if contains { Operator::Eq } else { Operator::Ne },
+                        Operator::Eq,
                         field.clone(),
                         Expression::set_name(&SetName::ipset_name(
                             Family::V6,
@@ -348,7 +348,7 @@ fn handle_set(
                     )
                     .into(),
                     Match::new(
-                        if contains { Operator::Ne } else { Operator::Eq },
+                        Operator::Ne,
                         field,
                         Expression::set_name(&SetName::ipset_name(
                             Family::V6,
@@ -372,6 +372,111 @@ fn handle_set(
     Ok(())
 }
 
+/// Adds statements that evaluate to true if an element does *not* match an IPFilter
+fn handle_ipfilter(
+    rules: &mut Vec<NftRule>,
+    name: &IpsetName,
+    field_name: &str,
+    env: &NftRuleEnv,
+) -> Result<(), Error> {
+    let mut new_rules = rules
+        .drain(..)
+        .flat_map(|rule| {
+            let mut new_rules = Vec::new();
+
+            if matches!(rule.family(), Some(Family::V4) | None) && env.contains_family(Family::V4) {
+                let field = Payload::field("ip", field_name);
+
+                let mut match_rule = rule.clone();
+                match_rule.set_family(Family::V4);
+
+                match_rule.push(
+                    Match::new(
+                        Operator::Ne,
+                        field.clone(),
+                        Expression::set_name(&SetName::ipset_name(
+                            Family::V4,
+                            name,
+                            env.vmid,
+                            false,
+                        )),
+                    )
+                    .into(),
+                );
+
+                new_rules.push(match_rule);
+
+                let mut nomatch_rule = rule.clone();
+                nomatch_rule.set_family(Family::V4);
+
+                nomatch_rule.push(
+                    Match::new(
+                        Operator::Eq,
+                        field,
+                        Expression::set_name(&SetName::ipset_name(
+                            Family::V4,
+                            name,
+                            env.vmid,
+                            true,
+                        )),
+                    )
+                    .into(),
+                );
+
+                new_rules.push(nomatch_rule);
+            }
+
+            if matches!(rule.family(), Some(Family::V6) | None) && env.contains_family(Family::V6) {
+                let field = Payload::field("ip6", field_name);
+
+                let mut match_rule = rule.clone();
+                match_rule.set_family(Family::V4);
+
+                match_rule.push(
+                    Match::new(
+                        Operator::Ne,
+                        field.clone(),
+                        Expression::set_name(&SetName::ipset_name(
+                            Family::V6,
+                            name,
+                            env.vmid,
+                            false,
+                        )),
+                    )
+                    .into(),
+                );
+
+                new_rules.push(match_rule);
+
+                let mut nomatch_rule = rule.clone();
+                nomatch_rule.set_family(Family::V4);
+
+                nomatch_rule.push(
+                    Match::new(
+                        Operator::Eq,
+                        field,
+                        Expression::set_name(&SetName::ipset_name(
+                            Family::V6,
+                            name,
+                            env.vmid,
+                            true,
+                        )),
+                    )
+                    .into(),
+                );
+
+                new_rules.push(nomatch_rule);
+            }
+
+            new_rules
+        })
+        .collect::<Vec<NftRule>>();
+
+    rules.append(&mut new_rules);
+
+    Ok(())
+}
+
 fn handle_match(
     rules: &mut Vec<NftRule>,
     ip: &IpAddrMatch,
@@ -447,7 +552,7 @@ fn handle_match(
 
             Ok(())
         }
-        IpAddrMatch::Set(name) => handle_set(rules, name, field_name, env, true),
+        IpAddrMatch::Set(name) => handle_set(rules, name, field_name, env),
     }
 }
 
@@ -679,13 +784,7 @@ impl ToNftRules for Ipfilter<'_> {
                 );
 
                 let mut ipfilter_rules = vec![base_rule.clone()];
-                handle_set(
-                    &mut ipfilter_rules,
-                    self.ipset().name(),
-                    "saddr",
-                    env,
-                    false,
-                )?;
+                handle_ipfilter(&mut ipfilter_rules, self.ipset().name(), "saddr", env)?;
                 rules.append(&mut ipfilter_rules);
 
                 if env.contains_family(Family::V4) {
diff --git a/proxmox-firewall/tests/snapshots/integration_tests__firewall.snap b/proxmox-firewall/tests/snapshots/integration_tests__firewall.snap
index feeda5b..c7d45f1 100644
--- a/proxmox-firewall/tests/snapshots/integration_tests__firewall.snap
+++ b/proxmox-firewall/tests/snapshots/integration_tests__firewall.snap
@@ -4112,7 +4112,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
         "set": {
           "family": "bridge",
           "table": "proxmox-firewall-guests",
-          "name": "v4-guest-100/ipfilter-net1",
+          "name": "v4-guest-100/ipfilter-net3",
           "type": "ipv4_addr",
           "flags": [
             "interval"
@@ -4125,7 +4125,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
         "set": {
           "family": "bridge",
           "table": "proxmox-firewall-guests",
-          "name": "v4-guest-100/ipfilter-net1"
+          "name": "v4-guest-100/ipfilter-net3"
         }
       }
     },
@@ -4134,7 +4134,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
         "set": {
           "family": "bridge",
           "table": "proxmox-firewall-guests",
-          "name": "v4-guest-100/ipfilter-net1-nomatch",
+          "name": "v4-guest-100/ipfilter-net3-nomatch",
           "type": "ipv4_addr",
           "flags": [
             "interval"
@@ -4147,7 +4147,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
         "set": {
           "family": "bridge",
           "table": "proxmox-firewall-guests",
-          "name": "v4-guest-100/ipfilter-net1-nomatch"
+          "name": "v4-guest-100/ipfilter-net3-nomatch"
         }
       }
     },
@@ -4156,12 +4156,12 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
         "element": {
           "family": "bridge",
           "table": "proxmox-firewall-guests",
-          "name": "v4-guest-100/ipfilter-net1",
+          "name": "v4-guest-100/ipfilter-net3",
           "elem": [
             {
               "prefix": {
-                "addr": "172.16.100.0",
-                "len": 24
+                "addr": "192.0.2.10",
+                "len": 32
               }
             }
           ]
@@ -4173,7 +4173,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
         "set": {
           "family": "bridge",
           "table": "proxmox-firewall-guests",
-          "name": "v6-guest-100/ipfilter-net1",
+          "name": "v6-guest-100/ipfilter-net3",
           "type": "ipv6_addr",
           "flags": [
             "interval"
@@ -4186,7 +4186,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
         "set": {
           "family": "bridge",
           "table": "proxmox-firewall-guests",
-          "name": "v6-guest-100/ipfilter-net1"
+          "name": "v6-guest-100/ipfilter-net3"
         }
       }
     },
@@ -4195,7 +4195,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
         "set": {
           "family": "bridge",
           "table": "proxmox-firewall-guests",
-          "name": "v6-guest-100/ipfilter-net1-nomatch",
+          "name": "v6-guest-100/ipfilter-net3-nomatch",
           "type": "ipv6_addr",
           "flags": [
             "interval"
@@ -4208,7 +4208,30 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
         "set": {
           "family": "bridge",
           "table": "proxmox-firewall-guests",
-          "name": "v6-guest-100/ipfilter-net1-nomatch"
+          "name": "v6-guest-100/ipfilter-net3-nomatch"
+        }
+      }
+    },
+    {
+      "add": {
+        "element": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v6-guest-100/ipfilter-net3",
+          "elem": [
+            {
+              "prefix": {
+                "addr": "fe80::be24:11ff:fe4d:b0fe",
+                "len": 128
+              }
+            },
+            {
+              "prefix": {
+                "addr": "fd80::1235",
+                "len": 128
+              }
+            }
+          ]
         }
       }
     },
@@ -4227,7 +4250,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
                     "key": "oifname"
                   }
                 },
-                "right": "veth100i1"
+                "right": "veth100i3"
               }
             },
             {
@@ -4239,7 +4262,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
                     "field": "daddr ip"
                   }
                 },
-                "right": "@v4-guest-100/ipfilter-net1"
+                "right": "@v4-guest-100/ipfilter-net3"
               }
             },
             {
@@ -4264,7 +4287,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
                     "key": "iifname"
                   }
                 },
-                "right": "veth100i1"
+                "right": "veth100i3"
               }
             },
             {
@@ -4276,7 +4299,32 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
                     "field": "saddr"
                   }
                 },
-                "right": "@v4-guest-100/ipfilter-net1"
+                "right": "@v4-guest-100/ipfilter-net3"
+              }
+            },
+            {
+              "drop": null
+            }
+          ]
+        }
+      }
+    },
+    {
+      "add": {
+        "rule": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "chain": "guest-100-out",
+          "expr": [
+            {
+              "match": {
+                "op": "==",
+                "left": {
+                  "meta": {
+                    "key": "iifname"
+                  }
+                },
+                "right": "veth100i3"
               }
             },
             {
@@ -4288,7 +4336,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
                     "field": "saddr"
                   }
                 },
-                "right": "@v4-guest-100/ipfilter-net1-nomatch"
+                "right": "@v4-guest-100/ipfilter-net3-nomatch"
               }
             },
             {
@@ -4313,7 +4361,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
                     "key": "iifname"
                   }
                 },
-                "right": "veth100i1"
+                "right": "veth100i3"
               }
             },
             {
@@ -4325,7 +4373,32 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
                     "field": "saddr"
                   }
                 },
-                "right": "@v6-guest-100/ipfilter-net1"
+                "right": "@v6-guest-100/ipfilter-net3"
+              }
+            },
+            {
+              "drop": null
+            }
+          ]
+        }
+      }
+    },
+    {
+      "add": {
+        "rule": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "chain": "guest-100-out",
+          "expr": [
+            {
+              "match": {
+                "op": "==",
+                "left": {
+                  "meta": {
+                    "key": "iifname"
+                  }
+                },
+                "right": "veth100i3"
               }
             },
             {
@@ -4337,7 +4410,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
                     "field": "saddr"
                   }
                 },
-                "right": "@v6-guest-100/ipfilter-net1-nomatch"
+                "right": "@v6-guest-100/ipfilter-net3-nomatch"
               }
             },
             {
@@ -4362,7 +4435,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
                     "key": "iifname"
                   }
                 },
-                "right": "veth100i1"
+                "right": "veth100i3"
               }
             },
             {
@@ -4374,7 +4447,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
                     "field": "saddr ip"
                   }
                 },
-                "right": "@v4-guest-100/ipfilter-net1"
+                "right": "@v4-guest-100/ipfilter-net3"
               }
             },
             {
@@ -4389,7 +4462,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
         "set": {
           "family": "bridge",
           "table": "proxmox-firewall-guests",
-          "name": "v4-guest-100/ipfilter-net3",
+          "name": "v4-guest-100/ipfilter-net1",
           "type": "ipv4_addr",
           "flags": [
             "interval"
@@ -4402,7 +4475,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
         "set": {
           "family": "bridge",
           "table": "proxmox-firewall-guests",
-          "name": "v4-guest-100/ipfilter-net3"
+          "name": "v4-guest-100/ipfilter-net1"
         }
       }
     },
@@ -4411,7 +4484,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
         "set": {
           "family": "bridge",
           "table": "proxmox-firewall-guests",
-          "name": "v4-guest-100/ipfilter-net3-nomatch",
+          "name": "v4-guest-100/ipfilter-net1-nomatch",
           "type": "ipv4_addr",
           "flags": [
             "interval"
@@ -4424,7 +4497,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
         "set": {
           "family": "bridge",
           "table": "proxmox-firewall-guests",
-          "name": "v4-guest-100/ipfilter-net3-nomatch"
+          "name": "v4-guest-100/ipfilter-net1-nomatch"
         }
       }
     },
@@ -4433,12 +4506,12 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
         "element": {
           "family": "bridge",
           "table": "proxmox-firewall-guests",
-          "name": "v4-guest-100/ipfilter-net3",
+          "name": "v4-guest-100/ipfilter-net1",
           "elem": [
             {
               "prefix": {
-                "addr": "192.0.2.10",
-                "len": 32
+                "addr": "172.16.100.0",
+                "len": 24
               }
             }
           ]
@@ -4450,7 +4523,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
         "set": {
           "family": "bridge",
           "table": "proxmox-firewall-guests",
-          "name": "v6-guest-100/ipfilter-net3",
+          "name": "v6-guest-100/ipfilter-net1",
           "type": "ipv6_addr",
           "flags": [
             "interval"
@@ -4463,7 +4536,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
         "set": {
           "family": "bridge",
           "table": "proxmox-firewall-guests",
-          "name": "v6-guest-100/ipfilter-net3"
+          "name": "v6-guest-100/ipfilter-net1"
         }
       }
     },
@@ -4472,7 +4545,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
         "set": {
           "family": "bridge",
           "table": "proxmox-firewall-guests",
-          "name": "v6-guest-100/ipfilter-net3-nomatch",
+          "name": "v6-guest-100/ipfilter-net1-nomatch",
           "type": "ipv6_addr",
           "flags": [
             "interval"
@@ -4485,30 +4558,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
         "set": {
           "family": "bridge",
           "table": "proxmox-firewall-guests",
-          "name": "v6-guest-100/ipfilter-net3-nomatch"
-        }
-      }
-    },
-    {
-      "add": {
-        "element": {
-          "family": "bridge",
-          "table": "proxmox-firewall-guests",
-          "name": "v6-guest-100/ipfilter-net3",
-          "elem": [
-            {
-              "prefix": {
-                "addr": "fe80::be24:11ff:fe4d:b0fe",
-                "len": 128
-              }
-            },
-            {
-              "prefix": {
-                "addr": "fd80::1235",
-                "len": 128
-              }
-            }
-          ]
+          "name": "v6-guest-100/ipfilter-net1-nomatch"
         }
       }
     },
@@ -4527,7 +4577,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
                     "key": "oifname"
                   }
                 },
-                "right": "veth100i3"
+                "right": "veth100i1"
               }
             },
             {
@@ -4539,7 +4589,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
                     "field": "daddr ip"
                   }
                 },
-                "right": "@v4-guest-100/ipfilter-net3"
+                "right": "@v4-guest-100/ipfilter-net1"
               }
             },
             {
@@ -4564,7 +4614,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
                     "key": "iifname"
                   }
                 },
-                "right": "veth100i3"
+                "right": "veth100i1"
               }
             },
             {
@@ -4576,7 +4626,32 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
                     "field": "saddr"
                   }
                 },
-                "right": "@v4-guest-100/ipfilter-net3"
+                "right": "@v4-guest-100/ipfilter-net1"
+              }
+            },
+            {
+              "drop": null
+            }
+          ]
+        }
+      }
+    },
+    {
+      "add": {
+        "rule": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "chain": "guest-100-out",
+          "expr": [
+            {
+              "match": {
+                "op": "==",
+                "left": {
+                  "meta": {
+                    "key": "iifname"
+                  }
+                },
+                "right": "veth100i1"
               }
             },
             {
@@ -4588,7 +4663,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
                     "field": "saddr"
                   }
                 },
-                "right": "@v4-guest-100/ipfilter-net3-nomatch"
+                "right": "@v4-guest-100/ipfilter-net1-nomatch"
               }
             },
             {
@@ -4613,7 +4688,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
                     "key": "iifname"
                   }
                 },
-                "right": "veth100i3"
+                "right": "veth100i1"
               }
             },
             {
@@ -4625,7 +4700,32 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
                     "field": "saddr"
                   }
                 },
-                "right": "@v6-guest-100/ipfilter-net3"
+                "right": "@v6-guest-100/ipfilter-net1"
+              }
+            },
+            {
+              "drop": null
+            }
+          ]
+        }
+      }
+    },
+    {
+      "add": {
+        "rule": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "chain": "guest-100-out",
+          "expr": [
+            {
+              "match": {
+                "op": "==",
+                "left": {
+                  "meta": {
+                    "key": "iifname"
+                  }
+                },
+                "right": "veth100i1"
               }
             },
             {
@@ -4637,7 +4737,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
                     "field": "saddr"
                   }
                 },
-                "right": "@v6-guest-100/ipfilter-net3-nomatch"
+                "right": "@v6-guest-100/ipfilter-net1-nomatch"
               }
             },
             {
@@ -4662,7 +4762,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
                     "key": "iifname"
                   }
                 },
-                "right": "veth100i3"
+                "right": "veth100i1"
               }
             },
             {
@@ -4674,7 +4774,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
                     "field": "saddr ip"
                   }
                 },
-                "right": "@v4-guest-100/ipfilter-net3"
+                "right": "@v4-guest-100/ipfilter-net1"
               }
             },
             {
@@ -5036,7 +5136,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
           "name": "vm-map-in",
           "elem": [
             [
-              "veth100i1",
+              "veth100i3",
               {
                 "goto": {
                   "target": "guest-100-in"
@@ -5044,7 +5144,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
               }
             ],
             [
-              "veth100i3",
+              "veth100i1",
               {
                 "goto": {
                   "target": "guest-100-in"
@@ -5188,7 +5288,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
           "name": "vm-map-out",
           "elem": [
             [
-              "veth100i1",
+              "veth100i3",
               {
                 "goto": {
                   "target": "guest-100-out"
@@ -5196,7 +5296,7 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
               }
             ],
             [
-              "veth100i3",
+              "veth100i1",
               {
                 "goto": {
                   "target": "guest-100-out"
-- 
2.47.3


_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [pve-devel] superseded: [PATCH proxmox{-ve-rs, -firewall} 0/4] Fix ipfilters in proxmox-firewall
  2025-09-25 10:05 [pve-devel] [PATCH proxmox{-ve-rs, -firewall} 0/4] Fix ipfilters in proxmox-firewall Stefan Hanreich
                   ` (3 preceding siblings ...)
  2025-09-25 10:05 ` [pve-devel] [PATCH proxmox-firewall 3/3] fix #6336: fix ipfilter matching logic Stefan Hanreich
@ 2025-09-25 12:22 ` Stefan Hanreich
  4 siblings, 0 replies; 6+ messages in thread
From: Stefan Hanreich @ 2025-09-25 12:22 UTC (permalink / raw)
  To: pve-devel

https://lore.proxmox.com/pve-devel/20250925122142.228719-1-s.hanreich@proxmox.com/T/

On 9/25/25 12:05 PM, Stefan Hanreich wrote:
> This patch series addresses two issues with ipfilters:
> 
> * containers would have the wrong CIDR inserted into the auto-generated ipfilter
>   ipsets
> * The nomatch logic isn't working correctly, due to wrong inversion of logic,
>   leading to ipfilters not working at all
> 
> Including the rustfmt patch here as well, instead of separately since we touch
> some of the imports that get changed there - leading to conflicts on applying
> otherwise.
> 
> proxmox-ve-rs:
> 
> Stefan Hanreich (1):
>   config: guest: store network devices in BTreeMap
> 
>  proxmox-ve-config/src/guest/vm.rs | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> 
> proxmox-firewall:
> 
> Stefan Hanreich (3):
>   run rustfmt
>   ipfilter: fix wrong entries for containers
>   fix #6336: fix ipfilter matching logic
> 
>  proxmox-firewall/src/config.rs                |   6 +-
>  proxmox-firewall/src/firewall.rs              |  16 +-
>  proxmox-firewall/src/object.rs                |   6 +-
>  proxmox-firewall/src/rule.rs                  | 155 +++++--
>  proxmox-firewall/tests/input/100.conf         |   1 +
>  .../integration_tests__firewall.snap          | 416 ++++++++++++++++++
>  6 files changed, 559 insertions(+), 41 deletions(-)
> 
> 
> Summary over all repositories:
>   7 files changed, 563 insertions(+), 45 deletions(-)
> 



_______________________________________________
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2025-09-25 12:22 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-09-25 10:05 [pve-devel] [PATCH proxmox{-ve-rs, -firewall} 0/4] Fix ipfilters in proxmox-firewall Stefan Hanreich
2025-09-25 10:05 ` [pve-devel] [PATCH proxmox-ve-rs 1/1] config: guest: store network devices in BTreeMap Stefan Hanreich
2025-09-25 10:05 ` [pve-devel] [PATCH proxmox-firewall 1/3] run rustfmt Stefan Hanreich
2025-09-25 10:05 ` [pve-devel] [PATCH proxmox-firewall 2/3] ipfilter: fix wrong entries for containers Stefan Hanreich
2025-09-25 10:05 ` [pve-devel] [PATCH proxmox-firewall 3/3] fix #6336: fix ipfilter matching logic Stefan Hanreich
2025-09-25 12:22 ` [pve-devel] superseded: [PATCH proxmox{-ve-rs, -firewall} 0/4] Fix ipfilters in proxmox-firewall Stefan Hanreich

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal