From d5fa307db1c745f24dcc578df469a0be29d399da Mon Sep 17 00:00:00 2001 From: Stefan Schantl Date: Fri, 14 Apr 2023 18:00:35 +0200 Subject: [PATCH] ipblocklist-functions.pl: Add load_blocklist function. This function uses the ipset-functions library and the perl ipset bindings to load or update a given blocklist into the kernel. Signed-off-by: Stefan Schantl --- config/cfgroot/ipblocklist-functions.pl | 67 +++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/config/cfgroot/ipblocklist-functions.pl b/config/cfgroot/ipblocklist-functions.pl index ad0f482d1..7fd3a1187 100644 --- a/config/cfgroot/ipblocklist-functions.pl +++ b/config/cfgroot/ipblocklist-functions.pl @@ -24,6 +24,7 @@ package IPblocklist; use strict; require '/var/ipfire/general-functions.pl'; +require '/var/ipfire/ipset-functions.pl'; require "${General::swroot}/ipblocklist/sources"; # The directory where all ipblocklist related files and settings are stored. @@ -276,6 +277,72 @@ sub load_blocklists () { return @errors; } +# +## Load blocklist function. +## +## This function is responsible to load/update a given blocklist. +## +## It uses the ipset-functions library and ipset perl bindings to directly +## interact with ipset and load the list into the kernel. +# +sub load_blocklist($@) { + my ($name, @data) = @_; + + # Check if the given set exists. + my $exists = &IPSet::Functions::ipset_exists($name); + + # Call functions from ipset-functions library to detect and calculate + # the type and hashsize and omit the maxelems. + my $setname = $name; + my $type = &IPSet::Functions::detect_hashtype(@data); + my $maxelem = @data; + my $hashsize = &IPSet::Functions::calculate_hashsize($maxelem); + + # Get a a random set name. + my $rand_name = &IPSet::Functions::random_setname(); + + # If the given set allready exists, assign the random generated name. + $setname = $rand_name if($exists); + + # Create a new empty set. + my $error = &IPSet::Functions::ipset_create($setname, $type, $hashsize, $maxelem); + + # Abort and return the error if there was one. + return $error if(($error) && ($error ne "1")); + + # Add the data to the recently created set. + &IPSet::Functions::add_to_set($setname, @data); + + # We are finished here and can return, if the set has not exist yet. + return unless($exists); + + # Get the data of the existing set. + my $set_data = &IPSet::Functions::ipset_set_data($name); + + # Return if the data of the set could not be grabbed. + return "No data" unless($set_data); + + # Check if the old and the new types are eqal. + if ($set_data->{type} eq $type) { + # The type is the same and we easily can swap the sets. + &IPSet::Functions::ipset_swap($setname, $name); + + + # Remove the old one. + &IPSet::Functions::ipset_remove($setname); + } else { + # + # Abort if the set is currently in use. + return "Set in use" if($set_data->{references} gt 0); + + # Drop the old set first. + &IPSet::Functions::ipset_remove($name); + + # Rename the set + &IPSet::Functions::ipset_rename($setname, $name); + } +} + # ## sub parse_ip_or_net_list( line ) ## -- 2.39.5