Skip to content

Commit 5c84c03

Browse files
committed
Add support for multiple VLANs per ifIndex
sFlow and Netflow v9/v10 may provide VLAN information in flows, so one can distinguish between different logical links on the same physical connection (e.g. transit via private VLAN over IXP).
1 parent 3a44e24 commit 5c84c03

File tree

4 files changed

+40
-12
lines changed

4 files changed

+40
-12
lines changed

HISTORY.md

+7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
## post 1.5
2+
3+
* Added support for multiple links on one ifIndex, based on VLANs. Only
4+
sFlow, Netflow v9 and v10 (IPFIX) support this. Obviously your router
5+
needs to provide the information. Just add "/<vlan>" to the ifIndex in
6+
your knownlinks file.
7+
18
## 1.5
29

310
* Merged netflow-asstatd.pl and sflow-asstatd.pl into one script so

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ scripts.
3030
Prerequisites
3131
-------------
3232

33-
- Perl 5.8
33+
- Perl 5.10
3434
- RRDtool 1.2 (with Perl "RRDs" library)
3535
- if using sFlow: the Net::sFlow module (CPAN)
3636
- web server with PHP 5

bin/asstatd.pl

+30-10
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
# cli params/rrd storage/sampling mods Steve Colam <[email protected]>
77

88
use strict;
9+
use 5.010;
910
use IO::Select;
1011
use IO::Socket;
1112
use RRDs;
@@ -259,7 +260,7 @@ sub parse_netflow_v9_data_flowset {
259260
my $datalen = length($flowsetdata);
260261
while (($ofs + $len) <= $datalen) {
261262
# Interpret values according to template
262-
my ($inoctets, $outoctets, $srcas, $dstas, $snmpin, $snmpout, $ipversion);
263+
my ($inoctets, $outoctets, $srcas, $dstas, $snmpin, $snmpout, $ipversion, $vlanin, $vlanout);
263264

264265
$inoctets = 0;
265266
$outoctets = 0;
@@ -312,11 +313,15 @@ sub parse_netflow_v9_data_flowset {
312313
$ipversion = unpack("C", $cur_fldval);
313314
} elsif ($cur_fldtype == 27 || $cur_fldtype == 28) { # IPV6_SRC_ADDR/IPV6_DST_ADDR
314315
$ipversion = 6;
316+
} elsif ($cur_fldtype == 58) { # SRC_VLAN
317+
$vlanin = unpack("n", $cur_fldval);
318+
} elsif ($cur_fldtype == 59) { # SRC_VLAN
319+
$vlanout = unpack("n", $cur_fldval);
315320
}
316321
}
317322

318323
if (defined($srcas) && defined($dstas) && defined($snmpin) && defined($snmpout)) {
319-
handleflow($ipaddr, $inoctets + $outoctets, $srcas, $dstas, $snmpin, $snmpout, $ipversion, 'netflow');
324+
handleflow($ipaddr, $inoctets + $outoctets, $srcas, $dstas, $snmpin, $snmpout, $ipversion, 'netflow', $vlanin, $vlanout);
320325
}
321326
}
322327
}
@@ -400,7 +405,7 @@ sub parse_netflow_v10_data_flowset {
400405
my $datalen = length($flowsetdata);
401406
while (($ofs + $len) <= $datalen) {
402407
# Interpret values according to template
403-
my ($inoctets, $outoctets, $srcas, $dstas, $snmpin, $snmpout, $ipversion);
408+
my ($inoctets, $outoctets, $srcas, $dstas, $snmpin, $snmpout, $ipversion, $vlanin, $vlanout);
404409

405410
$inoctets = 0;
406411
$outoctets = 0;
@@ -453,11 +458,15 @@ sub parse_netflow_v10_data_flowset {
453458
$ipversion = unpack("C", $cur_fldval);
454459
} elsif ($cur_fldtype == 27 || $cur_fldtype == 28) { # IPV6_SRC_ADDR/IPV6_DST_ADDR
455460
$ipversion = 6;
461+
} elsif ($cur_fldtype == 58) { # SRC_VLAN
462+
$vlanin = unpack("n", $cur_fldval);
463+
} elsif ($cur_fldtype == 59) { # SRC_VLAN
464+
$vlanout = unpack("n", $cur_fldval);
456465
}
457466
}
458467

459468
if (defined($srcas) && defined($dstas) && defined($snmpin) && defined($snmpout)) {
460-
handleflow($ipaddr, $inoctets + $outoctets, $srcas, $dstas, $snmpin, $snmpout, $ipversion, 'netflow');
469+
handleflow($ipaddr, $inoctets + $outoctets, $srcas, $dstas, $snmpin, $snmpout, $ipversion, 'netflow', $vlanin, $vlanout);
461470
}
462471
}
463472
}
@@ -541,13 +550,22 @@ sub parse_sflow {
541550
if ($dstas == $myas) {
542551
$dstas = 0;
543552
}
553+
554+
# Extract VLAN information
555+
my ($vlanin, $vlanout);
556+
if ($sFlowSample->{'SwitchSrcVlan'}) {
557+
$vlanin = $sFlowSample->{'SwitchSrcVlan'};
558+
}
559+
if ($sFlowSample->{'SwitchDestVlan'}) {
560+
$vlanout = $sFlowSample->{'SwitchDestVlan'};
561+
}
544562

545-
handleflow($ipaddr, $noctets, $srcas, $dstas, $snmpin, $snmpout, $ipversion, 'sflow');
563+
handleflow($ipaddr, $noctets, $srcas, $dstas, $snmpin, $snmpout, $ipversion, 'sflow', $vlanin, $vlanout);
546564
}
547565
}
548566

549567
sub handleflow {
550-
my ($routerip, $noctets, $srcas, $dstas, $snmpin, $snmpout, $ipversion) = @_;
568+
my ($routerip, $noctets, $srcas, $dstas, $snmpin, $snmpout, $ipversion, $vlanin, $vlanout) = @_;
551569

552570
if ($srcas == 0 && $dstas == 0) {
553571
# don't care about internal traffic
@@ -564,14 +582,16 @@ sub handleflow {
564582
if ($srcas == 0) {
565583
$as = $dstas;
566584
$direction = "out";
567-
$ifalias = $knownlinks{inet_ntoa($routerip) . '_' . $snmpout};
585+
$ifalias = $knownlinks{inet_ntoa($routerip) . '_' . $snmpout . '/' . $vlanout};
586+
$ifalias //= $knownlinks{inet_ntoa($routerip) . '_' . $snmpout};
568587
} elsif ($dstas == 0) {
569588
$as = $srcas;
570589
$direction = "in";
571-
$ifalias = $knownlinks{inet_ntoa($routerip) . '_' . $snmpin};
590+
$ifalias = $knownlinks{inet_ntoa($routerip) . '_' . $snmpin . '/' . $vlanin};
591+
$ifalias //= $knownlinks{inet_ntoa($routerip) . '_' . $snmpin};
572592
} else {
573-
handleflow($routerip, $noctets, $srcas, 0, $snmpin, $snmpout, $ipversion);
574-
handleflow($routerip, $noctets, 0, $dstas, $snmpin, $snmpout, $ipversion);
593+
handleflow($routerip, $noctets, $srcas, 0, $snmpin, $snmpout, $ipversion, $vlanin, $vlanout);
594+
handleflow($routerip, $noctets, 0, $dstas, $snmpin, $snmpout, $ipversion, $vlanin, $vlanout);
575595
return;
576596
}
577597

conf/knownlinks

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Router IP SNMP ifindex tag description color samplingrate
1+
# Router IP SNMP ifindex[/VLAN] tag description color samplingrate
22
# note: tabs must be used to separate fields (not spaces)
33
# max. length for tag is 12 characters; allowed characters: a-z A-Z 0-9 _
44
192.0.2.1 15 uplink1 Uplink 1 A6CEE3 1
@@ -8,3 +8,4 @@
88
192.0.2.2 42 peering1 IXP 1 FB9A99 1
99
192.0.2.2 45 peering2 IXP 2 E31A1C 1
1010
192.0.2.3 6 peering3 IXP 3 FDBF6F 2048
11+
192.0.2.3 6/42 uplink5 Uplink 5 via VLAN 42 F86FFD 2048

0 commit comments

Comments
 (0)