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.
show subscribers summary port extensive
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:
show
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:
/var/db/scripts/op
/var/db/scripts/event
setoid-sub-if.slax
/* 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"); } } } }
check pid
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.
pppoe-count
The value of jnxUtilStringTime is the Date and Time in yyyy mm dd hh mm ss format:
jnxUtilStringTime
yyyy mm dd hh mm ss
(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