diff options
author | zsdc <taras@vyos.io> | 2022-09-12 18:07:01 +0300 |
---|---|---|
committer | zsdc <taras@vyos.io> | 2022-09-19 20:16:12 +0300 |
commit | d55b9e14c14011577354b69cc569d2652d5e31fd (patch) | |
tree | 76c0e49c9149586f29630a457bf4854a26507d3e /scripts/firewall/vyatta-ipset.pl | |
parent | 6de742432786b4035842d3e3f2e4a10df68199f2 (diff) | |
download | vyatta-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-x | scripts/firewall/vyatta-ipset.pl | 35 |
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; |