This article shows how to obtain subscriber counts per physical interface by using the Utility MIB feature.
At times, a breakdown of Point-to-Point Protocol (PPP) and Dynamic Host Configuration Protocol (DHCP) subscriber counts on each AE or physical interface via Simple Network Management Protocol (SNMP) may be desired. However, the MX device does not provide subscriber count per physical interface value, broken down by client type, via SNMP.
Shown below is an example output of show subscribers summary port extensive
with DHCP and PPPoE users on AE.
user@mx480> show subscribers summary port extensive
Interface: ae2: xe-1
Port Count: 300
Detail:
Subscribers by Client Type
DHCP: 100
PPPoE: 200
Subscribers by Connection Type
Terminated: 300
Interface: ae2: xe-5
Port Count: 300
Detail:
Subscribers by Client Type
DHCP: 100
PPPoE: 200
Subscribers by Connection Type
Terminated: 300
Interface: xe-1/0/1
Port Count: 302
Detail:
Subscribers by Client Type
DHCP: 101
PPPoE: 201
Subscribers by Connection Type
Terminated: 302
Total Subscribers: 602
If an interface has only a single type of client, the output with the above show
command is:
user@mx480> show subscribers summary port extensive
Interface: ae2: xe-1
Port Count: 100
Detail:
Subscribers by Client Type
DHCP: 100
<<<<<no pppoe type here>>>>
Subscribers by Connection Type
Terminated: 100
With the Utility MIB feature, the output of show subscribers summary port extensive
can be reported via SNMP by performing the following steps:
-
Copy the following script to the /var/db/scripts/op
and /var/db/scripts/event
directories (both Routing Engines) with the setoid-sub-if.slax
file name:
/*
version 1.0
copy this slax file to /var/db/scripts/event (both RE)
check the result command is "show snmp mib walk ascii jnxUtil"
router#show event-options
event-options {
generate-event {
5-mins time-interval 300;
}
policy set-oids {
events 5-mins;
then {
event-script setoid-sub-if.slax;
}
}
}
*Debug Value:
*expr jcs:output( );
"Total:" _ $total-count;
*/
/* slax version, not script version */
version 1.1;
ns junos = "http://xml.juniper.net/junos/*/junos";
ns xnm = "http://xml.juniper.net/xnm/1.1/xnm";
ns jcs = "http://xml.juniper.net/junos/commit-scripts/1.0";
ns func extension = "http://exslt.org/functions";
ns jutils = "http://jutils/";
ns str = "http://exslt.org/strings";
ns set = "http://exslt.org/sets";
import "../import/junos.xsl";
var $connection = jcs:open();
template check_pid { <<<<<< The check pid
function
var $running_pid = jutils:running( $connection, $script );
if ( $running_pid ) {
"terminate script because another instance with pid " _ $running_pid _ " is still running";
}
}
function jutils:running( $connection, $script ) {
/* function to check if another instance of this script is still running
*
* :param connection: connection handle
* :param script: name used to identify the script
* :return: pid of running instance or false
*/
mvar $running = false();
var $pid = $junos-context/pid;
var $pid_filename = "/mfs/var/tmp/" _ $script _ ".pid";
var $pid_file = document( $pid_filename );
if ( not( jcs:empty( $pid_file//pid ) ) ) {
var $processes_rpc = { "show system processes extensive"; }
var $processes = jcs:execute( $connection, $processes_rpc );
var $processes_lines = jcs:break-lines( $processes );
for-each( $processes_lines ) {
if ( jcs:regex( "^[[:blank:][:space:]]*" _ $pid_file//pid _ "[[:blank:][:space:]]+.*cscript.*", . )[1] ) {
set $running = true();
}
}
}
if ( $running ) {
result $pid_file//pid;
} else {
{
copy-of $pid;
}
result false();
}
}
template snmp_set($instance, $value = "0", $type = "string" ) {
var $set_rpc = {
$type;
$value;
$instance;
}
var $out = jcs:invoke($set_rpc);
}
template clear-instance-regex() {
/* First walk the MIB and gather all instances */
var $walk-rpc = {
{
"jnxUtil";
;
}
}
var $mib-objects = jcs:invoke( $walk-rpc );
/* Clear all instances values */
for-each( $mib-objects/snmp-object ) {
/* Display the name */
var $type = ./object-value-type;
var $instance = substring-after( ./name , "." );
/* Only remove if it has a valid type */
if( string-length( $type ) == 12 ) {
/* Build RPC and invoke it */
var $rpc-clear = {
{
$instance;
substring-after( $type , "ASCII " );
}
}
var $results = jcs:invoke( $rpc-clear );
}
}
}
match / {
{
call check_pid;
call clear-instance-regex();
var $get_subscribers_port_summary_rpc = {
;
}
var $show-sub-sum-port-results = jcs:execute($connection, $get_subscribers_port_summary_rpc);
mvar $interface-name = 0;
mvar $total-sub-count = 0;
mvar $total-count = 0;
for-each($show-sub-sum-port-results/counters) {
if(position() = last()){
set $total-count = ./port-total;
call snmp_set($instance="Total" , $value="total-count:" _ $total-count , $type="string");
}
else if(position() mod 3 == 1 ){
set $interface-name = ./port-name;
set $total-sub-count = ./port-count;
if( starts-with( $interface-name , 'ae' ) ){
set $interface-name = substring-before($interface-name,":");
}
}
else if(position() mod 3 == 2 ){
mvar $session-type-dhcp = 0;
mvar $session-type-pppoe = 0;
if(./session-type-dhcp) {
set $session-type-dhcp = ./session-type-dhcp;
}
if(./session-type-pppoe) {
set $session-type-pppoe = ./session-type-pppoe;
}
call snmp_set($instance=$interface-name , $value="portname:" _ $interface-name _ " " _ "port-sub-count:" _ $total-sub-count _ " " _ "dhcp-count:" _ $session-type-dhcp _" " _ "pppoe-count:" _ $session-type-pppoe , $type="string");
}
}
}
}
-
Add the following configuration to execute the script every five minutes:
router#show event-options
event-options {
generate-event {
5-mins time-interval 300;
}
policy set-oids {
events 5-mins;
then {
event-script setoid-sub-if.slax;
}
}
}
-
Verify that the configuration is working:
user@mx480> show snmp mib walk ascii jnxUtil
jnxUtilStringValue."Total" = total-count:602
jnxUtilStringValue."ae2" = portname:ae2 port-sub-count:300 dhcp-count:100 pppoe-count:200
jnxUtilStringValue."xe-1/0/1" = portname:xe-1/0/1 port-sub-count:302 dhcp-count:101 pppoe-count:201
jnxUtilStringTime."Total" = 07 e2 08 14 06 34 0b 00 2b 05 00
jnxUtilStringTime."ae2" = 07 e2 08 14 06 34 0b 00 2b 05 00
jnxUtilStringTime."xe-1/0/1" = 07 e2 08 14 06 34 0b 00 2b 05 00
Note
-
If only a single client exists, the other client value (pppoe-count
in this case) will display as "0" after the script has been added.
-
The value of jnxUtilStringTime
is the Date and Time in yyyy mm dd hh mm ss
format:
(2018) 07 e2(08 20) 08 14 (06:52:11.00430500) 06 34 0b 00 2b 05 00
-
In some unknown situations, the above script may become stuck and may not exit properly. To address this problem, the check pid
function has been added to the script. If this script is running already, it cannot be executed again:
user@mx480> op setoid-sub-if | refresh 1
---(refreshed at 2018-08-20 06:55:20 IST)---
error: terminate script because another instance with pid 72850 is still running