[pve-devel] [PATCH proxmox-firewall 18/21] ipsets: autogenerate ipsets for vnets and ipam

Stefan Hanreich s.hanreich at proxmox.com
Wed Jun 26 14:15:47 CEST 2024


They act like virtual ipsets, similar to ipfilter-net, that can be
used for defining firewall rules for sdn objects dynamically.

The changes in proxmox-ve-config also introduced a dedicated struct
for representing ip ranges, so we update the existing code, so that it
uses that struct as well.

Signed-off-by: Stefan Hanreich <s.hanreich at proxmox.com>
---
 proxmox-firewall/src/firewall.rs              |   22 +-
 proxmox-firewall/src/object.rs                |   41 +-
 .../integration_tests__firewall.snap          | 1288 +++++++++++++++++
 proxmox-nftables/src/expression.rs            |   17 +-
 4 files changed, 1354 insertions(+), 14 deletions(-)

diff --git a/proxmox-firewall/src/firewall.rs b/proxmox-firewall/src/firewall.rs
index 4c85ea2..9c19580 100644
--- a/proxmox-firewall/src/firewall.rs
+++ b/proxmox-firewall/src/firewall.rs
@@ -197,6 +197,27 @@ impl Firewall {
         self.reset_firewall(&mut commands);
 
         let cluster_host_table = Self::cluster_table();
+        let guest_table = Self::guest_table();
+
+        if let Some(sdn_config) = self.config.sdn() {
+            let ipsets = sdn_config
+                .ipsets(None)
+                .map(|ipset| (ipset.name().to_string(), ipset))
+                .collect();
+
+            self.create_ipsets(&mut commands, &ipsets, &cluster_host_table, None)?;
+            self.create_ipsets(&mut commands, &ipsets, &guest_table, None)?;
+        }
+
+        if let Some(ipam_config) = self.config.ipam() {
+            let ipsets = ipam_config
+                .ipsets(None)
+                .map(|ipset| (ipset.name().to_string(), ipset))
+                .collect();
+
+            self.create_ipsets(&mut commands, &ipsets, &cluster_host_table, None)?;
+            self.create_ipsets(&mut commands, &ipsets, &guest_table, None)?;
+        }
 
         if self.config.host().is_enabled() {
             log::info!("creating cluster / host configuration");
@@ -242,7 +263,6 @@ impl Firewall {
             commands.push(Delete::table(TableName::from(Self::cluster_table())));
         }
 
-        let guest_table = Self::guest_table();
         let enabled_guests: BTreeMap<&Vmid, &GuestConfig> = self
             .config
             .guests()
diff --git a/proxmox-firewall/src/object.rs b/proxmox-firewall/src/object.rs
index 32c4ddb..cf7e773 100644
--- a/proxmox-firewall/src/object.rs
+++ b/proxmox-firewall/src/object.rs
@@ -72,20 +72,37 @@ impl ToNftObjects for Ipset {
             let mut nomatch_elements = Vec::new();
 
             for element in self.iter() {
-                let cidr = match &element.address {
-                    IpsetAddress::Cidr(cidr) => cidr,
-                    IpsetAddress::Alias(alias) => env
-                        .alias(alias)
-                        .ok_or(format_err!("could not find alias {alias} in environment"))?
-                        .address(),
+                let expression = match &element.address {
+                    IpsetAddress::Range(range) => {
+                        if family != range.family() {
+                            continue;
+                        }
+
+                        Expression::from(range)
+                    }
+                    IpsetAddress::Cidr(cidr) => {
+                        if family != cidr.family() {
+                            continue;
+                        }
+
+                        Expression::from(Prefix::from(cidr))
+                    }
+                    IpsetAddress::Alias(alias) => {
+                        let cidr = env
+                            .alias(alias)
+                            .ok_or_else(|| {
+                                format_err!("could not find alias {alias} in environment")
+                            })?
+                            .address();
+
+                        if family != cidr.family() {
+                            continue;
+                        }
+
+                        Expression::from(Prefix::from(cidr))
+                    }
                 };
 
-                if family != cidr.family() {
-                    continue;
-                }
-
-                let expression = Expression::from(Prefix::from(cidr));
-
                 if element.nomatch {
                     nomatch_elements.push(expression);
                 } else {
diff --git a/proxmox-firewall/tests/snapshots/integration_tests__firewall.snap b/proxmox-firewall/tests/snapshots/integration_tests__firewall.snap
index 669bad9..aa8ab64 100644
--- a/proxmox-firewall/tests/snapshots/integration_tests__firewall.snap
+++ b/proxmox-firewall/tests/snapshots/integration_tests__firewall.snap
@@ -202,6 +202,1294 @@ expression: "firewall.full_host_fw().expect(\"firewall can be generated\")"
         }
       }
     },
+    {
+      "add": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v4-dc/public-all",
+          "type": "ipv4_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v4-dc/public-all"
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v4-dc/public-all-nomatch",
+          "type": "ipv4_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v4-dc/public-all-nomatch"
+        }
+      }
+    },
+    {
+      "add": {
+        "element": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v4-dc/public-all",
+          "elem": [
+            {
+              "prefix": {
+                "addr": "10.101.0.0",
+                "len": 16
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v6-dc/public-all",
+          "type": "ipv6_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v6-dc/public-all"
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v6-dc/public-all-nomatch",
+          "type": "ipv6_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v6-dc/public-all-nomatch"
+        }
+      }
+    },
+    {
+      "add": {
+        "element": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v6-dc/public-all",
+          "elem": [
+            {
+              "prefix": {
+                "addr": "fd80::",
+                "len": 64
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v4-dc/public-dhcp",
+          "type": "ipv4_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v4-dc/public-dhcp"
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v4-dc/public-dhcp-nomatch",
+          "type": "ipv4_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v4-dc/public-dhcp-nomatch"
+        }
+      }
+    },
+    {
+      "add": {
+        "element": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v4-dc/public-dhcp",
+          "elem": [
+            {
+              "range": [
+                "10.101.99.100",
+                "10.101.99.200"
+              ]
+            }
+          ]
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v6-dc/public-dhcp",
+          "type": "ipv6_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v6-dc/public-dhcp"
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v6-dc/public-dhcp-nomatch",
+          "type": "ipv6_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v6-dc/public-dhcp-nomatch"
+        }
+      }
+    },
+    {
+      "add": {
+        "element": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v6-dc/public-dhcp",
+          "elem": [
+            {
+              "range": [
+                "fd80::1000",
+                "fd80::ffff"
+              ]
+            }
+          ]
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v4-dc/public-gateway",
+          "type": "ipv4_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v4-dc/public-gateway"
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v4-dc/public-gateway-nomatch",
+          "type": "ipv4_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v4-dc/public-gateway-nomatch"
+        }
+      }
+    },
+    {
+      "add": {
+        "element": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v4-dc/public-gateway",
+          "elem": [
+            {
+              "prefix": {
+                "addr": "10.101.1.1",
+                "len": 32
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v6-dc/public-gateway",
+          "type": "ipv6_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v6-dc/public-gateway"
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v6-dc/public-gateway-nomatch",
+          "type": "ipv6_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v6-dc/public-gateway-nomatch"
+        }
+      }
+    },
+    {
+      "add": {
+        "element": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v6-dc/public-gateway",
+          "elem": [
+            {
+              "prefix": {
+                "addr": "fd80::1",
+                "len": 128
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v4-dc/public-no-gateway",
+          "type": "ipv4_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v4-dc/public-no-gateway"
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v4-dc/public-no-gateway-nomatch",
+          "type": "ipv4_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v4-dc/public-no-gateway-nomatch"
+        }
+      }
+    },
+    {
+      "add": {
+        "element": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v4-dc/public-no-gateway",
+          "elem": [
+            {
+              "prefix": {
+                "addr": "10.101.0.0",
+                "len": 16
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "add": {
+        "element": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v4-dc/public-no-gateway-nomatch",
+          "elem": [
+            {
+              "prefix": {
+                "addr": "10.101.1.1",
+                "len": 32
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v6-dc/public-no-gateway",
+          "type": "ipv6_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v6-dc/public-no-gateway"
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v6-dc/public-no-gateway-nomatch",
+          "type": "ipv6_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v6-dc/public-no-gateway-nomatch"
+        }
+      }
+    },
+    {
+      "add": {
+        "element": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v6-dc/public-no-gateway",
+          "elem": [
+            {
+              "prefix": {
+                "addr": "fd80::",
+                "len": 64
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "add": {
+        "element": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v6-dc/public-no-gateway-nomatch",
+          "elem": [
+            {
+              "prefix": {
+                "addr": "fd80::1",
+                "len": 128
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v4-dc/public-all",
+          "type": "ipv4_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v4-dc/public-all"
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v4-dc/public-all-nomatch",
+          "type": "ipv4_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v4-dc/public-all-nomatch"
+        }
+      }
+    },
+    {
+      "add": {
+        "element": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v4-dc/public-all",
+          "elem": [
+            {
+              "prefix": {
+                "addr": "10.101.0.0",
+                "len": 16
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v6-dc/public-all",
+          "type": "ipv6_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v6-dc/public-all"
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v6-dc/public-all-nomatch",
+          "type": "ipv6_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v6-dc/public-all-nomatch"
+        }
+      }
+    },
+    {
+      "add": {
+        "element": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v6-dc/public-all",
+          "elem": [
+            {
+              "prefix": {
+                "addr": "fd80::",
+                "len": 64
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v4-dc/public-dhcp",
+          "type": "ipv4_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v4-dc/public-dhcp"
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v4-dc/public-dhcp-nomatch",
+          "type": "ipv4_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v4-dc/public-dhcp-nomatch"
+        }
+      }
+    },
+    {
+      "add": {
+        "element": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v4-dc/public-dhcp",
+          "elem": [
+            {
+              "range": [
+                "10.101.99.100",
+                "10.101.99.200"
+              ]
+            }
+          ]
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v6-dc/public-dhcp",
+          "type": "ipv6_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v6-dc/public-dhcp"
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v6-dc/public-dhcp-nomatch",
+          "type": "ipv6_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v6-dc/public-dhcp-nomatch"
+        }
+      }
+    },
+    {
+      "add": {
+        "element": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v6-dc/public-dhcp",
+          "elem": [
+            {
+              "range": [
+                "fd80::1000",
+                "fd80::ffff"
+              ]
+            }
+          ]
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v4-dc/public-gateway",
+          "type": "ipv4_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v4-dc/public-gateway"
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v4-dc/public-gateway-nomatch",
+          "type": "ipv4_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v4-dc/public-gateway-nomatch"
+        }
+      }
+    },
+    {
+      "add": {
+        "element": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v4-dc/public-gateway",
+          "elem": [
+            {
+              "prefix": {
+                "addr": "10.101.1.1",
+                "len": 32
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v6-dc/public-gateway",
+          "type": "ipv6_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v6-dc/public-gateway"
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v6-dc/public-gateway-nomatch",
+          "type": "ipv6_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v6-dc/public-gateway-nomatch"
+        }
+      }
+    },
+    {
+      "add": {
+        "element": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v6-dc/public-gateway",
+          "elem": [
+            {
+              "prefix": {
+                "addr": "fd80::1",
+                "len": 128
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v4-dc/public-no-gateway",
+          "type": "ipv4_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v4-dc/public-no-gateway"
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v4-dc/public-no-gateway-nomatch",
+          "type": "ipv4_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v4-dc/public-no-gateway-nomatch"
+        }
+      }
+    },
+    {
+      "add": {
+        "element": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v4-dc/public-no-gateway",
+          "elem": [
+            {
+              "prefix": {
+                "addr": "10.101.0.0",
+                "len": 16
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "add": {
+        "element": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v4-dc/public-no-gateway-nomatch",
+          "elem": [
+            {
+              "prefix": {
+                "addr": "10.101.1.1",
+                "len": 32
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v6-dc/public-no-gateway",
+          "type": "ipv6_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v6-dc/public-no-gateway"
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v6-dc/public-no-gateway-nomatch",
+          "type": "ipv6_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v6-dc/public-no-gateway-nomatch"
+        }
+      }
+    },
+    {
+      "add": {
+        "element": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v6-dc/public-no-gateway",
+          "elem": [
+            {
+              "prefix": {
+                "addr": "fd80::",
+                "len": 64
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "add": {
+        "element": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v6-dc/public-no-gateway-nomatch",
+          "elem": [
+            {
+              "prefix": {
+                "addr": "fd80::1",
+                "len": 128
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v4-dc/guest-ipam-101",
+          "type": "ipv4_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v4-dc/guest-ipam-101"
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v4-dc/guest-ipam-101-nomatch",
+          "type": "ipv4_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v4-dc/guest-ipam-101-nomatch"
+        }
+      }
+    },
+    {
+      "add": {
+        "element": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v4-dc/guest-ipam-101",
+          "elem": [
+            {
+              "prefix": {
+                "addr": "10.101.1.100",
+                "len": 32
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v6-dc/guest-ipam-101",
+          "type": "ipv6_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v6-dc/guest-ipam-101"
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v6-dc/guest-ipam-101-nomatch",
+          "type": "ipv6_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v6-dc/guest-ipam-101-nomatch"
+        }
+      }
+    },
+    {
+      "add": {
+        "element": {
+          "family": "inet",
+          "table": "proxmox-firewall",
+          "name": "v6-dc/guest-ipam-101",
+          "elem": [
+            {
+              "prefix": {
+                "addr": "fd80::1000",
+                "len": 128
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v4-dc/guest-ipam-101",
+          "type": "ipv4_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v4-dc/guest-ipam-101"
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v4-dc/guest-ipam-101-nomatch",
+          "type": "ipv4_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v4-dc/guest-ipam-101-nomatch"
+        }
+      }
+    },
+    {
+      "add": {
+        "element": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v4-dc/guest-ipam-101",
+          "elem": [
+            {
+              "prefix": {
+                "addr": "10.101.1.100",
+                "len": 32
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v6-dc/guest-ipam-101",
+          "type": "ipv6_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v6-dc/guest-ipam-101"
+        }
+      }
+    },
+    {
+      "add": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v6-dc/guest-ipam-101-nomatch",
+          "type": "ipv6_addr",
+          "flags": [
+            "interval"
+          ]
+        }
+      }
+    },
+    {
+      "flush": {
+        "set": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v6-dc/guest-ipam-101-nomatch"
+        }
+      }
+    },
+    {
+      "add": {
+        "element": {
+          "family": "bridge",
+          "table": "proxmox-firewall-guests",
+          "name": "v6-dc/guest-ipam-101",
+          "elem": [
+            {
+              "prefix": {
+                "addr": "fd80::1000",
+                "len": 128
+              }
+            }
+          ]
+        }
+      }
+    },
     {
       "add": {
         "set": {
diff --git a/proxmox-nftables/src/expression.rs b/proxmox-nftables/src/expression.rs
index 18b92d4..71a90eb 100644
--- a/proxmox-nftables/src/expression.rs
+++ b/proxmox-nftables/src/expression.rs
@@ -1,4 +1,5 @@
 use crate::types::{ElemConfig, Verdict};
+use proxmox_ve_config::firewall::types::address::IpRange;
 use serde::{Deserialize, Serialize};
 use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
 
@@ -50,6 +51,10 @@ pub enum Expression {
 }
 
 impl Expression {
+    pub fn range(start: impl Into<Expression>, end: impl Into<Expression>) -> Self {
+        Expression::Range(Box::new((start.into(), end.into())))
+    }
+
     pub fn set(expressions: impl IntoIterator<Item = Expression>) -> Self {
         Expression::Set(Vec::from_iter(expressions))
     }
@@ -169,12 +174,22 @@ impl From<&IpList> for Expression {
     }
 }
 
+#[cfg(feature = "config-ext")]
+impl From<&IpRange> for Expression {
+    fn from(value: &IpRange) -> Self {
+        match value {
+            IpRange::V4(range) => Expression::range(range.start(), range.end()),
+            IpRange::V6(range) => Expression::range(range.start(), range.end()),
+        }
+    }
+}
+
 #[cfg(feature = "config-ext")]
 impl From<&IpEntry> for Expression {
     fn from(value: &IpEntry) -> Self {
         match value {
             IpEntry::Cidr(cidr) => Expression::from(Prefix::from(cidr)),
-            IpEntry::Range(beg, end) => Expression::Range(Box::new((beg.into(), end.into()))),
+            IpEntry::Range(range) => Expression::from(range),
         }
     }
 }
-- 
2.39.2




More information about the pve-devel mailing list