NAME

SNMP::Info::Layer3::Juniper - SNMP Interface to L3 Juniper Devices

AUTHOR

Bill Fenner

SYNOPSIS

# Let SNMP::Info determine the correct subclass for you.
my $juniper = new SNMP::Info(
                         AutoSpecify => 1,
                         Debug       => 1,
                         DestHost    => 'myrouter',
                         Community   => 'public',
                         Version     => 2
                       )
   or die "Can't connect to DestHost.\n";

my $class      = $juniper->class();
print "SNMP::Info determined this device to fall under subclass : $class\n";

DESCRIPTION

Subclass for Juniper Devices running JUNOS

Inherited Classes

SNMP::Info::Layer3

Required MIBs

JUNIPER-VLAN-MIB dated "200901090000Z" or later.
JUNIPER-CHASSIS-DEFINES-MIB
JUNIPER-MIB
JUNIPER-VIRTUALCHASSIS-MIB
JUNIPER-L2ALD-MIB
JUNIPER-MIMSTP-MIB
SNMP-VIEW-BASED-ACM-MIB
JUNIPER-VPN-MIB
JUNIPER-IF-MIB

Inherited Classes' MIBs

See "Required MIBs" in SNMP::Info::Layer3 for its own MIB requirements.

GLOBALS

These are methods that return scalar value from SNMP

$juniper->vendor()

Returns 'juniper'

$juniper->os()

Returns 'junos'

$juniper->layers()

Checks forwarding table for Layer 2 support since some routers with switches do not report layers properly.

$juniper->os_ver()

Returns the software version extracted first from sysDescr or lldpLocSysDesc if not available in sysDescr.

$juniper->model()

Returns the model from sysObjectID, with jnxProductName removed from the beginning.

$juniper->serial()

Returns serial number

(jnxBoxSerialNo)

$juniper->mac()

Returns the MAC address used by this bridge when it must be referred to in a unique fashion.

(dot1dBaseBridgeAddress)

$juniper->box_descr()

The name, model, or detailed description of the device.

(jnxBoxDescr)

$juniper->version()

(jnxVirtualChassisMemberSWVersion)

$juniper->vc_model()

(jnxVirtualChassisMemberModel)

$juniper->jnx_stp_version()

(dot1dStpVersion)

$juniper->hasSTP()

Returns 1 when dot1dStpVersion is stpCompatible(0) and MSTP is not started, else 0. VSTP can run beside it.

$juniper->hasRSTP()

Returns 1 when dot1dStpVersion is rstp(2) and MSTP is not started, else 0. VSTP can run beside it.

$juniper->hasMSTP()

Returns 1 when jnxMIMstSystemControl for context 0 is start(1), else 0.

$juniper->hasVSTP()

Returns 1 when all of these hold, else 0:

  • jnxMIMstSystemControl does not start MSTP at context 0;

  • its walk completed, with rows at contexts other than 0 that all read shutdown(2);

  • jnxMIMstMstiBridgePriority has no row, and its walk completed.

See "Spanning Tree Trees".

Globals imported from SNMP::Info::Layer3

See documentation in "GLOBALS" in SNMP::Info::Layer3 for details.

TABLE METHODS

These are methods that return tables of information in the form of a reference to a hash.

$juniper->qb_fdb_index()

Returns reference to hash: key = FDB ID, value = VLAN ID.

$juniper->v_index()

Returns (jnxL2aldVlanTag) or (jnxExVlanTag) depending upon switch software version

$juniper->v_name()

Returns (jnxL2aldVlanName) or (jnxExVlanName) depending upon switch software version

$juniper->v_type()

Returns (jnxL2aldVlanType) or (jnxExVlanType) depending upon switch software version

$juniper->i_trunk()

(jnxExVlanPortAccessMode)

$juniper->i_vlan()

Returns a mapping between ifIndex and the PVID or default VLAN.

$juniper->i_vlan_membership()

Returns reference to hash of arrays: key = ifIndex, value = array of VLAN IDs. These are the VLANs which are members of the egress list for the port.

$juniper->i_vlan_membership_untagged()

Returns reference to hash of arrays: key = ifIndex, value = array of VLAN IDs. These are the VLANs which are members of the untagged egress list for the port.

$juniper->peth_port_ifindex()

Returns reference to a hash: key= PowerEthernet MIB interface number, value = ifIndex. As Juniper does not provide a mapping function, this does it manually. For example, ge-0/0/1 registers as PowerEthernet interface '1.2'

$juniper->i_edgeport_admin()

Returns 1 or 0 for each port by whether it is configured as an edge port. Format is a hash reference with key = ifIndex, value = [1|0]. Reads jnxMIMstCistPortAdminEdgeStatus, else dot1dStpPortAdminEdgePort through SNMP::Info::Bridge.

$juniper->i_edgeport_oper()

Returns 1 or 0 for each port by whether it currently operates as an edge port. Format is a hash reference with key = ifIndex, value = [1|0]. Reads jnxMIMstCistPortOperEdgeStatus, else dot1dStpPortOperEdgePort through SNMP::Info::Bridge.

$juniper->agg_ports()

Returns a HASH reference mapping from member to aggregate for each port bundle, from dot3adAggPortAttachedAggID. Junos reports logical units (ge-0/0/1.0, ae0.0) in that table; both sides are mapped to the physical interface beneath the unit (ge-0/0/1, ae0), as ifStackStatus shows. In lag_groups() the per-member partner fields can be undef, because Junos keys the port rows on logical units rather than on the physical member.

$juniper->jnx_vacm_context_name()

(vacmContextName)

$juniper->vrf_jnx_vpn_status()

Returns reference to hash of the row status of each VPN, keyed by jnxVpnType then the length-prefixed jnxVpnName. The index is what names the VPN, since both index leaves are not accessible. Type 2 is bgpIpVpn.

(jnxVpnRowStatus)

$juniper->jnx_mst_control()

(jnxMIMstSystemControl)

$juniper->jnx_mst_brg_address()

(jnxMIMstBrgAddress)

$juniper->jnx_mst_cist_root()

(jnxMIMstCistRoot)

$juniper->jnx_mst_cist_priority()

(jnxMIMstCistBridgePriority)

$juniper->jnx_msti_priority()

(jnxMIMstMstiBridgePriority)

$juniper->jnx_msti_root()

(jnxMIMstMstiBridgeRegionalRoot)

$juniper->jnx_msti_vlans_1k()

(jnxMIMstInstanceVlanMapped)

$juniper->jnx_msti_vlans_2k()

(jnxMIMstInstanceVlanMapped2k)

$juniper->jnx_msti_vlans_3k()

(jnxMIMstInstanceVlanMapped3k)

$juniper->jnx_msti_vlans_4k()

(jnxMIMstInstanceVlanMapped4k)

$juniper->jnx_cist_p_state()

(jnxMIMstCistPortState)

$juniper->jnx_cist_p_role()

(jnxMIMstCistCurrentPortRole)

$juniper->jnx_cist_p_bridge()

(jnxMIMstCistPortDesignatedBridge)

$juniper->jnx_cist_p_port()

(jnxMIMstCistPortDesignatedPort)

$juniper->jnx_cist_p_enable()

(jnxMIMstCistForcePortState)

$juniper->jnx_cist_p_edge_admin()

(jnxMIMstCistPortAdminEdgeStatus)

$juniper->jnx_cist_p_edge_oper()

(jnxMIMstCistPortOperEdgeStatus)

$juniper->jnx_msti_p_state()

(jnxMIMstMstiPortState)

$juniper->jnx_msti_p_role()

(jnxMIMstMstiCurrentPortRole)

$juniper->jnx_msti_p_bridge()

(jnxMIMstMstiPortDesignatedBridge)

$juniper->jnx_msti_p_port()

(jnxMIMstMstiPortDesignatedPort)

$juniper->jnx_msti_p_enable()

(jnxMIMstMstiForcePortState)

Spanning Tree Trees

These override "Spanning Tree Trees" in SNMP::Info::Bridge, where the records are described. Only the default context is read, except for VSTP trees.

The default context's protocol:

  • mstp when jnxMIMstSystemControl for context 0 is start(1).

  • Else rstp or stp, as dot1dStpVersion says (rstp(2), stpCompatible(0)).

  • Else unknown. Where BRIDGE-MIB serves the tree, cist.0 is reported with protocol undef, and stp_protocols() is ['dot1d'].

VSTP (vstp) runs alone or beside RSTP or STP. The device sets no flag for it; hasVSTP() lists the signs this class reads. The jnxMIMstSystemControl row at context 0 belongs to the default context, so shutdown(2) there, or a dot1dStpVersion, does not rule VSTP out. A row reading start(1) at another context is MSTP inside a routing instance, not VSTP. Junos refuses MSTP and VSTP in one routing instance, but VSTP in a virtual switch can run beside MSTP in the default instance; that VSTP tree is not listed.

The tree records:

Keys

cist.0 and msti.N under MSTP; cist.0 under RSTP and STP. Each VSTP tree is vlan.N in the default instance, and vlan.N@instance in routing instance instance; they are listed beside any cist.0. Under VSTP alone the default context serves no dot1dStp object, so there is no cist.0. A vlan.N@default key is not a tree.

vlan, instance

On VSTP trees only: the VLAN id, and the routing instance, default included.

protocol

The default context's protocol, as above; vstp on VSTP trees.

measured

1 under STP, RSTP, MSTP and VSTP. 0 when the protocol is unknown.

ports_complete

0 when a port row of the tree has no bp_index() entry, under MSTP, RSTP and STP. 1 otherwise, and on every VSTP tree.

contexts

The default context, except on a VSTP tree. A VSTP tree has one context:

{ kind => 'vlan', id => N, instance => 'instance',
  v2c => 'instance::N@%s', v3 => 'instance::N' }

Its instance key makes it differ from snmp_context('vlan', N), which answers for the default instance only; use the tree's own context.

bridge

Under MSTP, from jnxMIMstCistBridgePriority or jnxMIMstMstiBridgePriority as served, with jnxMIMstBrgAddress. Under RSTP and STP, from BRIDGE-MIB. Undef on VSTP trees.

root

Under MSTP, jnxMIMstCistRoot or jnxMIMstMstiBridgeRegionalRoot. Under RSTP and STP, dot1dStpDesignatedRoot. Undef on VSTP trees, since only the tree's own context serves it.

The port records:

Under MSTP

state, role, designated_bridge and designated_port from the JUNIPER-MIMSTP-MIB CIST or MSTI port table, role normalized by munge_dot1s_port_role(). enabled is the tree's jnxMIMstCistForcePortState or jnxMIMstMstiForcePortState: 0 for disabled(0), 1 for enabled(1), undef for a port with no row.

Under RSTP, STP and VSTP

From BRIDGE-MIB, in the tree's own context for a VSTP tree. role and role_raw are undef.

Each VSTP tree is served whole, as BRIDGE-MIB, in its own context instance::N. The tree list takes the VLANs and instances from the instance::N names in vacmContextName, with N from 1 to 4094. Other VLAN contexts get no reply at all, not an error, so ask only the listed ones. To reach a context:

  • SNMPv2c: the community instance::N@community, the instance first. community@N, the Cisco order, does not work on Junos.

  • SNMPv3: the context instance::N.

Device requirements for VSTP:

  • The community's or user's view includes SNMP-VIEW-BASED-ACM-MIB (1.3.6.1.6.3.16). Without it the VSTP VLAN list is unknown: stp_trees() holds no VSTP tree and stp_trees_complete() is 0.

  • For SNMPv3, an exact VACM context-prefix instance::N for each VLAN.

$juniper->stp_protocols()

Returns reference to an array holding the default context's protocol, then vstp when VSTP runs (['rstp', 'vstp'] beside RSTP, ['vstp'] alone), ['dot1d'] when only BRIDGE-MIB is served, or nothing. Protocol methods answer only in the default context: stp_protocols() reports an error in any other, and hasSTP() to hasVSTP() return 0.

$juniper->stp_trees()

Returns reference to hash of tree records, or an empty hash when nothing is served.

$juniper->stp_tree_ports($tree_key)

Returns reference to hash of the tree's port records keyed by ifIndex.

  • A vlan.N key is read in the context default::N, and a vlan.N@instance key in instance::N. In any other context it returns nothing, with error() naming the context to use.

  • Other keys are read only in the default context.

A listed instance::N name can have no tree behind it (see stp_trees_complete()); in such a context it returns no rows.

$juniper->stp_trees_complete()

Returns 1 or 0, as "Spanning Tree Trees" in SNMP::Info::Bridge describes. It returns 0 when:

  • no protocol is identified, including when only BRIDGE-MIB is served;

  • the jnxMIMstSystemControl walk was incomplete;

  • VSTP runs, and vacmContextName was not served or its walk was incomplete;

  • unless MSTP runs, the number of instance::N names in vacmContextName differs from the number of jnxMIMstSystemControl rows at contexts other than 0;

  • under MSTP, vacmContextName lists any instance::N name: VSTP in another routing instance, whose tree is not listed;

  • no tree is listed.

The count catches a VACM context-prefix that lists a name with no VSTP behind it, and a tree whose name the agent's view hides. When one of each occurs, they cancel out and neither is detected. Every control row at a context other than 0 counts, whatever it reads, so MSTP started inside a routing instance beside RSTP or STP in the default context also gives 0.

$juniper->stp_vlan_map()

Under MSTP returns reference to hash mapping VLAN id to msti.N, from the four jnxMIMstInstanceVlanMapped bitmaps (VLANs 1 to 4094). Only VLANs mapped to an MSTI appear: the device serves no row for the CIST. Otherwise nothing.

Routing instances

vrf_instances() lists:

  • each instance MPLS-L3VPN-STD-MIB serves, as kind vrf, with its route distinguisher and route targets;

  • each other name vacmContextName (SNMP-VIEW-BASED-ACM-MIB) serves, with SNMP-VIEW-BASED-ACM-MIB as its list source. It is kind vrf when jnxVpnTable (JUNIPER-VPN-MIB) lists the name as bgpIpVpn, and virtual-router otherwise. The management instance mgmt_junos is a virtual-router like any other, and reads in its own context.

These names are never listed:

  • the empty name, default and default-switch;

  • a name between double underscores, such as __juniper_private2__;

  • a name starting with a colon, such as :gribi;

  • an instance::N VSTP context;

  • a name jnxVpnTable lists with a type other than bgpIpVpn, such as a VPLS instance.

A layer 2 instance with no jnxVpnTable row, such as a virtual-switch, is listed as a virtual-router. It reads no address in its context, since the device holds none there.

The default instance is always the default record. Its list source is MPLS-L3VPN-STD-MIB when that serves a row, and otherwise SNMP-VIEW-BASED-ACM-MIB when vacmContextName serves a row. A device that lists no other instance there reports vrf_instances_complete() 1, none configured (see "Completeness" in SNMP::Info::VRF). vrf_instances_complete() is 0 when the vacmContextName or jnxVpnRowStatus walk was incomplete.

Each instance reads in its own context (context mode). The default context leaks: it also serves every instance's neighbors and addresses on the instances' ports.

  • The readers of default drop the rows on the ports mplsL3VpnIfConfTable gives a VRF. i_vrf() in the default context is that membership.

  • An instance listed only by vacmContextName, such as a virtual router or the management instance, is never covered by the membership table, even where mplsL3VpnIfConfTable names it. Its rows stay in default, except on ports that table names, and vrf_read_complete('default') is 0 while it is listed. Every device with mgmt_junos therefore reads 0 there.

  • To separate a virtual router's rows, read it in its own context first. Then drop from default's rows those on the ports i_vrf() reported in that router's context. vrf_read_complete('default') stays 0, since the class cannot check the result.

  • An internal instance that no list source names, such as __juniper_private1__ on the internal links, keeps its rows in default whatever is listed.

Neighbors:

  • Junos serves host link-local neighbors only in ipv6NetToMediaTable (IPV6-MIB). vrf_neighbors() adds them to the ipNetToPhysicalTable rows, once per port and address.

  • Junos serves an instance's own addresses as neighbors too: at an all-zero or empty MAC, or at the port's MAC, static in IPv4 and local in IPv6. vrf_neighbors() drops them all.

  • Junos holds fe80::1 on every port of an instance, but lists it in ipAddressTable on one only. Its rows on the other ports are dropped by the port's MAC.

$juniper->context_kinds($feature)

['vlan'] for stp while VSTP runs, since each VSTP tree is served in its own VLAN context; ['vrf'] for vrf, since each routing instance is served in its own context; nothing otherwise, and nothing for other features. See context_kinds() in SNMP::Info.

$juniper->snmp_context($kind, $id)

For vlan returns { kind => 'vlan', id => N, v2c => 'default::N@%s', v3 => 'default::N' }, the context of VLAN N in the default instance, with the context before the community. For vrf and an instance name returns { kind => 'vrf', id => $name, v2c => '$name@%s', v3 => $name }, with the instance before the community (red@community, never community@red); a Junos SNMPv3 context name is the instance name. The default instance, an empty name and no name get nothing, since the default context serves the default instance. Kinds other than vlan and vrf get nothing. See snmp_context() in SNMP::Info.

Pseudo ENTITY-MIB information

These methods emulate ENTITY-MIB Physical Table methods using JUNIPER-MIB and JUNIPER-VIRTUALCHASSIS-MIB.

$juniper->e_index()

Returns reference to hash. Key: IID, Value: Integer, Indices are combined into a eight digit integer, each index is two digits padded with leading zero if required.

$juniper->e_class()

Returns reference to hash. Key: IID, Value: General hardware type. A virtual chassis is a stack with one chassis per member.

$juniper->e_descr()

Returns reference to hash. Key: IID, Value: Human friendly name

$juniper->e_hwver()

Returns reference to hash. Key: IID, Value: Hardware version

$juniper->e_vendor()

Returns reference to hash. Key: IID, Value: juniper

$juniper->e_serial()

Returns reference to hash. Key: IID, Value: Serial number. In a virtual chassis each member frame reports its own serial (jnxVirtualChassisMemberSerialnumber).

$juniper->e_model()

Returns reference to hash. Key: IID, Value: Model name. In a virtual chassis each member frame reports its own model (jnxVirtualChassisMemberModel); other entries are from ENTITY-MIB (entPhysicalModelName).

$juniper->e_pos()

Returns reference to hash. Key: IID, Value: The relative position among all entities sharing the same parent.

$juniper->e_type()

Returns reference to hash. Key: IID, Value: Type of component/sub-component as defined in JUNIPER-CHASSIS-DEFINES-MIB.

$juniper->e_parent()

Returns reference to hash. Key: IID, Value: The value of e_index() for the entity which 'contains' this entity. A value of zero indicates this entity is not contained in any other entity.

$entity->e_fru()

BOOLEAN. Is a Field Replaceable unit?

(entPhysicalFRU)

Table Methods imported from SNMP::Info::Layer3

See documentation in "TABLE METHODS" in SNMP::Info::Layer3 for details.