public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
From: Hannes Laimer <h.laimer@proxmox.com>
To: pve-devel@lists.proxmox.com
Subject: [PATCH pve-container v4 43/45] lxc: update the microseg enforcement on a tag or hostname change
Date: Thu,  5 Nov 2026 12:13:22 +0100	[thread overview]
Message-ID: <20261105111324.706922-44-h.laimer@proxmox.com> (raw)
In-Reply-To: <20261105111324.706922-1-h.laimer@proxmox.com>

The groups of a container's NICs depend on its tags and hostname, but
a change of those took effect at the next start of the container or
the next network reload of the node. Update the NICs of a running
container once the new config is written, so the change applies right
away. The update reads the config under the same lock as a network
reload, so a reload running at the same time cannot leave the old
groups in place. A failed update only warns, and the next reload or
start catches up.

Moving a container between groups is an SDN change like putting a NIC
on a vnet, which needs SDN.Use on the vnet. So a tag or hostname
change that can move the container also needs SDN.Use on
/sdn/microseg, and so does creating, cloning or restoring a container
with such a tag or hostname.

A destroy with purge removes the container's own assignments from the
policy, as it removes the container from its backup and replication
jobs. Assignments by tag or hostname are not the container's and stay.

Signed-off-by: Hannes Laimer <h.laimer@proxmox.com>
---
 src/PVE/API2/LXC.pm        | 14 ++++++++++++++
 src/PVE/API2/LXC/Config.pm |  3 +++
 src/PVE/LXC.pm             | 28 ++++++++++++++++++++++++++++
 src/PVE/LXC/Create.pm      |  4 ++++
 4 files changed, 49 insertions(+)

diff --git a/src/PVE/API2/LXC.pm b/src/PVE/API2/LXC.pm
index 63d30d17dfaf..bca4c26c914d 100644
--- a/src/PVE/API2/LXC.pm
+++ b/src/PVE/API2/LXC.pm
@@ -334,6 +334,8 @@ __PACKAGE__->register_method({
         PVE::LXC::check_ct_modify_config_perm(
             $rpcenv, $authuser, $vmid, $pool, undef, $param, [], $unprivileged,
         );
+        PVE::Network::SDN::Microseg::check_name_access($rpcenv, $authuser, undef, "CT$vmid")
+            if !$restore && !defined($param->{hostname});
 
         my $storage_cfg = cfs_read_file("storage.cfg");
 
@@ -919,6 +921,12 @@ __PACKAGE__->register_method({
                 print "purging CT $vmid from related configurations..\n";
                 PVE::ReplicationConfig::remove_vmid_jobs($vmid);
                 PVE::VZDump::Plugin::remove_vmid_from_backup_jobs($vmid);
+                my $assignments =
+                    eval { PVE::Network::SDN::Microseg::remove_guest_assignments($vmid) };
+                warn "unable to remove the microseg assignments of CT $vmid: $@" if $@;
+                print
+                    "NOTE: removed the microseg assignments of CT $vmid, pending an SDN apply.\n"
+                    if $assignments;
 
                 if ($ha_managed) {
                     PVE::HA::Config::delete_service_from_config("ct:$vmid", $param->{purge});
@@ -2138,6 +2146,9 @@ __PACKAGE__->register_method({
                     $newconf->{$opt} = $value;
                 }
             }
+            PVE::Network::SDN::Microseg::check_tag_access(
+                $rpcenv, $authuser, undef, $newconf->{tags},
+            ) if defined($newconf->{tags});
             die "can't clone CT to node '$target' (CT uses local storage)\n"
                 if $target && !$sharedvm;
 
@@ -2151,6 +2162,9 @@ __PACKAGE__->register_method({
             delete $newconf->{template};
 
             $newconf->{hostname} = $param->{hostname} if $param->{hostname};
+            PVE::Network::SDN::Microseg::check_name_access(
+                $rpcenv, $authuser, undef, $newconf->{hostname},
+            ) if defined($newconf->{hostname});
             $newconf->{description} = $param->{description} if $param->{description};
 
             $lock_and_reload->(
diff --git a/src/PVE/API2/LXC/Config.pm b/src/PVE/API2/LXC/Config.pm
index 805eac0eac38..1ba8c5d865de 100644
--- a/src/PVE/API2/LXC/Config.pm
+++ b/src/PVE/API2/LXC/Config.pm
@@ -262,6 +262,9 @@ __PACKAGE__->register_method({
             $conf = PVE::LXC::Config->load_config($vmid);
 
             PVE::LXC::update_lxc_config($vmid, $conf);
+            # reads the tags and hostname from pmxcfs, so after the write
+            PVE::LXC::update_nets_enforcement($conf, $vmid)
+                if $running && grep { $_ eq 'tags' || $_ eq 'hostname' } (keys %$param, @delete);
             raise_param_exc($errors) if scalar(keys %$errors);
         };
 
diff --git a/src/PVE/LXC.pm b/src/PVE/LXC.pm
index 59d803d2592c..c8fa96ca81c6 100644
--- a/src/PVE/LXC.pm
+++ b/src/PVE/LXC.pm
@@ -25,6 +25,7 @@ use PVE::GuestHelpers qw(check_vnet_access safe_string_ne safe_num_ne safe_boole
 use PVE::INotify;
 use PVE::JSONSchema qw(get_standard_option);
 use PVE::Network;
+use PVE::Network::SDN::Microseg;
 use PVE::Network::SDN::Vnets;
 use PVE::Network::SDN::Zones;
 use PVE::ProcFSTools;
@@ -1097,6 +1098,21 @@ sub net_tap_plug : prototype($$) {
     PVE::Tools::run_command(['/sbin/ip', 'link', 'set', 'dev', $iface, 'up']);
 }
 
+# the groups of a NIC depend on the container's tags and hostname
+sub update_nets_enforcement {
+    my ($conf, $vmid) = @_;
+
+    for my $opt (keys %$conf) {
+        next if $opt !~ m/^net(\d+)$/;
+        my $iface = "veth${vmid}i$1";
+        next if !-d "/sys/class/net/$iface";
+        my $net = PVE::LXC::Config->parse_lxc_network($conf->{$opt});
+        next if ($net->{type} // '') ne 'veth';
+        my $firewall = $net->{firewall} && PVE::Firewall::Helpers::needs_fwbr($net->{bridge});
+        PVE::Network::SDN::Zones::tap_update($iface, $firewall);
+    }
+}
+
 sub update_net {
     my ($vmid, $conf, $opt, $newnet, $netid, $rootdir) = @_;
 
@@ -1656,6 +1672,12 @@ sub check_ct_modify_config_perm {
             raise_perm_exc("configuring device passthrough is only allowed for root\@pam");
         } elsif ($opt eq 'nameserver' || $opt eq 'searchdomain' || $opt eq 'hostname') {
             $rpcenv->check_vm_perm($authuser, $vmid, $pool, ['VM.Config.Network']);
+            PVE::Network::SDN::Microseg::check_name_access(
+                $rpcenv,
+                $authuser,
+                $oldconf->{$opt},
+                $delete ? undef : $newconf->{$opt},
+            ) if $opt eq 'hostname';
         } elsif ($opt eq 'features') {
             raise_perm_exc(
                 "changing feature flags for privileged container is only allowed for root\@pam")
@@ -1709,6 +1731,12 @@ sub check_ct_modify_config_perm {
             my $old = $oldconf->{$opt};
             my $new = $delete ? '' : $newconf->{$opt};
             PVE::GuestHelpers::assert_tag_permissions($vmid, $old, $new, $rpcenv, $authuser);
+            PVE::Network::SDN::Microseg::check_tag_access(
+                $rpcenv,
+                $authuser,
+                $old,
+                PVE::GuestHelpers::get_unique_tags($new),
+            );
         } else {
             $rpcenv->check_vm_perm($authuser, $vmid, $pool, ['VM.Config.Options']);
         }
diff --git a/src/PVE/LXC/Create.pm b/src/PVE/LXC/Create.pm
index 08b65cab7677..c4751b11b424 100644
--- a/src/PVE/LXC/Create.pm
+++ b/src/PVE/LXC/Create.pm
@@ -578,6 +578,10 @@ sub sanitize_and_merge_config {
         }
         $conf->{$key} = $oldconf->{$key} if !defined($conf->{$key});
     }
+    PVE::Network::SDN::Microseg::check_tag_access($rpcenv, $authuser, undef, $conf->{tags})
+        if defined($conf->{tags});
+    PVE::Network::SDN::Microseg::check_name_access($rpcenv, $authuser, undef, $conf->{hostname})
+        if defined($conf->{hostname});
 }
 
 sub restore_configuration_from_etc_vzdump {
-- 
2.47.3





  parent reply	other threads:[~2026-11-05 11:19 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-05 11:12 [PATCH access-control/cluster/container/docs/manager/network/proxmox{,-ve-rs,-perl-rs}/qemu-server v4 00/45] sdn: add microsegmentation support Hannes Laimer
2026-11-05 11:12 ` [PATCH proxmox v4 01/45] ebpf: build: keep the build directory out of the BPF objects Hannes Laimer
2026-11-05 11:12 ` [PATCH proxmox v4 02/45] ebpf: policy: add the enforcement subsystem for guest interfaces Hannes Laimer
2026-11-05 11:12 ` [PATCH proxmox v4 03/45] ebpf: policy: add a check for non-first fragments Hannes Laimer
2026-11-05 11:12 ` [PATCH proxmox-ve-rs v4 04/45] ve-config: firewall: add a constructor for sctp matches Hannes Laimer
2026-11-05 11:12 ` [PATCH proxmox-ve-rs v4 05/45] ve-config: sdn: microseg: add identity allocation for group sets Hannes Laimer
2026-11-05 11:12 ` [PATCH proxmox-ve-rs v4 06/45] ve-config: sdn: microseg: add config types Hannes Laimer
2026-11-05 11:12 ` [PATCH proxmox-ve-rs v4 07/45] ve-config: sdn: microseg: add tag matcher Hannes Laimer
2026-11-05 11:12 ` [PATCH proxmox-ve-rs v4 08/45] ve-config: sdn: microseg: add name regex matcher Hannes Laimer
2026-11-05 11:12 ` [PATCH proxmox-ve-rs v4 09/45] ve-config: sdn: microseg: narrow rules by protocol and ports Hannes Laimer
2026-11-05 11:12 ` [PATCH proxmox-ve-rs v4 10/45] ve-config: sdn: microseg: add group hierarchy Hannes Laimer
2026-11-05 11:12 ` [PATCH proxmox-ve-rs v4 11/45] ve-config: firewall: expose protocol, icmp type and code numbers Hannes Laimer
2026-11-05 11:12 ` [PATCH proxmox-ve-rs v4 12/45] ve-config: sdn: microseg: add the desired state Hannes Laimer
2026-11-05 11:12 ` [PATCH proxmox-ve-rs v4 13/45] microseg: add a crate that applies the policy to a node's guest NICs Hannes Laimer
2026-11-05 11:12 ` [PATCH proxmox-ve-rs v4 14/45] microseg: add a rule option that matches non-first fragments Hannes Laimer
2026-11-05 11:12 ` [PATCH pve-cluster v4 15/45] cfs: add 'sdn/microseg.cfg' to observed files Hannes Laimer
2026-11-05 11:12 ` [PATCH pve-access-control v4 16/45] permissions: add ACL path for SDN microsegmentation Hannes Laimer
2026-11-05 11:12 ` [PATCH proxmox-perl-rs v4 17/45] pve-rs: sdn: add microseg config binding Hannes Laimer
2026-11-05 11:12 ` [PATCH proxmox-perl-rs v4 18/45] pve-rs: sdn: microseg: bind the data plane Hannes Laimer
2026-11-05 11:12 ` [PATCH proxmox-perl-rs v4 19/45] pve-rs: sdn: microseg: check the data plane limits on render Hannes Laimer
2026-11-05 11:12 ` [PATCH proxmox-perl-rs v4 20/45] pve-rs: debian: fire the pve-microseg-update trigger on upgrade Hannes Laimer
2026-11-05 11:13 ` [PATCH pve-network v4 21/45] sdn: zones: add vxlan-gbp option to vxlan and evpn zones Hannes Laimer
2026-11-05 11:13 ` [PATCH pve-network v4 22/45] sdn: microseg: add config, API and guest inventory Hannes Laimer
2026-11-05 11:13 ` [PATCH pve-network v4 23/45] sdn: dry-run: show pending microseg changes Hannes Laimer
2026-11-05 11:13 ` [PATCH pve-network v4 24/45] sdn: microseg: enforce the policy on guest NICs Hannes Laimer
2026-11-05 11:13 ` [PATCH pve-network v4 25/45] sdn: microseg: add tag matcher Hannes Laimer
2026-11-05 11:13 ` [PATCH pve-network v4 26/45] sdn: microseg: add name regex matcher Hannes Laimer
2026-11-05 11:13 ` [PATCH pve-network v4 27/45] sdn: microseg: add an update for a running NIC Hannes Laimer
2026-11-05 11:13 ` [PATCH pve-network v4 28/45] sdn: microseg: expose protocol, port and macro rule options Hannes Laimer
2026-11-05 11:13 ` [PATCH pve-network v4 29/45] sdn: microseg: allow nesting groups under a parent Hannes Laimer
2026-11-05 11:13 ` [PATCH pve-network v4 30/45] sdn: microseg: expose the fragments rule option Hannes Laimer
2026-11-05 11:13 ` [PATCH pve-manager v4 31/45] network: apply the microseg policy on reload Hannes Laimer
2026-11-05 11:13 ` [PATCH pve-manager v4 32/45] pve-sdn-commit: apply the microseg policy at boot Hannes Laimer
2026-11-05 11:13 ` [PATCH pve-manager v4 33/45] ui: sdn: zones: add vxlan-gbp checkbox to vxlan and evpn Hannes Laimer
2026-11-05 11:13 ` [PATCH pve-manager v4 34/45] ui: sdn: add microsegmentation panel Hannes Laimer
2026-11-05 11:13 ` [PATCH pve-manager v4 35/45] ui: sdn: dry-run: show pending microseg diff Hannes Laimer
2026-11-05 11:13 ` [PATCH pve-manager v4 36/45] ui: sdn: microseg: add tag matcher Hannes Laimer
2026-11-05 11:13 ` [PATCH pve-manager v4 37/45] ui: sdn: microseg: add name regex matcher Hannes Laimer
2026-11-05 11:13 ` [PATCH pve-manager v4 38/45] ui: sdn: microseg: add narrowing to the rule form Hannes Laimer
2026-11-05 11:13 ` [PATCH pve-manager v4 39/45] ui: sdn: microseg: show and edit the group hierarchy Hannes Laimer
2026-11-05 11:13 ` [PATCH pve-manager v4 40/45] ui: sdn: microseg: add fragments option to the rule form Hannes Laimer
2026-11-05 11:13 ` [PATCH pve-manager v4 41/45] ui: sdn: microseg: add a guest tab with its groups and rules Hannes Laimer
2026-11-05 11:13 ` [PATCH qemu-server v4 42/45] network: update the microseg enforcement on a tag or name change Hannes Laimer
2026-11-05 11:13 ` Hannes Laimer [this message]
2026-11-05 11:13 ` [PATCH pve-docs v4 44/45] sdn: zones: document the VXLAN-GBP option Hannes Laimer
2026-11-05 11:13 ` [PATCH pve-docs v4 45/45] sdn: add microsegmentation section Hannes Laimer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261105111324.706922-44-h.laimer@proxmox.com \
    --to=h.laimer@proxmox.com \
    --cc=pve-devel@lists.proxmox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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