enh(cisco/asa): ipsec-tunnel mode - optimize snmp requests (#3206)

This commit is contained in:
qgarnier 2021-10-20 14:13:15 +02:00 committed by GitHub
parent c8dbfee69f
commit a62d7097d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 97 additions and 44 deletions

View File

@ -232,10 +232,11 @@ sub new {
}
my $mapping = {
cikeTunLocalValue => { oid => '.1.3.6.1.4.1.9.9.171.1.2.3.1.3' },
cikeTunRemoteValue => { oid => '.1.3.6.1.4.1.9.9.171.1.2.3.1.7' },
cikeTunActiveTime => { oid => '.1.3.6.1.4.1.9.9.171.1.2.3.1.16' },
cikeTunLocalValue => { oid => '.1.3.6.1.4.1.9.9.171.1.2.3.1.3' },
cikeTunRemoteValue => { oid => '.1.3.6.1.4.1.9.9.171.1.2.3.1.7' }
};
my $oid_cikeTunActiveTime = '.1.3.6.1.4.1.9.9.171.1.2.3.1.16';
my $mapping2 = {
cipSecTunInOctets => { oid => '.1.3.6.1.4.1.9.9.171.1.3.2.1.26' },
cipSecTunHcInOctets => { oid => '.1.3.6.1.4.1.9.9.171.1.3.2.1.27' },
@ -247,37 +248,41 @@ my $mapping2 = {
cipSecTunOutDropPkts => { oid => '.1.3.6.1.4.1.9.9.171.1.3.2.1.46' }
};
my $mapping3 = {
cipSecEndPtLocalAddr1 => { oid => '.1.3.6.1.4.1.9.9.171.1.3.3.1.4' },
cipSecEndPtLocalAddr2 => { oid => '.1.3.6.1.4.1.9.9.171.1.3.3.1.5' },
cipSecEndPtRemoteAddr1 => { oid => '.1.3.6.1.4.1.9.9.171.1.3.3.1.10' },
cipSecEndPtRemoteAddr2 => { oid => '.1.3.6.1.4.1.9.9.171.1.3.3.1.11' }
};
my $oid_cikeTunnelEntry = '.1.3.6.1.4.1.9.9.171.1.2.3.1';
my $oid_cipSecTunnelEntry = '.1.3.6.1.4.1.9.9.171.1.3.2.1';
my $oid_cipSecEndPtEntry = '.1.3.6.1.4.1.9.9.171.1.3.3.1';
my $oid_cipSecEndPtLocalAddr1 = '.1.3.6.1.4.1.9.9.171.1.3.3.1.4';
my $oid_cipSecTunIkeTunnelIndex = '.1.3.6.1.4.1.9.9.171.1.3.2.1.2';
sub manage_selection {
my ($self, %options) = @_;
$self->{tunnel} = {};
my $request_oids = [
{ oid => $oid_cikeTunnelEntry, start => $mapping->{cikeTunLocalValue}->{oid}, end => $mapping->{cikeTunActiveTime}->{oid} },
{ oid => $oid_cipSecTunnelEntry, start => $mapping2->{cipSecTunInOctets}->{oid}, end => $mapping2->{cipSecTunOutDropPkts}->{oid} },
{ oid => $oid_cipSecEndPtEntry, start => $mapping3->{cipSecEndPtLocalAddr1}->{oid}, end => $mapping3->{cipSecEndPtRemoteAddr2}->{oid} },
{ oid => $oid_cipSecTunIkeTunnelIndex }
];
my $results = $options{snmp}->get_multiple_table(oids => $request_oids);
$self->{cache_name} = 'cisco_ipsectunnel_' . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' .
(defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')) . '_' .
(defined($self->{option_results}->{filter_sa}) ? md5_hex($self->{option_results}->{filter_sa}) : md5_hex('all')) . '_' .
(defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all'));
$self->{global} = { total => 0 };
my $snmp_result = $options{snmp}->get_multiple_table(
oids => [
{ oid => $mapping->{cikeTunLocalValue}->{oid} },
{ oid => $mapping->{cikeTunRemoteValue}->{oid} }
],
return_type => 1
);
# The MIB doesn't give IPSec tunnel type (site-to-site or dynamic client)
# You surely need to filter on SA. Dynamic client usually doesn't push local routes.
foreach (keys %{$results->{$oid_cikeTunnelEntry}}) {
$self->{tunnel} = {};
my $ike_idx = {};
foreach (keys %$snmp_result) {
next if (!/$mapping->{cikeTunRemoteValue}->{oid}\.(\d+)/);
my $cike_tun_index = $1;
my $result = $options{snmp}->map_instance(mapping => $mapping, results => $results->{$oid_cikeTunnelEntry}, instance => $cike_tun_index);
my $result = $options{snmp}->map_instance(mapping => $mapping, results => $snmp_result, instance => $cike_tun_index);
my $name = $result->{cikeTunLocalValue} . '_' . $result->{cikeTunRemoteValue};
if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' &&
$name !~ /$self->{option_results}->{filter_name}/) {
@ -285,19 +290,70 @@ sub manage_selection {
next;
}
foreach my $key (keys %{$results->{$oid_cipSecTunIkeTunnelIndex}}) {
next if ($results->{$oid_cipSecTunIkeTunnelIndex}->{$key} != $cike_tun_index);
$key =~ /^$oid_cipSecTunIkeTunnelIndex\.(\d+)/;
my $cip_tun_index = $1;
$ike_idx->{$cike_tun_index} = 1;
$self->{tunnel}->{$name} = { display => $name, sa => 0, ike_tun_idx => $cike_tun_index };
}
$snmp_result = $options{snmp}->get_multiple_table(
oids => [
{ oid => $oid_cipSecTunIkeTunnelIndex },
{ oid => $oid_cipSecEndPtLocalAddr1 }
]
);
my $sectun_idx_instances = {};
my $sectun_idx_select = {};
foreach (keys %{$snmp_result->{$oid_cipSecTunIkeTunnelIndex}}) {
next if (!defined($ike_idx->{ $snmp_result->{$oid_cipSecTunIkeTunnelIndex}->{$_} }));
/^$oid_cipSecTunIkeTunnelIndex\.(\d+)/;
if (!defined($sectun_idx_instances->{ $snmp_result->{$oid_cipSecTunIkeTunnelIndex}->{$_} })) {
$sectun_idx_instances->{ $snmp_result->{$oid_cipSecTunIkeTunnelIndex}->{$_} } = [];
}
$sectun_idx_select->{$1} = 1;
push @{$sectun_idx_instances->{ $snmp_result->{$oid_cipSecTunIkeTunnelIndex}->{$_} }}, $1;
}
foreach my $name (keys %{$self->{tunnel}}) {
delete $self->{tunnel}->{$name} if (!defined($sectun_idx_instances->{ $self->{tunnel}->{$name}->{ike_tun_idx} }));
}
return if (scalar(keys %{$self->{tunnel}}) <= 0);
my $sec_endpoint_idx_select = {};
my $sec_endpoint_idx_instances = [];
foreach (keys %{$snmp_result->{$oid_cipSecEndPtLocalAddr1}}) {
/(\d+)\.(\d+)$/;
next if (!defined($sectun_idx_select->{$1}));
push @$sec_endpoint_idx_instances, $1 . '.' . $2;
$sec_endpoint_idx_select->{$1} = [] if (!defined($sec_endpoint_idx_select->{$1}));
$sec_endpoint_idx_select->{$1} = [$2, $snmp_result->{$oid_cipSecEndPtLocalAddr1}->{$_}];
}
$options{snmp}->load(
oids => [ map($_->{oid}, values(%$mapping2)) ],
instances => [ map(@$_, values(%$sectun_idx_instances)) ],
instance_regexp => '^(.*)$'
);
$options{snmp}->load(
oids => [$oid_cikeTunActiveTime],
instances => [ map($_->{ike_tun_idx}, values(%{$self->{tunnel}})) ],
instance_regexp => '^(.*)$'
);
$options{snmp}->load(
oids => [ map($_->{oid}, values(%$mapping3)) ],
instances => $sec_endpoint_idx_instances,
instance_regexp => '^(.*)$'
);
$snmp_result = $options{snmp}->get_leef();
foreach my $name (keys %{$self->{tunnel}}) {
foreach my $cip_sec_tun_idx (@{$sectun_idx_instances->{ $self->{tunnel}->{$name}->{ike_tun_idx} }}) {
my $result = $options{snmp}->map_instance(mapping => $mapping2, results => $snmp_result, instance => $cip_sec_tun_idx);
my $result2 = $options{snmp}->map_instance(mapping => $mapping2, results => $results->{$oid_cipSecTunnelEntry}, instance => $cip_tun_index);
my $sa_name = '';
foreach my $key2 (keys %{$results->{$oid_cipSecEndPtEntry}}) {
if ($key2 =~ /^$mapping3->{cipSecEndPtLocalAddr1}->{oid}\.$cip_tun_index\.(\d+)/) {
my $result3 = $options{snmp}->map_instance(mapping => $mapping3, results => $results->{$oid_cipSecEndPtEntry}, instance => $cip_tun_index . '.' . $1);
$sa_name = inet_ntoa($result3->{cipSecEndPtLocalAddr1}) . ':' . inet_ntoa($result3->{cipSecEndPtLocalAddr2}) . '_' . inet_ntoa($result3->{cipSecEndPtRemoteAddr1}) . ':' . inet_ntoa($result3->{cipSecEndPtRemoteAddr2});
last;
}
if (defined($sec_endpoint_idx_select->{$cip_sec_tun_idx})) {
my $result3 = $options{snmp}->map_instance(mapping => $mapping3, results => $snmp_result, instance => $cip_sec_tun_idx . '.' . $sec_endpoint_idx_select->{$cip_sec_tun_idx}->[0]);
$sa_name = inet_ntoa($sec_endpoint_idx_select->{$cip_sec_tun_idx}->[1]) . ':' . inet_ntoa($result3->{cipSecEndPtLocalAddr2}) . '_' . inet_ntoa($result3->{cipSecEndPtRemoteAddr1}) . ':' . inet_ntoa($result3->{cipSecEndPtRemoteAddr2});
}
if (defined($self->{option_results}->{filter_sa}) && $self->{option_results}->{filter_sa} ne '' &&
@ -306,26 +362,23 @@ sub manage_selection {
next;
}
$self->{tunnel}->{$name} = { display => $name, sa => 0 }
if (!defined($self->{tunnel}->{$name}));
if (defined($result2->{cipSecTunHcInOctets}) && defined($result2->{cipSecTunHcOutOctets})) {
delete $result2->{cipSecTunInOctets};
delete $result2->{cipSecTunInOctWraps};
delete $result2->{cipSecTunOutOctets};
delete $result2->{cipSecTunOutOctWraps};
if (defined($result->{cipSecTunHcInOctets}) && defined($result->{cipSecTunHcOutOctets})) {
delete $result->{cipSecTunInOctets};
delete $result->{cipSecTunInOctWraps};
delete $result->{cipSecTunOutOctets};
delete $result->{cipSecTunOutOctWraps};
}
foreach my $oid_name (keys %{$mapping2}) {
$self->{tunnel}->{$name}->{$oid_name . '_' . $cip_tun_index} = $result2->{$oid_name} if (defined($result2->{$oid_name}));
foreach my $oid_name (keys %$mapping2) {
$self->{tunnel}->{$name}->{ $oid_name . '_' . $cip_sec_tun_idx } = $result->{$oid_name} if (defined($result->{$oid_name}));
}
$self->{tunnel}->{$name}->{cikeTunActiveTime} = $result->{cikeTunActiveTime};
$self->{tunnel}->{$name}->{cikeTunActiveTime} = $snmp_result->{ $oid_cikeTunActiveTime . '.' . $self->{tunnel}->{$name}->{ike_tun_idx} };
$self->{tunnel}->{$name}->{sa}++;
}
}
$self->{cache_name} = 'cisco_ipsectunnel_' . $options{snmp}->get_hostname() . '_' . $options{snmp}->get_port() . '_' . $self->{mode} . '_' .
(defined($self->{option_results}->{filter_name}) ? md5_hex($self->{option_results}->{filter_name}) : md5_hex('all')) . '_' .
(defined($self->{option_results}->{filter_sa}) ? md5_hex($self->{option_results}->{filter_sa}) : md5_hex('all')) . '_' .
(defined($self->{option_results}->{filter_counters}) ? md5_hex($self->{option_results}->{filter_counters}) : md5_hex('all'));
foreach my $name (keys %{$self->{tunnel}}) {
delete $self->{tunnel}->{$name} if ($self->{tunnel}->{$name}->{sa} == 0);
}
$self->{global} = { total => scalar(keys %{$self->{tunnel}}) };
}