[pve-devel] [PATCH pve-firewall v2 21/25] add support for loading sdn firewall configuration
Wolfgang Bumiller
w.bumiller at proxmox.com
Thu Nov 7 11:44:18 CET 2024
On Thu, Oct 10, 2024 at 05:56:33PM GMT, Stefan Hanreich wrote:
> This also includes support for parsing rules referencing IPSets in the
> new SDN scope and generating those IPSets in the firewall.
>
> Loading SDN configuration is optional, since loading it requires root
> privileges which we do not have in all call sites. Adding the flag
> allows us to selectively load the SDN configuration only where
> required and at the same time allows us to only elevate privileges in
> the API where absolutely needed.
>
> Signed-off-by: Stefan Hanreich <s.hanreich at proxmox.com>
> ---
> src/PVE/Firewall.pm | 59 +++++++++++++++++++++++++++++++++++++++------
> 1 file changed, 52 insertions(+), 7 deletions(-)
>
> diff --git a/src/PVE/Firewall.pm b/src/PVE/Firewall.pm
> index 09544ba..9943f2e 100644
> --- a/src/PVE/Firewall.pm
> +++ b/src/PVE/Firewall.pm
> @@ -25,6 +25,7 @@ use PVE::Tools qw($IPV4RE $IPV6RE);
> use PVE::Tools qw(run_command lock_file dir_glob_foreach);
>
> use PVE::Firewall::Helpers;
> +use PVE::RS::Firewall::SDN;
>
> my $pvefw_conf_dir = "/etc/pve/firewall";
> my $clusterfw_conf_filename = "$pvefw_conf_dir/cluster.fw";
> @@ -1689,9 +1690,11 @@ sub verify_rule {
>
> if (my $value = $rule->{$name}) {
> if ($value =~ m/^\+/) {
> - if ($value =~ m@^\+(guest/|dc/)?(${ipset_name_pattern})$@) {
> + if ($value =~ m@^\+(guest/|dc/|sdn/)?(${ipset_name_pattern})$@) {
> &$add_error($name, "no such ipset '$2'")
> - if !($cluster_conf->{ipset}->{$2} || ($fw_conf && $fw_conf->{ipset}->{$2}));
> + if !($cluster_conf->{ipset}->{$2}
> + || ($fw_conf && $fw_conf->{ipset}->{$2})
> + || ($cluster_conf->{sdn} && $cluster_conf->{sdn}->{ipset}->{$2}));
>
> } else {
> &$add_error($name, "invalid ipset name '$value'");
> @@ -2108,13 +2111,15 @@ sub ipt_gen_src_or_dst_match {
>
> my $match;
> if ($adr =~ m/^\+/) {
> - if ($adr =~ m@^\+(guest/|dc/)?(${ipset_name_pattern})$@) {
> + if ($adr =~ m@^\+(guest/|dc/|sdn/)?(${ipset_name_pattern})$@) {
> my $scope = $1 // "";
> my $name = $2;
> my $ipset_chain;
The hunk below looks fishy.
> - if ($scope ne 'dc/' && $fw_conf && $fw_conf->{ipset}->{$name}) {
Previously $scope was dc or guest (or nothing).
This was the "guest" case, and guests took precedence, hence `ne 'dc/'`
> + if ((!$scope || $scope eq 'guest/') && $fw_conf && $fw_conf->{ipset}->{$name}) {
^ So this seems fine:
"(not set or set to guest) and a guest entry exists"
> $ipset_chain = compute_ipset_chain_name($fw_conf->{vmid}, $name, $ipversion);
> - } elsif ($scope ne 'guest/' && $cluster_conf && $cluster_conf->{ipset}->{$name}) {
^ Then we had "not guest", so:
"not set or set to datacenter and a cluster entry exists"
> + } elsif ((!$scope || $scope eq 'guest/') && $cluster_conf && $cluster_conf->{ipset}->{$name}) {
^ But here we have a 2nd instance of `eq 'guest/'`, so:
"not set or set to guest and a cluster entry exists"
Should probably be `(!$scope && $scope eq 'dc/')`, no?
> + $ipset_chain = compute_ipset_chain_name(0, $name, $ipversion);
> + } elsif ((!$scope || $scope eq 'sdn/') && $cluster_conf->{sdn} && $cluster_conf->{sdn}->{ipset}->{$name}) {
^ Finally the new case for "not set or scope is sdn and sdn entry
exists" which means that now we can also "fall through" to an sdn entry
if no scope is set (which makes sense I guess).
> $ipset_chain = compute_ipset_chain_name(0, $name, $ipversion);
> } else {
> die "no such ipset '$name'\n";
More information about the pve-devel
mailing list