summaryrefslogtreecommitdiff
path: root/scripts/firewall/vyatta-ipset.pl
diff options
context:
space:
mode:
authorzsdc <taras@vyos.io>2022-09-12 18:07:01 +0300
committerzsdc <taras@vyos.io>2022-09-19 20:16:12 +0300
commitd55b9e14c14011577354b69cc569d2652d5e31fd (patch)
tree76c0e49c9149586f29630a457bf4854a26507d3e /scripts/firewall/vyatta-ipset.pl
parent6de742432786b4035842d3e3f2e4a10df68199f2 (diff)
downloadvyatta-cfg-firewall-d55b9e14c14011577354b69cc569d2652d5e31fd.tar.gz
vyatta-cfg-firewall-d55b9e14c14011577354b69cc569d2652d5e31fd.zip
ipset: T2189: optimized firewall groups performance
This commit optimizes the speed of interaction with the ipset. * removed extra `sudo` from `ipset` commands, because scripts that run `ipset` commands already run under `sudo`. This gives approximately 4x performance improvement. * replaced logic in the `member_exists` function for port groups. Instead of calling `ipset -T` for each port now the whole list is received in one command and a search process is done inside Perl. This significantly improves speed for port groups with long port ranges inside. * delete ip address and port ranges using a single command instead deleting each element individually. * added the same ranges validation for address-group as for port-group.
Diffstat (limited to 'scripts/firewall/vyatta-ipset.pl')
-rwxr-xr-xscripts/firewall/vyatta-ipset.pl35
1 files changed, 32 insertions, 3 deletions
diff --git a/scripts/firewall/vyatta-ipset.pl b/scripts/firewall/vyatta-ipset.pl
index a5375dc..43322f3 100755
--- a/scripts/firewall/vyatta-ipset.pl
+++ b/scripts/firewall/vyatta-ipset.pl
@@ -33,6 +33,7 @@ use Vyatta::Misc;
use Vyatta::IpTables::IpSet;
use Sort::Versions;
use IO::Prompt;
+use NetAddr::IP;
use warnings;
use strict;
@@ -403,23 +404,51 @@ sub check_duplicates {
# check if this is a port range
if ($item =~ /([\d]+)-([\d]+)/) {
foreach my $port ($1..$2) {
- return "Port $port exist in more than one item\n" if (exists $portlist{$port});
+ return "Port $port exists in more than one configuration enrty\n" if (exists $portlist{$port});
$portlist{$port} = undef;
}
# check if this is an alphabetic port name
} elsif ($item =~ /^\D+/) {
my $port = getservbyname($item, "");
- return "Port $port exist in more than one item\n" if (exists $portlist{$port});
+ return "Port $port exists in more than one configuration enrty\n" if (exists $portlist{$port});
$portlist{$port} = undef;
# process simple numeric ports
} else {
- return "Port $item exist in more than one item\n" if (exists $portlist{$item});
+ return "Port $item exists in more than one configuration enrty\n" if (exists $portlist{$item});
$portlist{$item} = undef;
}
}
}
+ # check duplicates in address-group
+ if ($set_type eq "address") {
+ # define hash with addresses as keys
+ my %addresslist;
+
+ for my $item (@vals) {
+ # check if this is an address range
+ if ($item =~ /(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})-(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/) {
+ my $first_ip = new NetAddr::IP("$1/0");
+ my $last_ip = new NetAddr::IP("$2/0");
+
+ for (; $first_ip <= $last_ip; $first_ip++) {
+ my $current_addr = $first_ip->addr();
+ # check if an address already listed
+ if (exists $addresslist{$current_addr}) {
+ return "Address $current_addr exists in more than one configuration enrty\n";
+ }
+ # add an address to a list
+ $addresslist{$current_addr} = undef;
+ }
+ # process single addresses
+ } else {
+ return "Address $item exists in more than one configuration enrty\n" if (exists $addresslist{$item});
+ # add an address to a list
+ $addresslist{$item} = undef;
+ }
+ }
+ }
# do not return anything if there are no duplicates
return;