Skip to content

Commit 0f09745

Browse files
PR-ghg-bougard
authored andcommitted
Add Tagged VLAN, work at least with HPE Switch (#708)
1 parent fdf2620 commit 0f09745

File tree

3 files changed

+6279
-4011
lines changed

3 files changed

+6279
-4011
lines changed

lib/FusionInventory/Agent/Tools/Hardware.pm

Lines changed: 74 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1357,6 +1357,7 @@ sub _setVlans {
13571357

13581358
my $vlans = _getVlans(
13591359
snmp => $params{snmp},
1360+
ports => $params{ports}
13601361
);
13611362
return unless $vlans;
13621363

@@ -1379,6 +1380,7 @@ sub _getVlans {
13791380
my (%params) = @_;
13801381

13811382
my $snmp = $params{snmp};
1383+
my $ports = $params{ports};
13821384

13831385
my $results;
13841386
my $vtpVlanName = $snmp->walk('.1.3.6.1.4.1.9.9.46.1.3.1.1.4.1');
@@ -1401,35 +1403,82 @@ sub _getVlans {
14011403
}
14021404
}
14031405

1404-
# For other switches, we use another methods
1405-
# used for Alcatel-Lucent and ExtremNetworks (and perhaps others)
1406-
my $vlanIdName = $snmp->walk('.1.0.8802.1.1.2.1.5.32962.1.2.3.1.2');
1407-
my $portLink = $snmp->walk('.1.0.8802.1.1.2.1.3.7.1.3');
1408-
if($vlanIdName && $portLink){
1409-
foreach my $suffix (sort keys %{$vlanIdName}) {
1410-
my ($port, $vlan) = split(/\./, $suffix);
1411-
if ($portLink->{$port}) {
1412-
# case generic where $portLink = port number
1413-
my $portnumber = $portLink->{$port};
1414-
# case Cisco where $portLink = port name
1415-
unless ($portLink->{$port} =~ /^[0-9]+$/) {
1416-
$portnumber = $port;
1406+
# For Switch with dot1qVlanStaticEntry and dot1qVlanCurrent Present
1407+
my $dot1qVlanStaticName = $snmp->walk('.1.3.6.1.2.1.17.7.1.4.3.1.1');
1408+
my $dot1qVlanStaticRowStatus = $snmp->walk('.1.3.6.1.2.1.17.7.1.4.3.1.5');
1409+
# each result matches either of the following schemes :
1410+
# $prefix.$i = $value with $i as vlan_id, and each bit of $value represent the Egress (or Untagged) is present (1st bit = ifnumber 1, 2nd bit => ifnumber 2, etc...)
1411+
my $dot1qVlanCurrentEgressPorts = $snmp->walk('.1.3.6.1.2.1.17.7.1.4.2.1.4');
1412+
my $dot1qVlanCurrentUntaggedPorts = $snmp->walk('.1.3.6.1.2.1.17.7.1.4.2.1.5');
1413+
1414+
if ($dot1qVlanStaticRowStatus && $dot1qVlanStaticRowStatus && $dot1qVlanCurrentEgressPorts && $dot1qVlanCurrentUntaggedPorts) {
1415+
foreach my $vlan_id (sort keys %{$dot1qVlanStaticRowStatus}) {
1416+
if ($dot1qVlanStaticRowStatus->{$vlan_id} eq 1) {
1417+
my $name = $dot1qVlanStaticName->{$vlan_id};
1418+
1419+
my $suffix = defined($dot1qVlanCurrentEgressPorts->{$vlan_id}) ? $vlan_id : ("0.".$vlan_id);
1420+
next if !defined($dot1qVlanCurrentEgressPorts->{$suffix});
1421+
1422+
# Tagged & Untagged VLAN
1423+
my $bEgress = '';
1424+
if (isStringHexadecimal($dot1qVlanCurrentEgressPorts->{$suffix})) {
1425+
for (my $i=2; $i< length($dot1qVlanCurrentEgressPorts->{$suffix}); $i++) {
1426+
$bEgress .= sprintf('%04b', hex(substr($dot1qVlanCurrentEgressPorts->{$suffix}, $i, 1)));
1427+
}
1428+
}
1429+
1430+
# Untagged VLAN
1431+
my $bUntagged = '';
1432+
if (isStringHexadecimal($dot1qVlanCurrentUntaggedPorts->{$suffix})) {
1433+
for (my $i=2; $i< length($dot1qVlanCurrentUntaggedPorts->{$suffix}); $i++) {
1434+
$bUntagged .= sprintf('%04b', hex(substr($dot1qVlanCurrentUntaggedPorts->{$suffix}, $i, 1)));
1435+
}
1436+
}
1437+
1438+
next if ($bUntagged eq '' && $bEgress eq '');
1439+
1440+
foreach my $port_id (keys %{$ports}) {
1441+
my $isUntagged = ($port_id-1 <= length($bUntagged)) ? substr($bUntagged, $port_id-1, 1) : '0';
1442+
my $isTagged = ($isUntagged eq '0' && ($port_id-1 <= length($bEgress))) ? substr($bEgress, $port_id-1, 1) : '0';
1443+
push @{$results->{$port_id}}, {
1444+
NUMBER => $vlan_id,
1445+
NAME => $name,
1446+
TAGGED => $isTagged
1447+
} if $isTagged || $isUntagged;
14171448
}
1418-
push @{$results->{$portnumber}}, {
1419-
NUMBER => $vlan,
1420-
NAME => getCanonicalString($vlanIdName->{$suffix})
1421-
};
14221449
}
14231450
}
14241451
} else {
1425-
# A last method
1426-
my $vlanId = $snmp->walk('.1.0.8802.1.1.2.1.5.32962.1.2.1.1.1');
1427-
if($vlanId){
1428-
foreach my $port (sort keys %{$vlanId}) {
1429-
push @{$results->{$port}}, {
1430-
NUMBER => $vlanId->{$port},
1431-
NAME => "VLAN " . $vlanId->{$port}
1432-
};
1452+
# For other switches, we use another methods
1453+
# used for Alcatel-Lucent and ExtremNetworks (and perhaps others)
1454+
my $vlanIdName = $snmp->walk('.1.0.8802.1.1.2.1.5.32962.1.2.3.1.2');
1455+
my $portLink = $snmp->walk('.1.0.8802.1.1.2.1.3.7.1.3');
1456+
if ($vlanIdName && $portLink) {
1457+
foreach my $suffix (sort keys %{$vlanIdName}) {
1458+
my ($port, $vlan) = split(/\./, $suffix);
1459+
if ($portLink->{$port}) {
1460+
# case generic where $portLink = port number
1461+
my $portnumber = $portLink->{$port};
1462+
# case Cisco where $portLink = port name
1463+
unless ($portLink->{$port} =~ /^[0-9]+$/) {
1464+
$portnumber = $port;
1465+
}
1466+
push @{$results->{$portnumber}}, {
1467+
NUMBER => $vlan,
1468+
NAME => getCanonicalString($vlanIdName->{$suffix})
1469+
};
1470+
}
1471+
}
1472+
} else {
1473+
# A last method
1474+
my $vlanId = $snmp->walk('.1.0.8802.1.1.2.1.5.32962.1.2.1.1.1');
1475+
if ($vlanId) {
1476+
foreach my $port (sort keys %{$vlanId}) {
1477+
push @{$results->{$port}}, {
1478+
NUMBER => $vlanId->{$port},
1479+
NAME => "VLAN " . $vlanId->{$port}
1480+
};
1481+
}
14331482
}
14341483
}
14351484
}

lib/FusionInventory/Agent/Tools/SNMP.pm

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ our @EXPORT = qw(
1515
getCanonicalCount
1616
isInteger
1717
getRegexpOidMatch
18+
isStringHexadecimal
1819
);
1920

2021
sub getCanonicalSerialNumber {
@@ -144,6 +145,12 @@ sub getRegexpOidMatch {
144145
return qr/^$match/;
145146
}
146147

148+
sub isStringHexadecimal {
149+
my ($value) = @_;
150+
151+
return $value =~ /^0x[0-9a-fA-F]+$/;
152+
}
153+
147154
1;
148155
__END__
149156
@@ -180,3 +187,7 @@ return true if value is an integer.
180187
=head2 getRegexpOidMatch($oid)
181188
182189
return compiled regexp to match given oid.
190+
191+
=head2 isStringHexadecimal($value)
192+
193+
return true if value is a string hexadecimal (start with 0x).

0 commit comments

Comments
 (0)