[libsnmp-info-perl] 01/07: Imported Upstream version 3.28

gregor herrmann gregoa at debian.org
Sat Jul 11 20:35:09 UTC 2015


This is an automated email from the git hooks/post-receive script.

gregoa pushed a commit to branch master
in repository libsnmp-info-perl.

commit f9ba27903c70233229b8a328a1da797dd6a7f9b4
Author: gregor herrmann <gregoa at debian.org>
Date:   Sat Jul 11 22:22:35 2015 +0200

    Imported Upstream version 3.28
---
 ChangeLog                                 | 169 +++++++++---
 Info.pm                                   |  51 +++-
 Info/AMAP.pm                              |   2 +-
 Info/AdslLine.pm                          |   2 +-
 Info/Aggregate.pm                         |   2 +-
 Info/Airespace.pm                         |   2 +-
 Info/Bridge.pm                            | 134 +++++++++-
 Info/CDP.pm                               |   2 +-
 Info/CiscoAgg.pm                          |   2 +-
 Info/CiscoConfig.pm                       |   2 +-
 Info/CiscoPortSecurity.pm                 |   2 +-
 Info/CiscoPower.pm                        |   2 +-
 Info/CiscoQOS.pm                          |   2 +-
 Info/CiscoRTT.pm                          |   2 +-
 Info/CiscoStack.pm                        |   2 +-
 Info/CiscoStats.pm                        |   2 +-
 Info/CiscoStpExtensions.pm                |   2 +-
 Info/CiscoVTP.pm                          |  56 +++-
 Info/EDP.pm                               |   2 +-
 Info/Entity.pm                            |   2 +-
 Info/EtherLike.pm                         |   2 +-
 Info/FDP.pm                               |   2 +-
 Info/IEEE802dot11.pm                      |   2 +-
 Info/IEEE802dot3ad.pm                     |   2 +-
 Info/IPv6.pm                              |   2 +-
 Info/LLDP.pm                              |   4 +-
 Info/Layer1.pm                            |   2 +-
 Info/Layer1/Allied.pm                     |   2 +-
 Info/Layer1/Asante.pm                     |  10 +-
 Info/Layer1/Bayhub.pm                     |   2 +-
 Info/Layer1/Cyclades.pm                   |   2 +-
 Info/Layer1/S3000.pm                      |   2 +-
 Info/Layer2.pm                            |  42 ++-
 Info/Layer2/3Com.pm                       |   5 +-
 Info/Layer2/Airespace.pm                  |   2 +-
 Info/Layer2/Aironet.pm                    |  29 +-
 Info/Layer2/Allied.pm                     |   2 +-
 Info/Layer2/Baystack.pm                   |  90 ++++++-
 Info/Layer2/C1900.pm                      |   7 +-
 Info/Layer2/C2900.pm                      |   2 +-
 Info/Layer2/Catalyst.pm                   |   2 +-
 Info/Layer2/Centillion.pm                 |   2 +-
 Info/Layer2/Cisco.pm                      |   2 +-
 Info/Layer2/CiscoSB.pm                    |   2 +-
 Info/Layer2/HP.pm                         |  77 ++----
 Info/Layer2/HP4000.pm                     |  22 +-
 Info/Layer2/HPVC.pm                       |   2 +-
 Info/Layer2/Kentrox.pm                    |   2 +-
 Info/Layer2/N2270.pm                      |   2 +-
 Info/Layer2/NAP222x.pm                    |   2 +-
 Info/Layer2/NWSS2300.pm                   |   2 +-
 Info/Layer2/Netgear.pm                    |   2 +-
 Info/Layer2/Orinoco.pm                    |   2 +-
 Info/Layer2/Trapeze.pm                    |   2 +-
 Info/Layer2/Ubiquiti.pm                   |   2 +-
 Info/Layer2/ZyXEL_DSLAM.pm                |   2 +-
 Info/Layer3.pm                            |  51 ++--
 Info/Layer3/Aironet.pm                    |   2 +-
 Info/Layer3/AlcatelLucent.pm              |   2 +-
 Info/Layer3/AlteonAD.pm                   |  22 +-
 Info/Layer3/Altiga.pm                     |   2 +-
 Info/Layer3/Arista.pm                     |   2 +-
 Info/Layer3/Aruba.pm                      |  74 +++++-
 Info/Layer3/BayRS.pm                      |   8 +-
 Info/Layer3/BlueCoatSG.pm                 |   2 +-
 Info/Layer3/C3550.pm                      |   2 +-
 Info/Layer3/C4000.pm                      |   2 +-
 Info/Layer3/C6500.pm                      |   2 +-
 Info/Layer3/Cisco.pm                      |  14 +-
 Info/Layer3/CiscoASA.pm                   |   2 +-
 Info/Layer3/CiscoFWSM.pm                  |   2 +-
 Info/Layer3/CiscoSwitch.pm                |   2 +-
 Info/Layer3/Contivity.pm                  |   2 +-
 Info/Layer3/Dell.pm                       |  72 ++++-
 Info/Layer3/Enterasys.pm                  |  52 +++-
 Info/Layer3/Extreme.pm                    | 271 ++++++++++++++++++-
 Info/Layer3/F5.pm                         |  39 ++-
 Info/Layer3/Force10.pm                    |  35 +--
 Info/Layer3/{Steelhead.pm => Fortinet.pm} |  92 +++----
 Info/Layer3/Foundry.pm                    |  71 +++--
 Info/Layer3/H3C.pm                        |   2 +-
 Info/Layer3/HP9300.pm                     |   2 +-
 Info/Layer3/{H3C.pm => Huawei.pm}         |  88 +++---
 Info/Layer3/IBMGbTor.pm                   |   2 +-
 Info/Layer3/Juniper.pm                    |  49 ++--
 Info/Layer3/Lantronix.pm                  |   2 +-
 Info/Layer3/Microsoft.pm                  |   2 +-
 Info/Layer3/Mikrotik.pm                   |   2 +-
 Info/Layer3/N1600.pm                      |   2 +-
 Info/Layer3/NetSNMP.pm                    |   2 +-
 Info/Layer3/Netscreen.pm                  |   2 +-
 Info/Layer3/Nexus.pm                      |   2 +-
 Info/Layer3/PacketFront.pm                |   2 +-
 Info/Layer3/Passport.pm                   |   5 +-
 Info/Layer3/Pf.pm                         |   2 +-
 Info/Layer3/Pica8.pm                      |   2 +-
 Info/Layer3/SonicWALL.pm                  |   2 +-
 Info/Layer3/Steelhead.pm                  |   2 +-
 Info/Layer3/Sun.pm                        |   2 +-
 Info/Layer3/Tasman.pm                     |   2 +-
 Info/Layer3/Timetra.pm                    |   2 +-
 Info/Layer7.pm                            |  25 +-
 Info/Layer7/APC.pm                        |   2 +-
 Info/Layer7/Neoteris.pm                   |   2 +-
 Info/Layer7/Netscaler.pm                  |   2 +-
 Info/MAU.pm                               |   2 +-
 Info/MRO.pm                               |  11 +-
 Info/NortelStack.pm                       |   2 +-
 Info/PowerEthernet.pm                     |   2 +-
 Info/RapidCity.pm                         | 427 +++++++++++++++++++++++++++++-
 Info/SONMP.pm                             |   2 +-
 MANIFEST                                  |   2 +
 META.json                                 |  14 +-
 META.yml                                  |  16 +-
 README                                    |  21 +-
 115 files changed, 1815 insertions(+), 500 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index d852edb..c3ab1a7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,105 @@
 SNMP::Info - Friendly OO-style interface to Network devices using SNMP.
 
+version 3.28 (2015-06-18)
+
+  [ENHANCEMENTS]
+
+  * Add Layer3::Huawei class for Huawei Quidway switches
+  * Modified generic Layer3::Cisco class: use community based indexing if
+    the device returns a value for vtpVersion
+
+  [BUG FIXES]
+
+  * Correct port indexing of VSP 4K in L3::Passport
+
+version 3.27 (2015-05-05)
+
+  [ENHANCEMENTS]
+
+  * Cisco Aironet PSU information
+  * Only log adding mibdirs at debug level 2
+
+  [BUG FIXES]
+
+  * [#221] Drop Cisco Voice VLAN 4096
+
+version 3.26 (2015-03-07)
+
+  [ENHANCEMENTS]
+
+  * Add fan and psu reporting to Layer3::Dell
+  * Include Voice VLANs in (tagged) VLAN Membership on Cisco devices
+
+  [BUG FIXES]
+
+  * Fix typo in MRO::print_superclasses
+
+version 3.25 (2015-02-25)
+
+  [ENHANCEMENTS]
+
+    * Add new model name mappings for to Layer2::HP
+
+version 3.24 (2015-02-04)
+
+   [ENHANCEMENTS]
+
+    * Support RSTP and ieee8021d STP operating modes in RapidCity
+
+   [BUG FIXES]
+
+    * Fix single instance leafs defined in %FUNCS to behave like table leafs
+    * Fix incorrect FDB ID to VLAN ID mapping in Bridge and L3:Enterasys
+
+version 3.23 (2014-12-09)
+
+   [ENHANCEMENTS]
+
+    * Update MIB used in L1::Asante
+    * Enhanced STP support for L3::Extreme
+
+   [BUG FIXES]
+
+    * Fix Cisco VLAN membership issue introduced in 3.22 related to capturing
+      port VLANs on Cisco interfaces which are configured for trunking but
+      are not in operational trunking mode
+
+version 3.22 (2014-12-02)
+
+   [NEW FEATURES]
+
+    * Support obtaining FDB in Avaya SPBM edge deployments in L2::Baystack
+      NOTE: This requires a RAPID-CITY MIB with the rcBridgeSpbmMacTable
+    * Support for Fortinet devices in new class L3::Fortinet
+
+   [ENHANCEMENTS]
+
+    * Include LLDP support in base Layer2 and Layer3 classes. Due to the
+      widespread adoption of LLDP, this should improve mapping networks
+      when devices aren't supported in a more specific class.
+    * No longer ignore interfaces based on name, in base L2/L3/L7 device
+      classes. For several device classes SNMP::Info will now return tunnel
+      interfaces and/or loopbacks, if present.
+    * Use dot1qVlanCurrentTable if available to capture dynamic and static
+      VLANs, fall back to dot1qVlanStaticTable if not available.
+    * New method i_vlan_membership_untagged() for VLANs transmitted as
+      untagged frames.
+    * Capture Aruba AP hardware and software version when available
+    * New STP methods to support gathering information from devices running
+      mutiple STP instances such as PVST and MST
+    * Enhanced STP support for Avaya and Foundry classes
+
+   [BUG FIXES]
+
+    * [#64] Misdetection: Wireless APs, add products MIB to L2::3Com
+    * Use FDB ID to VID mapping if available to determine end station VLAN
+      rather than assuming they are the same.
+    * Capture port VLANs on Cisco interfaces which are configured for
+      trunking but are not in operational trunking mode
+    * Correct munging of stp_p_port(), i_stp_port(), and stp_root() methods
+      in Bridge
+    * In LLDP.pm don't create a variable in a conditional
+
 version 3.20 (2014-09-08)
 
    [NEW FEATURES]
@@ -63,7 +163,7 @@ version 3.16 (2014-06-23)
    [BUG FIXES]
 
     * Use CiscoVTP methods to get interface VLAN in L3::Cisco rather than
-      solely relying on the interface description. 
+      solely relying on the interface description.
 
 version 3.15 (2014-07-10)
 
@@ -215,7 +315,7 @@ version 3.08 (2013-10-22)
     * [#68] Fix device_port entries for switches with non-unique
       ifDesc (Nic Bernstein)
     * Don't try to munge undef values
-    * [#49] Perl 5.18 UNIVERSAL::can change could cause infinite loop 
+    * [#49] Perl 5.18 UNIVERSAL::can change could cause infinite loop
     * Silence warning from uninitialized variable in L3::Passport e_descr()
 
 version 3.07 (2013-10-01)
@@ -242,12 +342,11 @@ version 3.05 (2013-08-16)
       Layer2/CiscoSB class
     * Add proper LLDP support to Netgear.pm
     * Change $netgear->interfaces() to use ifName rather than ifDescr
-      as the former is unique per interface while the latter is not.  
+      as the former is unique per interface while the latter is not.
       If ifName is not present, concatenate ifDescr and ifIndex
       to achieve a unique value.
     * Properly report hardware version, Serial No. and OS Version for
       Netgear.
-    
 
 version 3.03 (2013-07-11)
 
@@ -277,7 +376,7 @@ version 3.01 (2013-04-13)
       they can be called directly, sonmp_ip(), cdp_ip(), etc.
     * L2::Bay and L2::Foundry have been removed from the distribution.  Both
       classes were depreciated and all functionality is available through
-      L2::Baystack and L3::Foundry. 
+      L2::Baystack and L3::Foundry.
 
     [NEW FEATURES]
 
@@ -307,7 +406,7 @@ version 3.01 (2013-04-13)
 
     [ENHANCEMENTS]
 
-    * UNIVERSAL::can() now works with dynamic methods 
+    * UNIVERSAL::can() now works with dynamic methods
     * Dynamically generated methods are added to symbol table to avoid
       AUTOLOAD on subsequent calls
     * L2::Airespace now supports 802.11n client tx rates
@@ -339,20 +438,20 @@ version 2.09 (2012-11-28)
     * New method i_ssidmac() to get BSSID's from AP's with initial support
       in L2::Aironet and Airespace classes
     * Support for Avaya Secure Routers in new class L3::Tasman
-    * Add EDP and LLDP L2 Topology to L3::Extreme 
+    * Add EDP and LLDP L2 Topology to L3::Extreme
     * [3185393] Support for Juniper SSL VPN in new class L7::Neoteris
-    * [3381027] Support for Cisco Nexus in new class L3::Nexus   
+    * [3381027] Support for Cisco Nexus in new class L3::Nexus
     * [1424336] Support for Extreme Discovery Protocol (EDP)
-    
+
     [ENHANCEMENTS]
 
-    * [3017571] Add LLDP support for NetSNMP device class (begemot) 
+    * [3017571] Add LLDP support for NetSNMP device class (begemot)
     * [3418918] Extreme devices now report OS as either extremeware or xos
     * [2809045] Strip preceding netscreen from model name in L3::Netscreen
     * [] Classify Linksys 2024 as L3::Dell (Rogier Krieger)
-    
+
     [BUG FIXES]
-    
+
     * Fixed logic to return cached data for table methods when available and
       not a partial fetch
     * Fix typo in PoD for Bridge.pm and CiscoConfig.pm (William Bulley)
@@ -372,7 +471,7 @@ version 2.08 (2012-07-15)
 
     * Pseudo ENTITY-MIB methods added to L3::Juniper for hardware information
     * Add method to report current transmit power of the radio interface,
-      dot11_cur_tx_pwr_mw(), in Airespace class 
+      dot11_cur_tx_pwr_mw(), in Airespace class
     * [3085411] Activate L3 properties for Netgear GSM7224v2 (phishphreek)
     * [3085413] SNMP OIDs for Netgear Serial and OS Ver (phishphreek)
     * [3286549] Dell LLDP Support (Nico Giefing)
@@ -421,7 +520,7 @@ version 2.06 (2011-09-28)
     * [3344843] Fix returning serial() and os_ver() for web-managable HP
       switches, introduced by HP/HP4000 class split, reported by J R Binks
     * [2809033] Put L2-only Cisco blade switches in L3::C6500
-    * [3408506] Fix uninitialized value in IPv6 when neighbor state is 
+    * [3408506] Fix uninitialized value in IPv6 when neighbor state is
       incomplete (Michael Borgelt)
 
 version 2.05 (2011-06-23)
@@ -437,13 +536,13 @@ version 2.04 (2011-03-31)
       (Brian De Wolf)
     + Added L3::Pf for FreeBSD PFSense Firewalls (max)
     * Added specific functions for neighbor mgmt addresses to CDP class
-    * Implemented os_bin() method in CiscoStats 
+    * Implemented os_bin() method in CiscoStats
     + [2980787] Fix for C1900 bp_index not containing interfaces.
       (Brian De Wolf)
     + [2599795] Added vendor_i_type() method to HP and HP4000 clases
     + [2688801] Minor modification for obscure Proxim/Orinoco device
       (jrbinks)
-    + [3051443] Add PoE measured power per port to Cisco, Extrme and HP 
+    + [3051443] Add PoE measured power per port to Cisco, Extrme and HP
       classes (jeroenvi)
     * Minor tweaks to support devices without sysServices
     * Added Cisco CBS3xxx blade switches to L3::C6500
@@ -481,7 +580,7 @@ version 2.00 (08/01/08)
     + Support for Alcatel-Lucent Service Router via L3::Timetra
     + Support for Alcatel-Lucent OmniAccess via L2::Aruba
 
-    * Silence warnings in MAU due to uninitialized variables 
+    * Silence warnings in MAU due to uninitialized variables
 
 version 1.09 (07/22/08) - Beta/developer release
     + Added support for HP ProCurve Foundry OEM switches, such as the 9300
@@ -505,7 +604,7 @@ version 1.09 (07/22/08) - Beta/developer release
     + Add support to specify MIB to resolve leaf names conflicts in
       %GLOBALS and %FUNCS.
     + Added munge_port_list() and modify_port_list() methods to assist in
-      working with PortList objects. 
+      working with PortList objects.
     + Added set_multi() method to enable a SNMP set command on several new
       values in one request.  Required for complex set operations
       on some agents.
@@ -532,7 +631,7 @@ version 1.05 (11/25/07) - CVS only. No official release
       Augenstein)
     + Added device specific support for LLDP in L2::HP, L2::Baystack,
       L3::Enterasys and L3::Foundry
-    + Added support for Enterasys devices as new class L3::Enterasys 
+    + Added support for Enterasys devices as new class L3::Enterasys
     + Added support for Dell PowerConnect switches as new class L3::Dell
     + Added basic support for generic routers running Microsoft Windows OS
       as new class L3::Microsoft (begemot)
@@ -556,7 +655,7 @@ version 1.05 (11/25/07) - CVS only. No official release
     + New class IEEE802dot11 class for generic standards based wireless AP
       support to include i_ssidlist()and i_80211channel() methods.
     + L2::Orinoco inherits from new IEEE802dot11 for i_ssidlist()and
-      i_80211channel() support. 
+      i_80211channel() support.
     + Added new VLAN methods i_pvid(), i_vlan_membership(), set_i_pvid(),
       set_i_vlan(), set_add_i_vlan_tagged(), set_remove_i_vlan_tagged() to
       Bridge, CiscoVTP, Extreme, HP, and RapidCity classes.
@@ -618,14 +717,14 @@ version 1.04 (07/08/06)
     +  Added C1130 and C1240 to L2::Aironet (Ralf Gross)
     +  Added detection for Cisco 2960, 2940, 3400 w/ MetroBase
     +  Added generic L2::Cisco Class
-    *  Corrected detection for Cisco Supervisor Engine 2 and 32 (IOS).  
+    *  Corrected detection for Cisco Supervisor Engine 2 and 32 (IOS).
     *  Fixed warnings in CiscoStack
     *  Updated ProCurve HP device detection for newer firmwares
 
 version 1.03 (04/14/06) - Beta/developer release
     * Use ipNetToMedia table instead of atTable for ARP
     * Remove CiscoStack from Layer3::C4000
-    * Fixed bug in MAU class when polling devices without MAU-MIB support 
+    * Fixed bug in MAU class when polling devices without MAU-MIB support
 
 version 1.01 (04/08/06) - Beta/developer release
     + Change version numbers to X.XX format.  Odd releases are beta
@@ -691,15 +790,15 @@ version 1.0 (04/07/06) - CVS only. No official release
       translated properly
 
 verison 0.9 (11/15/04)
-    + ** Added full Nortel/Bay/BayStack support 
-        by new developer Eric Miller.  
+    + ** Added full Nortel/Bay/BayStack support
+        by new developer Eric Miller.
         L2::Bay now depricated.
     + Added Alteon Ace support (Eric Miller)
     + Added Nortel Cotivity support (Eric Miller)
     + Added Nortel BayRS support (Eric Miller)
     + Added Nortel Centillion support (Eric Miller)
     + Added Nortel AP 222x support (Eric Miller)
-    + Added Orinco AP support (Eric Miller) 
+    + Added Orinco AP support (Eric Miller)
     + Added i_lastchange() per suggestion of Nicolai Petri
     + Added BULKWALK patch by Bradley Baetz - This should
           greatly speed up requests on SNMPv2c devices.
@@ -749,27 +848,27 @@ version 0.6 (06/18/03)
 
 version 0.5 (06/10/03)
     * Added ability to get paritial tables.  For example to get the
-      IP routing table for 128.114.*  you can do 
+      IP routing table for 128.114.*  you can do
       $ipr = $dev->ipr_dest('128.114');
     * Added IP Routing Table entries from RFC1213 to SNMP::Info
     * minor bug fixes
 
 version 0.4 (04/29/03)
-    * BIG CHANGE ! Internal Data structure has changed.  
+    * BIG CHANGE ! Internal Data structure has changed.
     * Added clear_cache() method
-    * Added NO_SUCH support for snmpget (TABLE) calls to get SNMP MIB II data 
+    * Added NO_SUCH support for snmpget (TABLE) calls to get SNMP MIB II data
       from SNMP Version 1 devices.
     * Methods load_all() and all() have changed their return value. Sorry but
       the API had to change.
     * New object methods snmp_comm(), snmp_ver(), store(), class(), nosuch()
       to make it more OO happy.
     * Globals are now cached
-    * Added new argument 'AutoSpecify' to new() to auto-connect with subclass 
+    * Added new argument 'AutoSpecify' to new() to auto-connect with subclass
       detected in device_type()
     * New method specify() returns a new subclass object
     * Subclasses are automatically loaded when specify or autospecify is used!
     * Added methods for Interface statistics (ifInOctets ...)
-    * Added methods for Memory and CPU statistics 
+    * Added methods for Memory and CPU statistics
     * Added SNMP::Info::Entity, moved out of L2-HP
     * Added SNMP::Info::Layer2::Aironet
 
@@ -782,7 +881,7 @@ version 0.3 (03/06/03)
       Thanks to Martin Lorensen <martin /at- lorensen.dk>
     * Removed requirement for SNMP in the Makefile.PL and moved it to t/prereq.t
       so that the Module will install via CPAN without trying to install the old
-      4.2.0 version of SNMP on CPAN.  Will now fail in the test phase. 
+      4.2.0 version of SNMP on CPAN.  Will now fail in the test phase.
       Thanks again to Martin Lorensen <martin /at- lorensen.dk>
     * Moved tests from test.pl to t/*
 
@@ -792,10 +891,10 @@ version 0.2 (02/19/03)
     * Fixed HP Detection in device_type()
     * Added Spanning Tree Protocol (STP) methods to SNMP::Info::Bridge
     * Removed HP Specific MIBS in SNMP::Info::Layer2 and cleaned up model()
-    * Added poke for Bay 450 Switches 
+    * Added poke for Bay 450 Switches
     * Mapped HP Part Numbers to model numbers J4812A => 2512 in
       SNMP::Info::Layer2::HP
-     
+
 version 0.1 (12/30/02)
     * Initial Release
     * SubClasses Included:
@@ -805,13 +904,13 @@ version 0.1 (12/30/02)
         * SNMP::Info::MAU
         * SNMP::Info::Layer1
               o SNMP::Info::Layer1::Allied
-              o SNMP::Info::Layer1::Asante 
+              o SNMP::Info::Layer1::Asante
         * SNMP::Info::Layer2
               o SNMP::Info::Layer2::Bay
               o SNMP::Info::Layer2::C1900
               o SNMP::Info::Layer2::C2900
               o SNMP::Info::Layer2::Catalyst
-              o SNMP::Info::Layer2::HP 
+              o SNMP::Info::Layer2::HP
         * SNMP::Info::Layer3
               o SNMP::Info::Layer3::Aironet
               o SNMP::Info::Layer3::Foundry
diff --git a/Info.pm b/Info.pm
index 382d2a3..63b3451 100644
--- a/Info.pm
+++ b/Info.pm
@@ -24,7 +24,7 @@ use vars
     qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE $AUTOLOAD $INIT $DEBUG %SPEED_MAP
     $NOSUCH $BIGINT $REPEATERS/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 =head1 NAME
 
@@ -32,7 +32,7 @@ SNMP::Info - OO Interface to Network devices and MIBs through SNMP
 
 =head1 VERSION
 
-SNMP::Info - Version 3.20
+SNMP::Info - Version 3.28
 
 =head1 AUTHOR
 
@@ -395,6 +395,12 @@ F<MAU-MIB> (RFC2668).  Some Layer2 devices use this for extended Ethernet
 
 See documentation in L<SNMP::Info::MAU> for details.
 
+=item SNMP::Info::MRO
+
+Method resolution introspection for SNMP::Info
+
+See documentation in L<SNMP::Info::MRO> for details.
+
 =item SNMP::Info::NortelStack
 
 F<S5-AGENT-MIB>, F<S5-CHASSIS-MIB>.
@@ -778,6 +784,12 @@ Subclass for Force10 devices.
 
 See documentation in L<SNMP::Info::Layer3::Force10> for details.
 
+=item SNMP::Info::Layer3::Fortinet
+
+Subclass for Fortinet devices.
+
+See documentation in L<SNMP::Info::Layer3::Fortinet> for details.
+
 =item SNMP::Info::Layer3::Foundry
 
 Subclass for Brocade (Foundry) Network devices.
@@ -797,6 +809,12 @@ Original Equipment Manufacturer (OEM) such as the HP ProCurve 9300 and 6300 seri
 
 See documentation in L<SNMP::Info::Layer3::HP9300> for details.
 
+=item SNMP::Info::Layer3::Huawei
+
+SNMP Interface to Huawei Layer 3 switches and routers.
+
+See documentation in L<SNMP::Info::Layer3::Huawei> for details.
+
 =item SNMP::Info::Layer3::IBMGbTor
 
 SNMP Interface to IBM Rackswitch (formerly Blade Network Technologies)
@@ -1493,6 +1511,7 @@ sub device_type {
         1872 => 'SNMP::Info::Layer3::AlteonAD',
         1916 => 'SNMP::Info::Layer3::Extreme',
         1991 => 'SNMP::Info::Layer3::Foundry',
+        2011 => 'SNMP::Info::Layer3::Huawei',
         2021 => 'SNMP::Info::Layer3::NetSNMP',
         2272 => 'SNMP::Info::Layer3::Passport',
         2636 => 'SNMP::Info::Layer3::Juniper',
@@ -1510,6 +1529,7 @@ sub device_type {
         9303 => 'SNMP::Info::Layer3::PacketFront',
         10002 => 'SNMP::Info::Layer2::Ubiquiti',
         12325 => 'SNMP::Info::Layer3::Pf',
+        12356 => 'SNMP::Info::Layer3::Fortinet',
         14179 => 'SNMP::Info::Layer2::Airespace',
         14525 => 'SNMP::Info::Layer2::Trapeze',
         14823 => 'SNMP::Info::Layer3::Aruba',
@@ -1532,6 +1552,7 @@ sub device_type {
         1872  => 'SNMP::Info::Layer3::AlteonAD',
         1916  => 'SNMP::Info::Layer3::Extreme',
         1991  => 'SNMP::Info::Layer3::Foundry',
+        2011  => 'SNMP::Info::Layer3::Huawei',
         2272  => 'SNMP::Info::Layer3::Passport',
         2925  => 'SNMP::Info::Layer1::Cyclades',
         3224  => 'SNMP::Info::Layer3::Netscreen',
@@ -1665,7 +1686,7 @@ sub device_type {
         # Starting with IOS 15, Aironet reports sysServices 6, even though
         # it still is the same layer2 access point.
         $objtype = 'SNMP::Info::Layer2::Aironet'
-            if ($desc =~ /\b(C1100|C1130|C1140|AP1200|C350|C1200|C1240|C1250)\b/
+            if ($desc =~ /\b(C1100|C1130|C1140|AP1200|C350|C1200|C1240|C1250|C2700|C3700)\b/
             and $desc =~ /\bIOS\b/ );
 
         # Airespace (WLC) Module
@@ -3404,7 +3425,7 @@ sub munge_mac {
 
 =item munge_prio_mac()
 
-Takes an 8-byte octet stream (HEX-STRING) and returns a colon separated ASCII
+Takes an 2-byte octet stream (HEX-STRING) and returns a colon separated ASCII
 hex string.
 
 =cut
@@ -3418,6 +3439,22 @@ sub munge_prio_mac {
     return;
 }
 
+=item munge_prio_port()
+
+Takes an 8-byte octet stream (HEX-STRING) and returns a colon separated ASCII
+hex string.
+
+=cut
+
+sub munge_prio_port {
+    my $mac = shift;
+    return unless defined $mac;
+    return unless length $mac;
+    $mac = join( ':', map { sprintf "%02x", $_ } unpack( 'C*', $mac ) );
+    return $mac if $mac =~ /^([0-9A-F][0-9A-F]:){1}[0-9A-F][0-9A-F]$/i;
+    return;
+}
+
 =item munge_octet2hex()
 
 Takes a binary octet stream and returns an ASCII hex string
@@ -3593,7 +3630,8 @@ sub init {
 
     foreach my $d (@$mibdirs) {
         next unless -d $d;
-        print "SNMP::Info::init() - Adding new mibdir:$d\n" if $self->debug();
+        print "SNMP::Info::init() - Adding new mibdir:$d\n"
+          if $self->debug() > 1;
         SNMP::addMibDirs($d);
     }
 
@@ -4516,7 +4554,8 @@ sub _validate_autoload_method {
     my $table_leaf = 0;
 
     if ( !$globals->{$attr}
-        && ( defined $indexes && scalar( @{$indexes} ) > 0 ) )
+        && ( ( defined $indexes && scalar( @{$indexes} ) > 0 )
+            || $funcs->{$attr} ))
     {
         $table_leaf = 1;
     }
diff --git a/Info/AMAP.pm b/Info/AMAP.pm
index 6485cfa..f9f47ca 100644
--- a/Info/AMAP.pm
+++ b/Info/AMAP.pm
@@ -38,7 +38,7 @@ use SNMP::Info;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS
     = ( 'ALCATEL-IND1-INTERSWITCH-PROTOCOL-MIB' => 'aipAMAPRemDeviceType', );
diff --git a/Info/AdslLine.pm b/Info/AdslLine.pm
index acd3985..6430eb6 100644
--- a/Info/AdslLine.pm
+++ b/Info/AdslLine.pm
@@ -38,7 +38,7 @@ use SNMP::Info;
 
 use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = ( 'ADSL-LINE-MIB' => 'adslLineType' );
 
diff --git a/Info/Aggregate.pm b/Info/Aggregate.pm
index 18561d9..e89506b 100644
--- a/Info/Aggregate.pm
+++ b/Info/Aggregate.pm
@@ -38,7 +38,7 @@ use SNMP::Info;
 
 use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (); # IF-MIB
 
diff --git a/Info/Airespace.pm b/Info/Airespace.pm
index 6ec2e9e..895a1ab 100644
--- a/Info/Airespace.pm
+++ b/Info/Airespace.pm
@@ -39,7 +39,7 @@ use SNMP::Info;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::MIBS,
diff --git a/Info/Bridge.pm b/Info/Bridge.pm
index 55ac7db..d355412 100644
--- a/Info/Bridge.pm
+++ b/Info/Bridge.pm
@@ -42,7 +42,7 @@ use SNMP::Info;
 
 use vars qw/$VERSION $DEBUG %MIBS %FUNCS %GLOBALS %MUNGE $INIT/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     'BRIDGE-MIB'   => 'dot1dBaseBridgeAddress',
@@ -84,6 +84,17 @@ $VERSION = '3.20';
     'bs_to'     => 'dot1dStaticAllowedToGoTo',
     'bs_status' => 'dot1dStaticStatus',
 
+    # These leafs are not part of a table, but placed here
+    # to return a hash reference to ease API compatibility with
+    # MST and PVST implementations indexed by a spanning tree
+    # instance id
+    'stp_i_mac'       => 'dot1dBaseBridgeAddress',
+    'stp_i_time'      => 'dot1dStpTimeSinceTopologyChange',
+    'stp_i_ntop'      => 'dot1dStpTopChanges',
+    'stp_i_root'      => 'dot1dStpDesignatedRoot',
+    'stp_i_root_port' => 'dot1dStpRootPort',
+    'stp_i_priority'  => 'dot1dStpPriority',
+
     # Spanning Tree Protocol Table : dot1dStpPortTable
     'stp_p_id'       => 'dot1dStpPort',
     'stp_p_priority' => 'dot1dStpPortPriority',
@@ -125,15 +136,18 @@ $VERSION = '3.20';
     'b_mac'            => \&SNMP::Info::munge_mac,
     'fw_mac'           => \&SNMP::Info::munge_mac,
     'bs_mac'           => \&SNMP::Info::munge_mac,
-    'stp_root'         => \&SNMP::Info::munge_mac,
+    'stp_root'         => \&SNMP::Info::munge_prio_mac,
+    'stp_i_mac'        => \&SNMP::Info::munge_mac,
+    'stp_i_root'       => \&SNMP::Info::munge_prio_mac,
     'stp_p_root'       => \&SNMP::Info::munge_prio_mac,
     'stp_p_bridge'     => \&SNMP::Info::munge_prio_mac,
-    'stp_p_port'       => \&SNMP::Info::munge_prio_mac,
+    'stp_p_port'       => \&SNMP::Info::munge_prio_port,
     'qb_cv_egress'     => \&SNMP::Info::munge_port_list,
     'qb_cv_untagged'   => \&SNMP::Info::munge_port_list,
     'qb_v_egress'      => \&SNMP::Info::munge_port_list,
     'qb_v_fbdn_egress' => \&SNMP::Info::munge_port_list,
     'qb_v_untagged'    => \&SNMP::Info::munge_port_list,
+    'qb_cv_untagged'   => \&SNMP::Info::munge_port_list,
 
 );
 
@@ -163,10 +177,20 @@ sub qb_fw_vlan {
     my $partial = shift;
 
     my $qb_fw_port = $bridge->qb_fw_port($partial);
+    my $qb_fdb_ids = $bridge->qb_fdb_index() || {};
+
+
     my $qb_fw_vlan = {};
     foreach my $idx ( keys %$qb_fw_port ) {
         my ( $fdb_id, $mac ) = _qb_fdbtable_index($idx);
-        $qb_fw_vlan->{$idx} = $fdb_id;
+        # Many devices do not populate the dot1qVlanCurrentTable, so default
+        # to FDB ID = VID, but if we have a mapping use it.  
+        my $vlan = $fdb_id;
+        # defined as test since some devices have a vlan 0
+        if (defined $qb_fdb_ids->{$fdb_id}) {
+            $vlan = $qb_fdb_ids->{$fdb_id};
+        }
+        $qb_fw_vlan->{$idx} = $vlan;
     }
     return $qb_fw_vlan;
 }
@@ -189,6 +213,25 @@ sub qb_i_vlan_t {
     return $i_vlan;
 }
 
+sub qb_fdb_index {
+    my $bridge  = shift;
+    my $partial = shift;
+
+    # Some devices may not implement TimeFilter in a standard manner
+    # appearing to loop on this request.  Override in the device class,
+    # see Enterasys for example.
+    my $qb_fdb_ids = $bridge->dot1qVlanFdbId() || {};
+
+    # Strip the TimeFilter
+    my $vl_fdb_index = {};
+    for my $fdb_entry (keys(%$qb_fdb_ids)) {
+        (my $vlan = $fdb_entry) =~ s/^\d+\.//;
+        $vl_fdb_index->{$qb_fdb_ids->{$fdb_entry}} = $vlan;
+    }
+
+    return $vl_fdb_index;
+}
+
 # Most devices now support Q-BRIDGE-MIB, fall back to 
 # BRIDGE-MIB for those that don't.
 sub fw_mac {
@@ -343,20 +386,31 @@ sub i_vlan_membership {
     my $bridge  = shift;
     my $partial = shift;
 
-    my $index = $bridge->bp_index();
+    # Use VlanCurrentTable if available since it will include dynamic
+    # VLANs.  However, some devices do not populate the table.
+    my $v_ports = $bridge->qb_cv_egress() || $bridge->qb_v_egress();
+
+    return $bridge->_vlan_hoa($v_ports, $partial);
+}
+
+sub i_vlan_membership_untagged {
+    my $bridge  = shift;
+    my $partial = shift;
 
     # Use VlanCurrentTable if available since it will include dynamic
     # VLANs.  However, some devices do not populate the table.
+    my $v_ports = $bridge->qb_cv_untagged() || $bridge->qb_v_untagged();
 
-    # 11/07 - Todo: Issue with some devices trying to query VlanCurrentTable
-    # as table may grow very large with frequent VLAN changes.
-    # 06/08 - VlanCurrentTable may be due to timefilter, should query with
-    # zero partial for no time filter.
-    # my $v_ports = $bridge->qb_cv_egress() || $bridge->qb_v_egress();
+    return $bridge->_vlan_hoa($v_ports, $partial);
+}
+
+sub _vlan_hoa {
+    my $bridge = shift;
+    my ( $v_ports, $partial ) = @_;
 
-    my $v_ports = $bridge->qb_v_egress() || {};
+    my $index = $bridge->bp_index();
 
-    my $i_vlan_membership = {};
+    my $vlan_hoa = {};
     foreach my $idx ( keys %$v_ports ) {
         next unless ( defined $v_ports->{$idx} );
         my $portlist = $v_ports->{$idx};
@@ -376,10 +430,10 @@ sub i_vlan_membership {
             my $ifindex = $index->{$port};
             next unless ( defined($ifindex) );    # shouldn't happen
             next if ( defined $partial and $ifindex !~ /^$partial$/ );
-            push( @{ $i_vlan_membership->{$ifindex} }, $vlan );
+            push( @{ $vlan_hoa->{$ifindex} }, $vlan );
         }
     }
-    return $i_vlan_membership;
+    return $vlan_hoa;
 }
 
 sub set_i_pvid {
@@ -649,11 +703,21 @@ IDs.  These are the VLANs which are members of the egress list for the port.
     print "Port: $port VLAN: $vlan\n";
   }
 
+=item $bridge->i_vlan_membership_untagged()
+
+Returns reference to hash of arrays: key = C<ifIndex>, value = array of VLAN
+IDs.  These are the VLANs which are members of the untagged egress list for
+the port.
+
 =item $bridge->qb_i_vlan_t()
 
 Returns reference to hash: key = C<dot1dBasePort>, value = either 'trunk' for
 tagged ports or the VLAN ID.
 
+=item $bridge->qb_fdb_index()
+
+Returns reference to hash: key = VLAN ID, value = FDB ID.
+
 =item $bridge->v_index()
 
 Returns VLAN IDs
@@ -707,6 +771,48 @@ to this port.
 
 =back
 
+=head2 Spanning Tree Instance Globals
+
+These are not part of a table, but return a hash reference to ease API
+compatibility with MST and PVST implementations indexed by a spanning tree
+instance id.
+
+=over
+
+=item $bridge->stp_i_time()
+
+Returns time since last topology change detected. (100ths/second)
+
+(C<dot1dStpTimeSinceTopologyChange>)
+
+=item $bridge->stp_i_time()
+
+Returns the total number of topology changes detected.
+
+(C<dot1dStpTopChanges>)
+
+=item $bridge->stp_i_root()
+
+Returns root of STP.
+
+(C<dot1dStpDesignatedRoot>)
+
+=item $bridge->stp_i_root_port()
+
+Returns the port number of the port that offers the lowest cost path
+to the root bridge.
+
+(C<dot1dStpRootPort>)
+
+=item $bridge->stp_i_priority()
+
+Returns the port number of the port that offers the lowest cost path
+to the root bridge.
+
+(C<dot1dStpPriority>)
+
+=back
+
 =head2 Spanning Tree Protocol Table (C<dot1dStpPortTable>)
 
 Descriptions are straight from F<BRIDGE-MIB.my>
diff --git a/Info/CDP.pm b/Info/CDP.pm
index c2f2d2f..06bc582 100644
--- a/Info/CDP.pm
+++ b/Info/CDP.pm
@@ -43,7 +43,7 @@ use SNMP::Info;
 use vars
     qw/$VERSION $DEBUG %FUNCS %GLOBALS %MIBS %MUNGE $INIT %CDP_CAPABILITIES/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 # Five data structures required by SNMP::Info
 %MIBS = ( 'CISCO-CDP-MIB' => 'cdpGlobalRun' );
diff --git a/Info/CiscoAgg.pm b/Info/CiscoAgg.pm
index 2ea0c8f..8fbe246 100644
--- a/Info/CiscoAgg.pm
+++ b/Info/CiscoAgg.pm
@@ -43,7 +43,7 @@ use SNMP::Info::IEEE802dot3ad 'agg_ports_lag';
 
 use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
   %SNMP::Info::IEEE802dot3ad::MIBS,
diff --git a/Info/CiscoConfig.pm b/Info/CiscoConfig.pm
index 46f8821..f35cc16 100644
--- a/Info/CiscoConfig.pm
+++ b/Info/CiscoConfig.pm
@@ -39,7 +39,7 @@ use SNMP::Info;
 
 use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     'CISCO-CONFIG-COPY-MIB' => 'ccCopyTable',
diff --git a/Info/CiscoPortSecurity.pm b/Info/CiscoPortSecurity.pm
index 10a149b..d663e95 100644
--- a/Info/CiscoPortSecurity.pm
+++ b/Info/CiscoPortSecurity.pm
@@ -38,7 +38,7 @@ use Exporter;
 
 use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE %PAECAPABILITIES/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     'CISCO-PORT-SECURITY-MIB' => 'ciscoPortSecurityMIB',
diff --git a/Info/CiscoPower.pm b/Info/CiscoPower.pm
index 15a9209..9db440c 100644
--- a/Info/CiscoPower.pm
+++ b/Info/CiscoPower.pm
@@ -39,7 +39,7 @@ use SNMP::Info;
 
 use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = ( 'CISCO-POWER-ETHERNET-EXT-MIB' => 'cpeExtPsePortEntPhyIndex',
           'CISCO-CDP-MIB' => 'cdpCachePowerConsumption' );
diff --git a/Info/CiscoQOS.pm b/Info/CiscoQOS.pm
index f6f55e5..3ee7516 100644
--- a/Info/CiscoQOS.pm
+++ b/Info/CiscoQOS.pm
@@ -39,7 +39,7 @@ use SNMP::Info;
 
 use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = ( 'CISCO-CLASS-BASED-QOS-MIB' => 'cbQosIfIndex', );
 
diff --git a/Info/CiscoRTT.pm b/Info/CiscoRTT.pm
index 11dc40b..901ffcb 100644
--- a/Info/CiscoRTT.pm
+++ b/Info/CiscoRTT.pm
@@ -39,7 +39,7 @@ use SNMP::Info;
 
 use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = ( 'CISCO-RTTMON-MIB' => 'rttMonCtrlAdminOwner', );
 
diff --git a/Info/CiscoStack.pm b/Info/CiscoStack.pm
index 5cd8311..6039d87 100644
--- a/Info/CiscoStack.pm
+++ b/Info/CiscoStack.pm
@@ -38,7 +38,7 @@ use Exporter;
 
 use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE %PORTSTAT/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = ( 'CISCO-STACK-MIB' => 'ciscoStackMIB', );
 
diff --git a/Info/CiscoStats.pm b/Info/CiscoStats.pm
index a04beff..071ecaa 100644
--- a/Info/CiscoStats.pm
+++ b/Info/CiscoStats.pm
@@ -42,7 +42,7 @@ use SNMP::Info;
 
 use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     'SNMPv2-MIB'            => 'sysDescr',
diff --git a/Info/CiscoStpExtensions.pm b/Info/CiscoStpExtensions.pm
index c7eafb5..f35758c 100644
--- a/Info/CiscoStpExtensions.pm
+++ b/Info/CiscoStpExtensions.pm
@@ -36,7 +36,7 @@ use SNMP::Info::Bridge;
 
 use vars qw/$VERSION $DEBUG %MIBS %FUNCS %GLOBALS %MUNGE %PORTSTAT $INIT/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 @SNMP::Info::CiscoStpExtensions::ISA = qw/SNMP::Info::Bridge SNMP::Info Exporter/;
 @SNMP::Info::CiscoStpExtensions::EXPORT_OK = qw//;
diff --git a/Info/CiscoVTP.pm b/Info/CiscoVTP.pm
index 7935902..8141d2b 100644
--- a/Info/CiscoVTP.pm
+++ b/Info/CiscoVTP.pm
@@ -41,7 +41,7 @@ use SNMP::Info;
 
 use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     'CISCO-VTP-MIB'                       => 'vtpVlanName',
@@ -149,6 +149,7 @@ sub i_vlan {
 
     my $port_vlan      = $vtp->vtp_trunk_native($partial)   || {};
     my $i_vlan         = $vtp->i_vlan2($partial)            || {};
+    my $trunk_dyn      = $vtp->vtp_trunk_dyn($partial)      || {};
     my $trunk_dyn_stat = $vtp->vtp_trunk_dyn_stat($partial) || {};
 
     my %i_vlans;
@@ -165,8 +166,17 @@ sub i_vlan {
     foreach my $port ( keys %$port_vlan ) {
         my $vlan = $port_vlan->{$port};
         next unless defined $vlan;
+
+        # ports up and trunking should have a trunking status
         my $stat = $trunk_dyn_stat->{$port};
-        if ( defined $stat and $stat =~ /^trunking/ ) {
+
+        # vtp_trunk_dyn_stat is not useful for down ports
+        # so we use vtp_trunk_dyn to see if trunking is set
+        my $dyn = $trunk_dyn->{$port};
+        
+        if (($stat and $stat =~ /^trunking/ )
+            or ($dyn and (($dyn eq 'on') or ($dyn eq 'onNoNegotiate'))))
+        {
             $i_vlans{$port} = $vlan;
         }
     }
@@ -217,6 +227,8 @@ sub i_vlan_membership {
     my $vtp_vlans      = $vtp->v_state();
     my $i_vlan         = $vtp->i_vlan2($partial)            || {};
     my $trunk_dyn_stat = $vtp->vtp_trunk_dyn_stat($partial) || {};
+    my $trunk_dyn      = $vtp->vtp_trunk_dyn($partial)      || {};
+    my $i_voice_vlan   = $vtp->i_voice_vlan($partial)       || {};
 
     my $i_vlan_membership = {};
 
@@ -224,14 +236,24 @@ sub i_vlan_membership {
     foreach my $port ( keys %$i_vlan ) {
         my $vlan = $i_vlan->{$port};
         next unless defined $vlan;
-        my $stat = $trunk_dyn_stat->{$port};
-        if ( defined $stat and $stat =~ /notTrunking/ ) {
+        my $dyn = $trunk_dyn->{$port};
+        unless ($dyn and (($dyn eq 'on') or ($dyn eq 'onNoNegotiate'))) {
             push( @{ $i_vlan_membership->{$port} }, $vlan );
         }
     }
 
-    # Get trunk ports
+    # Get voice VLANs
+    foreach my $port ( keys %$i_voice_vlan ) {
+        my $vlan = $i_voice_vlan->{$port};
+        next unless defined $vlan;
+        next unless ($vlan =~ m/[[:digit:]]+/ and $vlan < 4095);
+        my $dyn = $trunk_dyn->{$port};
+        unless ($dyn and (($dyn eq 'on') or ($dyn eq 'onNoNegotiate'))) {
+            push( @{ $i_vlan_membership->{$port} }, $vlan );
+        }
+    }
 
+    # Get trunk ports
     my %oper_vlans;
     foreach my $iid ( keys %$vtp_vlans ) {
         my $vlan    = 0;
@@ -248,7 +270,9 @@ sub i_vlan_membership {
 
     foreach my $port ( keys %$ports_vlans ) {
         my $stat = $trunk_dyn_stat->{$port};
-        if ( defined $stat and $stat =~ /^trunking/ ) {
+        my $dyn = $trunk_dyn->{$port};
+        if (($stat and $stat =~ /^trunking/ )
+            or ($dyn and (($dyn eq 'on') or ($dyn eq 'onNoNegotiate')))) {
             my $k     = 0;
             my $list1 = $ports_vlans->{$port} || '0';
             my $list2 = $ports_vlans_2k->{$port} || '0';
@@ -270,6 +294,20 @@ sub i_vlan_membership {
     return $i_vlan_membership;
 }
 
+sub i_vlan_membership_untagged {
+    my $vtp  = shift;
+    my $partial = shift;
+
+    my $vlans = $vtp->i_vlan($partial);
+    my $i_vlan_membership = {};
+    foreach my $port (keys %$vlans) {
+        my $vlan = $vlans->{$port};
+        push( @{ $i_vlan_membership->{$port} }, $vlan );
+    }
+    
+    return $i_vlan_membership;
+}
+
 sub set_i_pvid {
     my $vtp = shift;
     my ( $vlan_id, $ifindex ) = @_;
@@ -590,6 +628,12 @@ IDs.  These are the VLANs which are members of enabled VLAN list for the port.
     print "Port: $port VLAN: $vlan\n";
   }
 
+=item $vtp->i_vlan_membership_untagged()
+
+Returns reference to hash of arrays: key = C<ifIndex>, value = array of VLAN
+IDs.  These are the VLANs which are members of the untagged egress list for
+the port.
+
 =back
 
 =head2 VLAN Table (C<CISCO-VTP-MIB::vtpVlanTable>)
diff --git a/Info/EDP.pm b/Info/EDP.pm
index 5d46e4f..890cb91 100644
--- a/Info/EDP.pm
+++ b/Info/EDP.pm
@@ -39,7 +39,7 @@ use SNMP::Info;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     'EXTREME-EDP-MIB'   => 'extremeEdpPortIfIndex',
diff --git a/Info/Entity.pm b/Info/Entity.pm
index 44528e6..c558667 100644
--- a/Info/Entity.pm
+++ b/Info/Entity.pm
@@ -41,7 +41,7 @@ use SNMP::Info;
 
 use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = ( 'ENTITY-MIB' => 'entPhysicalSerialNum' );
 
diff --git a/Info/EtherLike.pm b/Info/EtherLike.pm
index ffaada9..45eb45c 100644
--- a/Info/EtherLike.pm
+++ b/Info/EtherLike.pm
@@ -41,7 +41,7 @@ use SNMP::Info;
 
 use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = ( 'EtherLike-MIB' => 'etherMIB' );
 
diff --git a/Info/FDP.pm b/Info/FDP.pm
index 1d3463a..c39bfe1 100644
--- a/Info/FDP.pm
+++ b/Info/FDP.pm
@@ -42,7 +42,7 @@ use SNMP::Info;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = ( 'FOUNDRY-SN-SWITCH-GROUP-MIB' => 'snFdpGlobalRun' );
 
diff --git a/Info/IEEE802dot11.pm b/Info/IEEE802dot11.pm
index 56f5299..0c932d6 100644
--- a/Info/IEEE802dot11.pm
+++ b/Info/IEEE802dot11.pm
@@ -38,7 +38,7 @@ use Exporter;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = ( 'IEEE802dot11-MIB' => 'dot11DesiredSSID', );
 
diff --git a/Info/IEEE802dot3ad.pm b/Info/IEEE802dot3ad.pm
index dafa2db..16e1e6d 100644
--- a/Info/IEEE802dot3ad.pm
+++ b/Info/IEEE802dot3ad.pm
@@ -43,7 +43,7 @@ use SNMP::Info::Aggregate;
 
 use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
   %SNMP::Info::Aggregate::MIBS,
diff --git a/Info/IPv6.pm b/Info/IPv6.pm
index 83e64f3..0a0528a 100644
--- a/Info/IPv6.pm
+++ b/Info/IPv6.pm
@@ -44,7 +44,7 @@ use constant {
     IPV6MIB => 3,
 };
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 
 
diff --git a/Info/LLDP.pm b/Info/LLDP.pm
index c96b156..53b380d 100644
--- a/Info/LLDP.pm
+++ b/Info/LLDP.pm
@@ -39,7 +39,7 @@ use SNMP::Info;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     'LLDP-MIB'          => 'lldpLocSysCapEnabled',
@@ -316,7 +316,7 @@ sub _lldp_addr_index {
     my @oids   = split( /\./, $idx );
     my $index  = join( '.', splice( @oids, 0, 3 ) );
     my $proto  = shift(@oids);
-    my $length = shift(@oids) if scalar @oids > 4;
+    shift(@oids) if scalar @oids > 4; # $length
 
     # IPv4
     if ( $proto == 1 ) {
diff --git a/Info/Layer1.pm b/Info/Layer1.pm
index 82fabfc..906c6dc 100644
--- a/Info/Layer1.pm
+++ b/Info/Layer1.pm
@@ -41,7 +41,7 @@ use SNMP::Info;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %PORTSTAT %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = ( %SNMP::Info::MIBS, 'SNMP-REPEATER-MIB' => 'rptrPortGroupIndex' );
 
diff --git a/Info/Layer1/Allied.pm b/Info/Layer1/Allied.pm
index 3246738..a054a10 100644
--- a/Info/Layer1/Allied.pm
+++ b/Info/Layer1/Allied.pm
@@ -41,7 +41,7 @@ use SNMP::Info::Layer1;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 # Set for No CDP
 %GLOBALS = ( %SNMP::Info::Layer1::GLOBALS, 'root_ip' => 'actualIPAddr', );
diff --git a/Info/Layer1/Asante.pm b/Info/Layer1/Asante.pm
index b597d6c..13b5778 100644
--- a/Info/Layer1/Asante.pm
+++ b/Info/Layer1/Asante.pm
@@ -41,7 +41,7 @@ use SNMP::Info::Layer1;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 # Set for No CDP
 %GLOBALS = ( %SNMP::Info::Layer1::GLOBALS, );
@@ -50,11 +50,11 @@ $VERSION = '3.20';
     %SNMP::Info::Layer1::FUNCS,
     'asante_port'  => 'ePortIndex',
     'asante_group' => 'ePortGrpIndex',
-    'i_type'       => 'ePortStateType',
+    'i_type'       => 'ePortGrpIndex',
     'asante_up'    => 'ePortStateLinkStatus',
 );
 
-%MIBS = ( %SNMP::Info::Layer1::MIBS, 'ASANTE-HUB1012-MIB' => 'asante' );
+%MIBS = ( %SNMP::Info::Layer1::MIBS, 'ASANTE-AH1012-MIB' => 'asante' );
 
 %MUNGE = ( %SNMP::Info::Layer1::MUNGE, );
 
@@ -202,7 +202,7 @@ Asante device through SNMP.
 
 =over
 
-=item F<ASANTE-HUB1012-MIB>
+=item F<ASANTE-AH1012-MIB>
 
 =back
 
@@ -230,7 +230,7 @@ Returns 'asante' :)
 
 =item $asante->model()
 
-Cross references $asante->id() to the F<ASANTE-HUB1012-MIB> and returns
+Cross references $asante->id() to the F<ASANTE-AH1012-MIB> and returns
 the results.
 
 =back
diff --git a/Info/Layer1/Bayhub.pm b/Info/Layer1/Bayhub.pm
index 292caaa..470c4fb 100644
--- a/Info/Layer1/Bayhub.pm
+++ b/Info/Layer1/Bayhub.pm
@@ -42,7 +42,7 @@ use SNMP::Info::Layer2;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer2::MIBS,
diff --git a/Info/Layer1/Cyclades.pm b/Info/Layer1/Cyclades.pm
index 8445013..6b1a744 100644
--- a/Info/Layer1/Cyclades.pm
+++ b/Info/Layer1/Cyclades.pm
@@ -39,7 +39,7 @@ use SNMP::Info::Layer1;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE $AUTOLOAD/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer1::MIBS,
diff --git a/Info/Layer1/S3000.pm b/Info/Layer1/S3000.pm
index 2977e53..eae1bc6 100644
--- a/Info/Layer1/S3000.pm
+++ b/Info/Layer1/S3000.pm
@@ -39,7 +39,7 @@ use SNMP::Info::Layer2;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer2::MIBS,
diff --git a/Info/Layer2.pm b/Info/Layer2.pm
index 67e38f2..84fadab 100644
--- a/Info/Layer2.pm
+++ b/Info/Layer2.pm
@@ -38,18 +38,20 @@ use SNMP::Info;
 use SNMP::Info::Bridge;
 use SNMP::Info::Entity;
 use SNMP::Info::PowerEthernet;
+use SNMP::Info::LLDP;
 
 @SNMP::Info::Layer2::ISA
-    = qw/SNMP::Info SNMP::Info::Bridge SNMP::Info::Entity SNMP::Info::PowerEthernet Exporter/;
+    = qw/SNMP::Info SNMP::Info::Bridge SNMP::Info::Entity SNMP::Info::PowerEthernet SNMP::Info::LLDP Exporter/;
 @SNMP::Info::Layer2::EXPORT_OK = qw//;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %PORTSTAT %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::MIBS,         %SNMP::Info::Bridge::MIBS,
     %SNMP::Info::Entity::MIBS, %SNMP::Info::PowerEthernet::MIBS,
+    %SNMP::Info::LLDP::MIBS,
 );
 
 %GLOBALS = (
@@ -57,6 +59,7 @@ $VERSION = '3.20';
     %SNMP::Info::Bridge::GLOBALS,
     %SNMP::Info::Entity::GLOBALS,
     %SNMP::Info::PowerEthernet::GLOBALS,
+    %SNMP::Info::LLDP::GLOBALS,
     'serial1' =>
         '.1.3.6.1.4.1.9.3.6.3.0',    # OLD-CISCO-CHASSIS-MIB::chassisId.0
 );
@@ -64,6 +67,7 @@ $VERSION = '3.20';
 %FUNCS = (
     %SNMP::Info::FUNCS,         %SNMP::Info::Bridge::FUNCS,
     %SNMP::Info::Entity::FUNCS, %SNMP::Info::PowerEthernet::FUNCS,
+    %SNMP::Info::LLDP::FUNCS,
 );
 
 %MUNGE = (
@@ -73,6 +77,7 @@ $VERSION = '3.20';
     %SNMP::Info::Bridge::MUNGE,
     %SNMP::Info::Entity::MUNGE,
     %SNMP::Info::PowerEthernet::MUNGE,
+    %SNMP::Info::LLDP::MUNGE,
 );
 
 # Method OverRides
@@ -133,23 +138,6 @@ sub serial {
     return;
 }
 
-sub i_ignore {
-    my $l2      = shift;
-    my $partial = shift;
-
-    my $i_type = $l2->i_type($partial) || {};
-
-    my %i_ignore = ();
-
-    foreach my $if ( keys %$i_type ) {
-        my $type = $i_type->{$if};
-        $i_ignore{$if}++
-            if $type =~ /(loopback|other|cpu)/i;
-    }
-
-    return \%i_ignore;
-}
-
 sub interfaces {
     my $l2      = shift;
     my $partial = shift;
@@ -235,6 +223,8 @@ after determining a more specific class using the method above.
 
 =item SNMP::Info::Entity
 
+=item SNMP::Info::LLDP
+
 =back
 
 =head2 Required MIBs
@@ -288,6 +278,10 @@ See documentation in L<SNMP::Info::Bridge/"GLOBALS"> for details.
 
 See documentation in L<SNMP::Info::Entity/"GLOBALS"> for details.
 
+=head2 Globals imported from SNMP::Info::LLDP
+
+See documentation in L<SNMP::Info::LLDP/"GLOBALS"> for details.
+
 =head1 TABLE METHODS
 
 These are methods that return tables of information in the form of a reference
@@ -304,12 +298,6 @@ name.
 
 Defaults to C<ifDescr> but checks and overrides with C<ifName>
 
-=item $l2->i_ignore()
-
-Returns reference to hash.  Increments value of IID if port is to be ignored.
-
-Ignores ports with C<ifType> of loopback, propvirtual, other, and cpu
-
 =back
 
 =head2 Table Methods imported from SNMP::Info
@@ -324,4 +312,8 @@ See documentation in L<SNMP::Info::Bridge/"TABLE METHODS"> for details.
 
 See documentation in L<SNMP::Info::Entity/"TABLE METHODS"> for details.
 
+=head2 Table Methods imported from SNMP::Info::LLDP
+
+See documentation in L<SNMP::Info::LLDP/"TABLE METHODS"> for details.
+
 =cut
diff --git a/Info/Layer2/3Com.pm b/Info/Layer2/3Com.pm
index aca5846..47f5486 100644
--- a/Info/Layer2/3Com.pm
+++ b/Info/Layer2/3Com.pm
@@ -11,11 +11,12 @@ use SNMP::Info::CDP;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE $AUTOLOAD/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::LLDP::MIBS,
     %SNMP::Info::Layer2::MIBS,
+    'A3Com-products-MIB' => 'wlanAP7760',
 );
 
 %GLOBALS = (
@@ -117,6 +118,8 @@ Subclass for 3Com L2 devices
 
 =over
 
+=item F<A3Com-products-MIB>
+
 =item Inherited Classes' MIBs
 
 See L<SNMP::Info::Layer2/"Required MIBs"> for its own MIB requirements.
diff --git a/Info/Layer2/Airespace.pm b/Info/Layer2/Airespace.pm
index 33cc2b0..4baa5b1 100644
--- a/Info/Layer2/Airespace.pm
+++ b/Info/Layer2/Airespace.pm
@@ -40,7 +40,7 @@ use SNMP::Info::Airespace;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::MIBS,      %SNMP::Info::Bridge::MIBS,
diff --git a/Info/Layer2/Aironet.pm b/Info/Layer2/Aironet.pm
index ebad742..ff9d314 100644
--- a/Info/Layer2/Aironet.pm
+++ b/Info/Layer2/Aironet.pm
@@ -49,7 +49,7 @@ use SNMP::Info::IEEE802dot11;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %GLOBALS = (
     %SNMP::Info::IEEE802dot11::GLOBALS,
@@ -60,7 +60,8 @@ $VERSION = '3.20';
     %SNMP::Info::CiscoConfig::GLOBALS,
     %SNMP::Info::CDP::GLOBALS,
     'serial' => 'entPhysicalSerialNum.1',
-    'descr'  => 'sysDescr'
+    'descr'  => 'sysDescr',
+    'ps1_type' => 'cpoePdCurrentPowerSource'
 );
 
 %FUNCS = (
@@ -97,6 +98,7 @@ $VERSION = '3.20';
     'CISCO-DOT11-ASSOCIATION-MIB'         => 'cDot11ClientSubIfIndex',
     'CISCO-DOT11-SSID-SECURITY-MIB'       => 'cdot11SecVlanNameId',
     'CISCO-VLAN-IFTABLE-RELATIONSHIP-MIB' => 'cviRoutedVlanIfIndex',
+    'CISCO-POE-PD-MIB'                    => 'cpoePdCurrentPowerSource',
 );
 
 %MUNGE = (
@@ -457,6 +459,18 @@ sub i_ssidmac {
     return $i_ssidmac;
 }
 
+###
+# PoE status.  The ps1_type is the PoE injector type, which is just
+# a scalar; the status is a little more complex.
+sub ps1_status {
+    my $aironet = shift;
+    my $idx = $aironet->cpoePdCurrentPowerLevel();
+    my $mw = $aironet->cpoePdSupportedPower( $idx );
+    my $descr = $aironet->cpoePdSupportedPowerMode( $idx );
+
+    return sprintf( "%.2fW (%s)", $mw->{$idx} * 0.001, $descr->{$idx} );
+}
+
 1;
 __END__
 
@@ -540,17 +554,13 @@ These are methods that return scalar value from SNMP
 
 =over
 
-=item $aironet->discription()
-
-Adds info from method e_descr() from SNMP::Info::Entity
-
 =item $aironet->vendor()
 
 Returns 'cisco'
 
 =item $aironet->description()
 
-System description
+System description. Adds info from method e_descr() from SNMP::Info::Entity
 
 =back
 
@@ -648,6 +658,11 @@ being broadcast.
 With the same keys as i_ssidlist, returns the Basic service set
 identification (BSSID), MAC address, the AP is using for the SSID. 
 
+=item $aironet ps1_status()
+
+Returns the PoE injector status based on C<cpoePdSupportedPower> and 
+C<cpoePdSupportedPowerMode>.
+
 =back
 
 =head2 Table Methods imported from SNMP::Info::Layer2
diff --git a/Info/Layer2/Allied.pm b/Info/Layer2/Allied.pm
index 4701f61..acfa690 100644
--- a/Info/Layer2/Allied.pm
+++ b/Info/Layer2/Allied.pm
@@ -40,7 +40,7 @@ use SNMP::Info::Layer1;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %GLOBALS = ( %SNMP::Info::Layer2::GLOBALS );
 
diff --git a/Info/Layer2/Baystack.pm b/Info/Layer2/Baystack.pm
index e1c1119..d97289f 100644
--- a/Info/Layer2/Baystack.pm
+++ b/Info/Layer2/Baystack.pm
@@ -46,7 +46,7 @@ use SNMP::Info::Layer3;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::MIBS,    %SNMP::Info::LLDP::MIBS,
@@ -341,6 +341,60 @@ sub peth_port_ifindex {
     return \%peth_port_ifindex;
 }
 
+# Currently only ERS 4800 v5.8+ support the rcBridgeSpbmMacTable 
+# which holds the FDB for a SPBM edge deployment.
+#
+# Q-BRIDGE still holds some entries when the rcBridgeSpbmMacTable is in use
+# so we merge hash entries.
+
+sub fw_mac {
+    my $rapidcity = shift;
+
+    my $qb = $rapidcity->SUPER::fw_mac() || {};
+    my $spbm = $rapidcity->rc_spbm_fw_mac() || {};
+    my $fw_mac = { %$qb, %$spbm };
+    
+    return $fw_mac;
+}
+
+sub fw_port {
+    my $rapidcity = shift;
+
+    my $qb = $rapidcity->SUPER::fw_port() || {};
+    my $spbm = $rapidcity->rc_spbm_fw_port() || {};
+    my $fw_port = { %$qb, %$spbm };
+    
+    return $fw_port;
+}
+
+sub fw_status {
+    my $rapidcity = shift;
+
+    my $qb = $rapidcity->SUPER::fw_status() || {};    
+    my $spbm = $rapidcity->rc_spbm_fw_status() || {};
+    my $fw_status = { %$qb, %$spbm };
+    
+    return $fw_status;
+}
+
+sub qb_fw_vlan {
+    my $rapidcity = shift;
+
+    my $qb = $rapidcity->SUPER::qb_fw_vlan() || {};
+    my $spbm = $rapidcity->rc_spbm_fw_vlan() || {};
+    my $qb_fw_vlan = { %$qb, %$spbm };
+    
+    return $qb_fw_vlan;
+}
+
+# Baystack uses S5-AGENT-MIB (loaded in NortelStack) versus RAPID-CITY
+sub stp_ver {
+    my $rapidcity = shift;
+
+    return $rapidcity->s5AgSysSpanningTreeOperMode()
+      || $rapidcity->SUPER::stp_ver();
+}
+
 1;
 
 __END__
@@ -444,6 +498,14 @@ Returns 'baystack' or 'boss' depending on software version.
 
 Returns the firmware version extracted from C<sysDescr>.
 
+=item $baystack->stp_ver()
+
+Returns the particular STP version running on this device.  
+
+Values: C<nortelStpg>, C<pvst>, C<rstp>, C<mstp>, C<ieee8021d>
+
+(C<s5AgSysSpanningTreeOperMode>)
+
 =back
 
 =head2 Overrides
@@ -600,6 +662,32 @@ ns_e_vendor().
 
 =back
 
+=head2 Layer 2 Forwarding Database
+
+These methods try to obtain the layer 2 forwarding database entries via the
+normal bridge methods as well as SPBM entries via rapid city methods.
+
+=over
+
+=item $baystack->fw_mac()
+
+Returns reference to hash of forwarding table MAC Addresses
+
+=item $baystack->fw_port()
+
+Returns reference to hash of forwarding table entries port interface
+identifier (iid)
+
+=item $baystack->qb_fw_vlan()
+
+Returns reference to hash of forwarding table entries VLAN ID
+
+=item $baystack->fw_status()
+
+Returns reference to hash of forwarding table entries status
+
+=back
+
 =head2 Table Methods imported from SNMP::Info::SONMP
 
 See L<SNMP::Info::SONMP/"TABLE METHODS"> for details.
diff --git a/Info/Layer2/C1900.pm b/Info/Layer2/C1900.pm
index 71fb7e4..54b64c7 100644
--- a/Info/Layer2/C1900.pm
+++ b/Info/Layer2/C1900.pm
@@ -48,7 +48,7 @@ use SNMP::Info::Layer2;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %GLOBALS = (
     %SNMP::Info::Layer2::GLOBALS,
@@ -261,6 +261,8 @@ sub i_vlan_membership {
     return $i_vlan_membership;
 }
 
+sub i_vlan_membership_untagged { return; }
+
 sub bp_index {
     my $c1900   = shift;
     my $partial = shift;
@@ -470,6 +472,9 @@ bridge group IDs.
     print "Port: $port VLAN: $vlan\n";
   }
 
+=item $c1900->i_vlan_membership_untagged()
+
+Unsupported, returns nothing.
 
 =item $c1900->bp_index()
 
diff --git a/Info/Layer2/C2900.pm b/Info/Layer2/C2900.pm
index a8b7b9b..2132043 100644
--- a/Info/Layer2/C2900.pm
+++ b/Info/Layer2/C2900.pm
@@ -41,7 +41,7 @@ use SNMP::Info::Layer2::Cisco;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %GLOBALS = (
     %SNMP::Info::Layer2::Cisco::GLOBALS,
diff --git a/Info/Layer2/Catalyst.pm b/Info/Layer2/Catalyst.pm
index 9878244..a4ec87b 100644
--- a/Info/Layer2/Catalyst.pm
+++ b/Info/Layer2/Catalyst.pm
@@ -42,7 +42,7 @@ use SNMP::Info::Layer2::Cisco;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer2::Cisco::MIBS,
diff --git a/Info/Layer2/Centillion.pm b/Info/Layer2/Centillion.pm
index 0bc9e70..79128ce 100644
--- a/Info/Layer2/Centillion.pm
+++ b/Info/Layer2/Centillion.pm
@@ -43,7 +43,7 @@ use SNMP::Info::SONMP;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::MIBS,
diff --git a/Info/Layer2/Cisco.pm b/Info/Layer2/Cisco.pm
index b4522ed..6794513 100644
--- a/Info/Layer2/Cisco.pm
+++ b/Info/Layer2/Cisco.pm
@@ -52,7 +52,7 @@ use SNMP::Info::Layer2;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer2::MIBS,
diff --git a/Info/Layer2/CiscoSB.pm b/Info/Layer2/CiscoSB.pm
index 1906cfa..3566801 100644
--- a/Info/Layer2/CiscoSB.pm
+++ b/Info/Layer2/CiscoSB.pm
@@ -50,7 +50,7 @@ use SNMP::Info::CDP;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 # This will be filled in with the device's index into the EntPhysicalEntry
 # table by the serial() function.
diff --git a/Info/Layer2/HP.pm b/Info/Layer2/HP.pm
index 98a19e3..b4fcfef 100644
--- a/Info/Layer2/HP.pm
+++ b/Info/Layer2/HP.pm
@@ -36,7 +36,6 @@ use strict;
 use Exporter;
 use SNMP::Info::Layer3;
 use SNMP::Info::MAU;
-use SNMP::Info::LLDP;
 use SNMP::Info::CDP;
 use SNMP::Info::Aggregate;
 
@@ -44,7 +43,6 @@ use SNMP::Info::Aggregate;
     SNMP::Info::Aggregate
     SNMP::Info::Layer3 
     SNMP::Info::MAU 
-    SNMP::Info::LLDP
     SNMP::Info::CDP 
     Exporter
 /;
@@ -52,12 +50,11 @@ use SNMP::Info::Aggregate;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %PORTSTAT %MODEL_MAP %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::MIBS,
     %SNMP::Info::MAU::MIBS,
-    %SNMP::Info::LLDP::MIBS,
     %SNMP::Info::CDP::MIBS,
     %SNMP::Info::Aggregate::MIBS,
     'RFC1271-MIB'    => 'logDescription',
@@ -74,7 +71,6 @@ $VERSION = '3.20';
 %GLOBALS = (
     %SNMP::Info::Layer3::GLOBALS,
     %SNMP::Info::MAU::GLOBALS,
-    %SNMP::Info::LLDP::GLOBALS,
     %SNMP::Info::CDP::GLOBALS,
     %SNMP::Info::Aggregate::GLOBALS,
     'serial1'      => 'entPhysicalSerialNum.1',
@@ -93,7 +89,6 @@ $VERSION = '3.20';
 %FUNCS = (
     %SNMP::Info::Layer3::FUNCS,
     %SNMP::Info::MAU::FUNCS,
-    %SNMP::Info::LLDP::FUNCS,
     %SNMP::Info::CDP::FUNCS,
     %SNMP::Info::Aggregate::FUNCS,
     'i_type2'   => 'ifType',
@@ -119,7 +114,6 @@ $VERSION = '3.20';
     # Inherit all the built in munging
     %SNMP::Info::Layer3::MUNGE,
     %SNMP::Info::MAU::MUNGE,
-    %SNMP::Info::LLDP::MUNGE,
     %SNMP::Info::CDP::MUNGE,
     %SNMP::Info::Aggregate::MUNGE,
     'c_id'   => \&munge_hp_c_id,
@@ -131,6 +125,8 @@ $VERSION = '3.20';
 %MODEL_MAP = (
     'J8131A' => 'WAP-420-WW',
     'J8130A' => 'WAP-420-NA',
+    'J9833A' => 'PS1810-8G',
+    'J9834A' => 'PS1810-24G',
     'J8133A' => 'AP520WL',
     'J8680A' => '9408sl',
     'J9091A' => '8212zl',
@@ -145,8 +141,10 @@ $VERSION = '3.20';
     'J8992A' => '6200yl-24G',
     'J4902A' => '6108',
     'J8698A' => '5412zl',
+    'J9851A' => '5412R-zl2',
     'J8719A' => '5408yl',
     'J8697A' => '5406zl',
+    'J9850A' => '5406R-zl2',
     'J8718A' => '5404yl',
     'J4819A' => '5308XL',
     'J4850A' => '5304XL',
@@ -178,8 +176,12 @@ $VERSION = '3.20';
     'J4815A' => '3324XL',
     'J4851A' => '3124',
     'J9729A' => '2920-48G-PoE+',
+    'J9729A' => '2920-48G-PoE+',
+    'J9728A' => '2920-48G',
     'J9728A' => '2920-48G',
     'J9727A' => '2920-24G-PoE+',
+    'J9727A' => '2920-24G-PoE+',
+    'J9726A' => '2920-24G',
     'J9726A' => '2920-24G',
     'J9562A' => '2915-8G-PoE',
     'J9148A' => '2910al-48G-PoE+',
@@ -192,30 +194,41 @@ $VERSION = '3.20';
     'J4903A' => '2824',
     'J9022A' => '2810-48G',
     'J9021A' => '2810-24G',
-    'J4899C' => '2650C',
     'J8165A' => '2650-PWR',
     'J4899B' => '2650-CR',
+    'J4899C' => '2650C',
     'J4899A' => '2650',
-    'J4900C' => '2626C',
     'J8164A' => '2626-PWR',
     'J4900B' => '2626-CR',
+    'J4900C' => '2626C',
     'J4900A' => '2626',
     'J9627A' => '2620-48-PoE+',
     'J9626A' => '2620-48',
-    'J9625A' => '2620-24-PoE+',
     'J9624A' => '2620-24-PPoE+',
+    'J9625A' => '2620-24-PoE+',
     'J9623A' => '2620-24',
     'J9565A' => '2615-8-PoE',
     'J9089A' => '2610-48-PWR',
     'J9088A' => '2610-48',
-    'J9086A' => '2610-24/12PWR',
     'J9087A' => '2610-24-PWR',
+    'J9086A' => '2610-24/12PWR',
     'J9085A' => '2610-24',
     'J8762A' => '2600-8-PWR',
+    'J9780A' => '2530-8-PoE+',
+    'J9777A' => '2530-8G',
+    'J9783A' => '2530-8',
+    'J9778A' => '2530-48-PoE+',
+    'J9853A' => '2530-48G-PoE+-2SFP+',
     'J9772A' => '2530-48G-PoE+',
+    'J9855A' => '2530-48G-2SFP+',
     'J9775A' => '2530-48G',
+    'J9781A' => '2530-48',
+    'J9779A' => '2530-24-PoE+',
+    'J9854A' => '2530-24G-PoE+-2SFP+',
     'J9773A' => '2530-24G-PoE+',
+    'J9856A' => '2530-24G-2SFP+',
     'J9776A' => '2530-24G',
+    'J9782A' => '2530-24',
     'J4813A' => '2524',
     'J9298A' => '2520G-8-PoE',
     'J9299A' => '2520G-24-PoE',
@@ -231,6 +244,8 @@ $VERSION = '3.20';
     'J4817A' => '2312',
     'J9449A' => '1810G-8',
     'J9450A' => '1810G-24',
+    'J9802A' => '1810-8G',
+    'J9803A' => '1810-24G',
     'J9029A' => '1800-8G',
     'J9028A' => '1800-24G',
 );
@@ -536,30 +551,6 @@ sub set_i_vlan_tagged {
 
 sub agg_ports { return agg_ports_ifstack(@_) }
 
-sub qb_fw_vlan {
-    my $hp = shift;
-    my $partial = shift;
-    my $qb_fw_vlan = $hp->SUPER::qb_fw_vlan($partial);
-
-    my $fdb_to_dot1q = {};
-    my $fdb_id = $hp->dot1qVlanFdbId(0);
-    foreach my $fdb_entry (keys %$fdb_id) {
-        my ($timemark, $vlan_id) = split(/\./, $fdb_entry);
-        $fdb_to_dot1q->{$fdb_id->{$fdb_entry}} = $vlan_id;
-    }
-    foreach my $learn (keys %$qb_fw_vlan) {
-        my $fdb_idx = $qb_fw_vlan->{$learn};
-        if (exists $fdb_to_dot1q->{$fdb_idx}) {
-            $qb_fw_vlan->{$learn} = $fdb_to_dot1q->{$fdb_idx}; 
-        }
-    }
-
-    return $qb_fw_vlan;
-}
-
-
-
-
 1;
 __END__
 
@@ -606,8 +597,6 @@ after determining a more specific class using the method above.
 
 =item SNMP::Info::Layer2
 
-=item SNMP::Info::LLDP
-
 =item SNMP::Info::MAU
 
 =back
@@ -827,22 +816,12 @@ Power supplied by PoE ports, in milliwatts
 Returns what version of STP the device is running.
 (C<hpicfBridgeRstpForceVersion> with fallback to inherited stp_ver())
 
-=item $hp->qb_fw_vlan()
-
-Returns reference to hash of forwarding table entries VLAN ID
-
-(C<dot1qFdbId>), (C<rcBridgeTpFdbVlanId>)
-
 =back
 
 =head2 Globals imported from SNMP::Info::Layer2
 
 See documentation in L<SNMP::Info::Layer2/"GLOBALS"> for details.
 
-=head2 Globals imported from SNMP::Info::LLDP
-
-See documentation in L<SNMP::Info::LLDP/"GLOBALS"> for details.
-
 =head2 Globals imported from SNMP::Info::MAU
 
 See documentation in L<SNMP::Info::MAU/"GLOBALS"> for details.
@@ -894,10 +873,6 @@ ifIndex of the corresponding master ports.
 
 See documentation in L<SNMP::Info::Layer2/"TABLE METHODS"> for details.
 
-=head2 Table Methods imported from SNMP::Info::LLDP
-
-See documentation in L<SNMP::Info::LLDP/"TABLE METHODS"> for details.
-
 =head2 Table Methods imported from SNMP::Info::MAU
 
 See documentation in L<SNMP::Info::MAU/"TABLE METHODS"> for details.
diff --git a/Info/Layer2/HP4000.pm b/Info/Layer2/HP4000.pm
index 04c6dca..c7240fe 100644
--- a/Info/Layer2/HP4000.pm
+++ b/Info/Layer2/HP4000.pm
@@ -44,7 +44,7 @@ use SNMP::Info::CDP;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %PORTSTAT %MODEL_MAP %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::MIBS,
@@ -376,6 +376,20 @@ sub i_vlan_membership {
     return $i_vlan_membership;
 }
 
+sub i_vlan_membership_untagged {
+    my $hp  = shift;
+    my $partial = shift;
+
+    my $vlans = $hp->i_vlan($partial);
+    my $i_vlan_membership = {};
+    foreach my $port (keys %$vlans) {
+        my $vlan = $vlans->{$port};
+        push( @{ $i_vlan_membership->{$port} }, $vlan );
+    }
+    
+    return $i_vlan_membership;
+}
+
 sub set_i_vlan {
     my $hp = shift;
     my $rv;
@@ -680,6 +694,12 @@ It is the union of tagged, untagged, and auto ports.
     print "Port: $port VLAN: $vlan\n";
   }
 
+=item $hp->i_vlan_membership_untagged()
+
+Returns reference to hash of arrays: key = C<ifIndex>, value = array of VLAN
+IDs.  These are the VLANs which are members of the untagged egress list for
+the port.
+
 =item $hp->v_index()
 
 Returns VLAN IDs
diff --git a/Info/Layer2/HPVC.pm b/Info/Layer2/HPVC.pm
index 786e15d..572a9f6 100644
--- a/Info/Layer2/HPVC.pm
+++ b/Info/Layer2/HPVC.pm
@@ -41,7 +41,7 @@ use SNMP::Info::LLDP;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer2::MIBS,
diff --git a/Info/Layer2/Kentrox.pm b/Info/Layer2/Kentrox.pm
index d48692d..5df0a70 100644
--- a/Info/Layer2/Kentrox.pm
+++ b/Info/Layer2/Kentrox.pm
@@ -36,7 +36,7 @@ use SNMP::Info::Layer2;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE $AUTOLOAD/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer2::MIBS,
diff --git a/Info/Layer2/N2270.pm b/Info/Layer2/N2270.pm
index f669439..f06b8f6 100644
--- a/Info/Layer2/N2270.pm
+++ b/Info/Layer2/N2270.pm
@@ -43,7 +43,7 @@ use SNMP::Info::Airespace;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE $AUTOLOAD $INIT $DEBUG/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::MIBS,        %SNMP::Info::Bridge::MIBS,
diff --git a/Info/Layer2/NAP222x.pm b/Info/Layer2/NAP222x.pm
index 94caebf..220bd64 100644
--- a/Info/Layer2/NAP222x.pm
+++ b/Info/Layer2/NAP222x.pm
@@ -42,7 +42,7 @@ use SNMP::Info::Layer2;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer2::MIBS, %SNMP::Info::IEEE802dot11::MIBS,
diff --git a/Info/Layer2/NWSS2300.pm b/Info/Layer2/NWSS2300.pm
index c82e227..aedebeb 100644
--- a/Info/Layer2/NWSS2300.pm
+++ b/Info/Layer2/NWSS2300.pm
@@ -39,7 +39,7 @@ use SNMP::Info::Bridge;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::MIBS,
diff --git a/Info/Layer2/Netgear.pm b/Info/Layer2/Netgear.pm
index 5c8980f..62bbd9b 100644
--- a/Info/Layer2/Netgear.pm
+++ b/Info/Layer2/Netgear.pm
@@ -40,7 +40,7 @@ use SNMP::Info::LLDP;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 # This will be filled in with the device's index into the EntPhysicalEntry
 # table by the serial() function.
diff --git a/Info/Layer2/Orinoco.pm b/Info/Layer2/Orinoco.pm
index 15f8479..fbdd0a1 100644
--- a/Info/Layer2/Orinoco.pm
+++ b/Info/Layer2/Orinoco.pm
@@ -41,7 +41,7 @@ use SNMP::Info::Layer2;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer2::MIBS,
diff --git a/Info/Layer2/Trapeze.pm b/Info/Layer2/Trapeze.pm
index dac201c..a7826c3 100644
--- a/Info/Layer2/Trapeze.pm
+++ b/Info/Layer2/Trapeze.pm
@@ -40,7 +40,7 @@ use SNMP::Info::LLDP;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::MIBS,
diff --git a/Info/Layer2/Ubiquiti.pm b/Info/Layer2/Ubiquiti.pm
index 2b9dbb5..86218e8 100644
--- a/Info/Layer2/Ubiquiti.pm
+++ b/Info/Layer2/Ubiquiti.pm
@@ -15,7 +15,7 @@ use SNMP::Info::Layer2;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer2::MIBS,
diff --git a/Info/Layer2/ZyXEL_DSLAM.pm b/Info/Layer2/ZyXEL_DSLAM.pm
index 48e0820..8b88f81 100644
--- a/Info/Layer2/ZyXEL_DSLAM.pm
+++ b/Info/Layer2/ZyXEL_DSLAM.pm
@@ -39,7 +39,7 @@ use SNMP::Info::Layer2;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 # Set for No CDP
 %GLOBALS = ( %SNMP::Info::Layer2::GLOBALS );
diff --git a/Info/Layer3.pm b/Info/Layer3.pm
index 51eeb57..e8f4282 100644
--- a/Info/Layer3.pm
+++ b/Info/Layer3.pm
@@ -41,17 +41,19 @@ use SNMP::Info::Entity;
 use SNMP::Info::PowerEthernet;
 use SNMP::Info::IPv6;
 use SNMP::Info::AdslLine;
+use SNMP::Info::LLDP;
 
 @SNMP::Info::Layer3::ISA = qw/
     SNMP::Info::PowerEthernet SNMP::Info::IPv6
     SNMP::Info::Entity SNMP::Info::EtherLike
     SNMP::Info::Bridge SNMP::Info::AdslLine
+    SNMP::Info::LLDP
     SNMP::Info Exporter/;
 @SNMP::Info::Layer3::EXPORT_OK = qw//;
 
 use vars qw/$VERSION %GLOBALS %FUNCS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::MIBS,
@@ -61,6 +63,7 @@ $VERSION = '3.20';
     %SNMP::Info::Entity::MIBS,
     %SNMP::Info::PowerEthernet::MIBS,
     %SNMP::Info::IPv6::MIBS,
+    %SNMP::Info::LLDP::MIBS,
     'IP-MIB'   => 'ipNetToMediaIfIndex',
     'OSPF-MIB' => 'ospfRouterId',
     'BGP4-MIB' => 'bgpIdentifier',
@@ -76,6 +79,7 @@ $VERSION = '3.20';
     %SNMP::Info::Entity::GLOBALS,
     %SNMP::Info::PowerEthernet::GLOBALS,
     %SNMP::Info::IPv6::GLOBALS,
+    %SNMP::Info::LLDP::GLOBALS,
     'mac' => 'ifPhysAddress.1',
     'serial1' =>
         '.1.3.6.1.4.1.9.3.6.3.0',    # OLD-CISCO-CHASSIS-MIB::chassisId.0
@@ -92,6 +96,7 @@ $VERSION = '3.20';
     %SNMP::Info::Entity::FUNCS,
     %SNMP::Info::PowerEthernet::FUNCS,
     %SNMP::Info::IPv6::FUNCS,
+    %SNMP::Info::LLDP::FUNCS,
 
     # Obsolete Address Translation Table (ARP Cache)
     'old_at_index'   => 'atIfIndex',
@@ -150,6 +155,7 @@ $VERSION = '3.20';
     %SNMP::Info::Entity::MUNGE,
     %SNMP::Info::PowerEthernet::MUNGE,
     %SNMP::Info::IPv6::MUNGE,
+    %SNMP::Info::LLDP::MUNGE,
     'old_at_paddr' => \&SNMP::Info::munge_mac,
     'at_paddr'     => \&SNMP::Info::munge_mac,
     'n2p_paddr'    => \&SNMP::Info::munge_mac,
@@ -185,23 +191,6 @@ sub root_ip {
     return;
 }
 
-sub i_ignore {
-    my $l3      = shift;
-    my $partial = shift;
-
-    my $interfaces = $l3->interfaces($partial) || {};
-
-    my %i_ignore;
-    foreach my $if ( keys %$interfaces ) {
-
-        # lo -> cisco aironet 350 loopback
-        if ( $interfaces->{$if} =~ /(tunnel|loopback|\blo\b|null)/i ) {
-            $i_ignore{$if}++;
-        }
-    }
-    return \%i_ignore;
-}
-
 sub serial {
     my $l3 = shift;
 
@@ -427,6 +416,8 @@ after determining a more specific class using the method above.
 
 =item SNMP::Info::IPv6
 
+=item SNMP::Info::LLDP
+
 =back
 
 =head2 Required MIBs
@@ -455,6 +446,8 @@ See L<SNMP::Info::PowerEthernet/"Required MIBs"> for its MIB requirements.
 
 See L<SNMP::Info::IPv6/"Required MIBs"> for its MIB requirements.
 
+See L<SNMP::Info::LLDP/"Required MIBs"> for its MIB requirements.
+
 =head1 GLOBALS
 
 These are methods that return scalar value from SNMP
@@ -528,6 +521,18 @@ See L<SNMP::Info::EtherLike/"GLOBALS"> for details.
 
 See L<SNMP::Info::Entity/"GLOBALS"> for details.
 
+=head2 Global Methods imported from SNMP::Info:PowerEthernet
+
+See L<SNMP::Info::PowerEthernet/"GLOBALS"> for details.
+
+=head2 Global Methods imported from SNMP::Info::IPv6
+
+See L<SNMP::Info::IPv6/"GLOBALS"> for details.
+
+=head2 Global Methods imported from SNMP::Info::LLDP
+
+See L<SNMP::Info::LLDP/"GLOBALS"> for details.
+
 =head1 TABLE METHODS
 
 These are methods that return tables of information in the form of a reference
@@ -544,12 +549,6 @@ name.
 
 Only returns those iids that have a description listed in $l3->i_description()
 
-=item $l3->i_ignore()
-
-Returns reference to hash.  Creates a key for each IID that should be ignored.
-
-Currently looks for tunnel,loopback,lo,null from $l3->interfaces()
-
 =item $l3->i_name()
 
 Returns reference to hash of iid to human set name. 
@@ -803,4 +802,8 @@ See L<SNMP::Info::PowerEthernet/"TABLE METHODS"> for details.
 
 See L<SNMP::Info::IPv6/"TABLE METHODS"> for details.
 
+=head2 Table Methods imported from SNMP::Info::LLDP
+
+See L<SNMP::Info::LLDP/"TABLE METHODS"> for details.
+
 =cut
diff --git a/Info/Layer3/Aironet.pm b/Info/Layer3/Aironet.pm
index da34e92..b0923f1 100644
--- a/Info/Layer3/Aironet.pm
+++ b/Info/Layer3/Aironet.pm
@@ -41,7 +41,7 @@ use SNMP::Info::Layer3;
 
 use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::MIBS,
diff --git a/Info/Layer3/AlcatelLucent.pm b/Info/Layer3/AlcatelLucent.pm
index 0e85e2e..c17dd8f 100644
--- a/Info/Layer3/AlcatelLucent.pm
+++ b/Info/Layer3/AlcatelLucent.pm
@@ -49,7 +49,7 @@ use SNMP::Info::LLDP;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::MIBS,
diff --git a/Info/Layer3/AlteonAD.pm b/Info/Layer3/AlteonAD.pm
index 9b733d1..420f8dd 100644
--- a/Info/Layer3/AlteonAD.pm
+++ b/Info/Layer3/AlteonAD.pm
@@ -39,7 +39,7 @@ use SNMP::Info::Layer3;
 
 use vars qw/$VERSION %GLOBALS %FUNCS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::MIBS,
@@ -385,6 +385,20 @@ sub i_vlan_membership {
     return $i_vlan_membership;
 }
 
+sub i_vlan_membership_untagged {
+    my $alteon  = shift;
+    my $partial = shift;
+
+    my $vlans = $alteon->i_vlan($partial);
+    my $i_vlan_membership = {};
+    foreach my $port (keys %$vlans) {
+        my $vlan = $vlans->{$port};
+        push( @{ $i_vlan_membership->{$port} }, $vlan );
+    }
+    
+    return $i_vlan_membership;
+}
+
 # Bridge MIB does not map Bridge Port to ifIndex correctly on some code
 # versions
 sub bp_index {
@@ -574,6 +588,12 @@ IDs.  These are the VLANs which are members of the egress list for the port.
     print "Port: $port VLAN: $vlan\n";
   }
 
+=item $alteon->i_vlan_membership_untagged()
+
+Returns reference to hash of arrays: key = C<ifIndex>, value = array of VLAN
+IDs.  These are the VLANs which are members of the untagged egress list for
+the port.
+
 =item $alteon->v_index()
 
 Returns VLAN IDs
diff --git a/Info/Layer3/Altiga.pm b/Info/Layer3/Altiga.pm
index 4d86572..acc75ef 100644
--- a/Info/Layer3/Altiga.pm
+++ b/Info/Layer3/Altiga.pm
@@ -40,7 +40,7 @@ use SNMP::Info::Layer3;
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE 
             $int_include_vpn $fake_idx $type_class/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
             %SNMP::Info::Layer3::MIBS,
diff --git a/Info/Layer3/Arista.pm b/Info/Layer3/Arista.pm
index c061972..5647d5c 100644
--- a/Info/Layer3/Arista.pm
+++ b/Info/Layer3/Arista.pm
@@ -48,7 +48,7 @@ use SNMP::Info::Aggregate;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::MIBS,
diff --git a/Info/Layer3/Aruba.pm b/Info/Layer3/Aruba.pm
index caf697c..aacc10f 100644
--- a/Info/Layer3/Aruba.pm
+++ b/Info/Layer3/Aruba.pm
@@ -40,7 +40,7 @@ use SNMP::Info::LLDP;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::MIBS,
@@ -124,6 +124,8 @@ $VERSION = '3.20';
     'aruba_ap_model'  => 'wlanAPModelName',
     'aruba_ap_name'   => 'wlanAPName',
     'aruba_ap_ip'     => 'wlanAPIpAddress',
+    'aruba_ap_hw_ver' => 'wlanAPHwVersion',
+    'aruba_ap_sw_ver' => 'wlanAPSwVersion',
 
     # WLSX-WLAN-MIB::wlsxWlanESSIDVlanPoolTable
     'aruba_ssid_vlan' => 'wlanESSIDVlanPoolStatus',
@@ -484,6 +486,7 @@ sub i_vlan {
 	return $aruba->SUPER::i_vlan($partial)
 		if keys %{ $aruba->SUPER::i_vlan($partial) };
 
+	# If we don't have Q-BRIDGE-MIB, we're a wireless controller
 	my $index = $aruba->aruba_if_idx();
 
 	if ($partial) {
@@ -512,6 +515,7 @@ sub i_vlan_membership {
 	return $aruba->SUPER::i_vlan_membership($partial)
 		if keys %{ $aruba->SUPER::i_vlan_membership($partial) };
 
+	# If we don't have Q-BRIDGE-MIB, we're a wireless controller
 	my $essid_ssid = $aruba->aruba_ap_bssid_ssid();
 	my $ssid_vlans = $aruba->aruba_ssid_vlan();
 	my $if_vlans   = $aruba->aruba_if_vlan_member();
@@ -555,6 +559,32 @@ sub i_vlan_membership {
 	return $i_vlan_membership;
 }
 
+sub i_vlan_membership_untagged {
+	my $aruba   = shift;
+	my $partial = shift;
+
+	return $aruba->SUPER::i_vlan_membership_untagged($partial)
+		if keys %{ $aruba->SUPER::i_vlan_membership_untagged($partial) };
+
+	# If we don't have Q-BRIDGE-MIB, we're a wireless controller
+	# It is unclear if native VLAN is transmitted untagged
+	# This assumes Cisco-like behavior on trunks that native VLAN is
+	# transmitted untagged, if this needs to be changed we will need to
+	# consider ifExtMode rather than just using i_vlan
+	my $if_membership = $aruba->i_vlan_membership();
+	my $if_ = $aruba->i_vlan();
+	my $if_mode   = $aruba->aruba_if_mode();
+
+    my $vlans = $aruba->i_vlan($partial);
+    my $i_vlan_membership = {};
+    foreach my $port (keys %$vlans) {
+        my $vlan = $vlans->{$port};
+        push( @{ $i_vlan_membership->{$port} }, $vlan );
+    }
+
+    return $i_vlan_membership;
+}
+
 sub i_80211channel {
     my $aruba   = shift;
     my $partial = shift;
@@ -995,8 +1025,9 @@ sub e_type {
 sub e_hwver {
     my $aruba = shift;
 
-    my $ap_hw   = $aruba->aruba_card_hw()   || {};
-    my $ap_fpga = $aruba->aruba_card_fpga() || {};
+    my $ap_hw     = $aruba->aruba_card_hw()   || {};
+    my $ap_fpga   = $aruba->aruba_card_fpga() || {};
+    my $ap_hw_ver = $aruba->aruba_ap_hw_ver() || {};
 
     my %e_hwver;
 
@@ -1008,9 +1039,36 @@ sub e_hwver {
 
 	$e_hwver{$iid} = "$hw $fpga";
     }
+
+    # APs
+    foreach my $idx ( keys %$ap_hw_ver ) {
+	my $hw_ver = $ap_hw_ver->{$idx};
+	next unless defined $hw_ver;
+
+	$e_hwver{$idx} = "$hw_ver";
+    }
+
     return \%e_hwver;
 }
 
+sub e_swver {
+    my $aruba = shift;
+
+    my $ap_sw_ver = $aruba->aruba_ap_hw_ver() || {};
+
+    my %e_swver;
+
+    # APs
+    foreach my $idx ( keys %$ap_sw_ver ) {
+	my $sw_ver = $ap_sw_ver->{$idx};
+	next unless defined $sw_ver;
+
+	$e_swver{$idx} = "$sw_ver";
+    }
+
+    return \%e_swver;
+}
+
 sub e_vendor {
     my $aruba = shift;
 
@@ -1586,6 +1644,12 @@ Returns reference to map of IIDs to VLAN ID of the interface.
 Returns reference to hash of arrays: key = C<ifIndex>, value = array of VLAN
 IDs.  These are the VLANs for which the port is a member.
 
+=item $aruba->i_vlan_membership_untagged()
+
+Returns reference to hash of arrays: key = C<ifIndex>, value = array of VLAN
+IDs.  These are the VLANs which are members of the untagged egress list for
+the port.
+
 =item $aruba->bp_index()
 
 Augments the bridge MIB by returning reference to a hash containing the
@@ -1648,6 +1712,10 @@ Returns reference to hash.  Key: IID, Value: Type of component.
 
 Returns reference to hash.  Key: IID, Value: Hardware revision.
 
+=item $aruba->e_swver()
+
+Returns reference to hash.  Key: IID, Value: Software revision.
+
 =item $aruba->e_vendor()
 
 Returns reference to hash.  Key: IID, Value: aruba.
diff --git a/Info/Layer3/BayRS.pm b/Info/Layer3/BayRS.pm
index 6d08666..782045d 100644
--- a/Info/Layer3/BayRS.pm
+++ b/Info/Layer3/BayRS.pm
@@ -43,7 +43,7 @@ use SNMP::Info::Bridge;
 use vars qw/$VERSION %GLOBALS %FUNCS %MIBS %MUNGE %MODEL_MAP
     %MODID_MAP %PROCID_MAP/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::MIBS,
@@ -732,6 +732,8 @@ sub i_vlan {
     return \%i_vlan;
 }
 
+sub i_pvid { goto &i_vlan }
+
 sub root_ip {
     my $bayrs = shift;
 
@@ -1549,6 +1551,10 @@ interfaces.
 
 Returns reference to hash.  Maps port VLAN ID to IIDs.
 
+=item $bayrs->i_pvid()
+
+Returns reference to hash.  Maps port VLAN ID to IIDs.
+
 =back
 
 =head2 Pseudo F<ENTITY-MIB> information
diff --git a/Info/Layer3/BlueCoatSG.pm b/Info/Layer3/BlueCoatSG.pm
index 684c2f7..a74109e 100644
--- a/Info/Layer3/BlueCoatSG.pm
+++ b/Info/Layer3/BlueCoatSG.pm
@@ -36,7 +36,7 @@ use SNMP::Info::Layer3;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer2::MIBS, %SNMP::Info::Layer3::MIBS,
diff --git a/Info/Layer3/C3550.pm b/Info/Layer3/C3550.pm
index 5a4df8c..03b2723 100644
--- a/Info/Layer3/C3550.pm
+++ b/Info/Layer3/C3550.pm
@@ -47,7 +47,7 @@ use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
 @SNMP::Info::Layer3::C3550::EXPORT_OK = qw//;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 # NOTE: Order creates precedence
 #       Example: v_name exists in Bridge.pm and CiscoVTP.pm
diff --git a/Info/Layer3/C4000.pm b/Info/Layer3/C4000.pm
index f263dab..836526b 100644
--- a/Info/Layer3/C4000.pm
+++ b/Info/Layer3/C4000.pm
@@ -44,7 +44,7 @@ use SNMP::Info::MAU;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::MAU::MIBS,
diff --git a/Info/Layer3/C6500.pm b/Info/Layer3/C6500.pm
index 565a2a3..c0e888f 100644
--- a/Info/Layer3/C6500.pm
+++ b/Info/Layer3/C6500.pm
@@ -51,7 +51,7 @@ use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 # NOTE: Order creates precedence
 #       Example: v_name exists in Bridge.pm and CiscoVTP.pm
diff --git a/Info/Layer3/Cisco.pm b/Info/Layer3/Cisco.pm
index 7e72bee..ef8ca6c 100644
--- a/Info/Layer3/Cisco.pm
+++ b/Info/Layer3/Cisco.pm
@@ -55,7 +55,7 @@ use SNMP::Info::Layer3;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::MIBS,
@@ -136,6 +136,13 @@ sub i_vlan {
     return $i_vlan;
 }
 
+sub cisco_comm_indexing { 
+    my $cisco = shift;
+    # If we get a VTP version, it's *extremely* likely that the device needs community based indexing
+    my $vtp = $cisco->vtp_version() || '0';
+    return ($vtp ne '0');
+}
+
 1;
 __END__
 
@@ -237,6 +244,11 @@ These are methods that return scalar value from SNMP
 
 (C<cEigrpAsRouterId>)
 
+=item $switch->cisco_comm_indexing()
+
+Returns 1 when the device is likely to need vlan indexing.
+Determined by checking C<vtpVersion>.
+
 =back
 
 =head2 Global Methods imported from SNMP::Info::CiscoVTP
diff --git a/Info/Layer3/CiscoASA.pm b/Info/Layer3/CiscoASA.pm
index 30907d5..a13304f 100644
--- a/Info/Layer3/CiscoASA.pm
+++ b/Info/Layer3/CiscoASA.pm
@@ -45,7 +45,7 @@ use SNMP::Info::Layer3;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = ( %SNMP::Info::Layer3::MIBS, %SNMP::Info::CiscoStats::MIBS, );
 
diff --git a/Info/Layer3/CiscoFWSM.pm b/Info/Layer3/CiscoFWSM.pm
index 7ee3a8b..9eca95f 100644
--- a/Info/Layer3/CiscoFWSM.pm
+++ b/Info/Layer3/CiscoFWSM.pm
@@ -43,7 +43,7 @@ use SNMP::Info::Layer3;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = ( %SNMP::Info::Layer3::MIBS, %SNMP::Info::CiscoStats::MIBS, );
 
diff --git a/Info/Layer3/CiscoSwitch.pm b/Info/Layer3/CiscoSwitch.pm
index 007bb22..db355f8 100644
--- a/Info/Layer3/CiscoSwitch.pm
+++ b/Info/Layer3/CiscoSwitch.pm
@@ -50,7 +50,7 @@ use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::Cisco::MIBS,
diff --git a/Info/Layer3/Contivity.pm b/Info/Layer3/Contivity.pm
index 3cbd12a..ecac54f 100644
--- a/Info/Layer3/Contivity.pm
+++ b/Info/Layer3/Contivity.pm
@@ -42,7 +42,7 @@ use SNMP::Info::Entity;
 
 use vars qw/$VERSION %GLOBALS %FUNCS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::MIBS, %SNMP::Info::Layer3::MIBS, %SNMP::Info::Entity::MIBS,
diff --git a/Info/Layer3/Dell.pm b/Info/Layer3/Dell.pm
index 5f322e3..defc3e1 100644
--- a/Info/Layer3/Dell.pm
+++ b/Info/Layer3/Dell.pm
@@ -40,7 +40,7 @@ use SNMP::Info::LLDP;
 
 use vars qw/$VERSION %GLOBALS %FUNCS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::MIBS,
@@ -153,6 +153,48 @@ sub serial {
     return $dell->SUPER::serial();
 }
 
+# check all fans, and report overall status
+sub fan {
+    my $dell = shift;
+
+    my $fan   = $dell->dell_fan_desc()  || {};
+    my $state = $dell->dell_fan_state() || {};
+    my @messages = ();
+
+    foreach my $k (keys %$fan) {
+        next if $state->{$k} and $state->{$k} eq 'normal';
+        push @messages, "$fan->{$k}: $state->{$k}";
+    }
+
+    push @messages, ((scalar keys %$fan). " fans OK")
+      if scalar @messages == 0;
+
+    return (join ", ", @messages);
+}
+
+sub _ps_status {
+    my ($dell, $unit) = @_;
+
+    my $status = 'unknown';
+    return $status if !defined $unit;
+
+    my $desc  = $dell->dell_pwr_desc()  || {};
+    my $state = $dell->dell_pwr_state() || {};
+
+    foreach my $k (keys %$desc) {
+        next unless $desc->{$k} and $desc->{$k} eq "ps1_unit$unit";
+        return ($state->{$k} || $status);
+    }
+
+    return $status;
+}
+
+sub ps1_type { return 'internalRedundant' }
+sub ps2_type { return 'internalRedundant' }
+
+sub ps1_status { return (shift)->_ps_status(1) }
+sub ps2_status { return (shift)->_ps_status(2) }
+
 sub interfaces {
     my $dell    = shift;
     my $partial = shift;
@@ -213,6 +255,10 @@ sub _vendor {
     }
 }
 
+# dot1qTpFdbTable uses dot1qVlanIndex rather than dot1qFdbId as index,
+# so pretend we don't have the mapping
+sub qb_fdb_index {return}
+
 1;
 __END__
 
@@ -308,6 +354,26 @@ id().  Defaults to 'dlink'.
 Returns 'dell', 'dlink', or 'ibm' based upon the IANA enterprise number in
 id().  Defaults to 'dlink'.
 
+=item $dell->fan()
+
+Return the status of all fans from the F<Dell-Vendor-MIB>
+
+=item $dell->ps1_type()
+
+Return the type of the first power supply from the F<Dell-Vendor-MIB>
+
+=item $dell->ps2_type()
+
+Return the type of the second power supply from the F<Dell-Vendor-MIB>
+
+=item $dell->ps1_status()
+
+Return the status of the first power supply from the F<Dell-Vendor-MIB>
+
+=item $dell->ps2_status()
+
+Return the status of the second power supply from the F<Dell-Vendor-MIB>
+
 =back
 
 =head2 Overrides
@@ -387,6 +453,10 @@ sometimes not unique.
 Returns reference to hash of iid to current link administrative duplex
 setting.
 
+=item $dell->qb_fdb_index()
+
+Returns nothing to work around incorrect indexing of C<dot1qTpFdbTable>
+
 =back
 
 =head2 Table Methods imported from SNMP::Info::Layer3
diff --git a/Info/Layer3/Enterasys.pm b/Info/Layer3/Enterasys.pm
index e4b8983..d289016 100644
--- a/Info/Layer3/Enterasys.pm
+++ b/Info/Layer3/Enterasys.pm
@@ -44,7 +44,7 @@ use SNMP::Info::Layer3;
 
 use vars qw/$VERSION $DEBUG %GLOBALS %FUNCS $INIT %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::MIBS, %SNMP::Info::CDP::MIBS,
@@ -149,11 +149,47 @@ sub i_duplex_admin {
     return $enterasys->mau_i_duplex_admin($partial);
 }
 
-#  LLDP table timefilter implementation continuously increments when walked
+#  TimeFilter implementation continuously increments when walked
 #  and we may never reach the end of the table.  This behavior can be
 #  modified with the "set snmp timefilter break disable" command,
 #  unfortunately it is not the default.  Query with a partial value of zero
-#  which means no time filter.
+#  which means no time filter for tables with and index containing a
+#  TimeFilter
+
+sub qb_fdb_index {
+    my $bridge  = shift;
+
+    my $qb_fdb_ids = $bridge->dot1qVlanFdbId(0) || {};
+
+    # Strip the TimeFilter
+    my $vl_fdb_index = {};
+    for my $fdb_entry (keys(%$qb_fdb_ids)) {
+        (my $vlan = $fdb_entry) =~ s/^\d+\.//;
+        $vl_fdb_index->{$qb_fdb_ids->{$fdb_entry}} = $vlan;
+    }
+
+    return $vl_fdb_index;
+}
+
+sub i_vlan_membership {
+    my $bridge  = shift;
+    my $partial = shift;
+
+    # dot1qVlanCurrentTable TimeFilter index
+    my $v_ports = $bridge->qb_cv_egress(0) || $bridge->qb_v_egress();
+
+    return $bridge->_vlan_hoa($v_ports, $partial);
+}
+
+sub i_vlan_membership_untagged {
+    my $bridge  = shift;
+    my $partial = shift;
+
+    # dot1qVlanCurrentTable TimeFilter index
+    my $v_ports = $bridge->qb_cv_untagged(0) || $bridge->qb_v_untagged();
+
+    return $bridge->_vlan_hoa($v_ports, $partial);
+}
 
 sub lldp_ip {
     my $enterasys = shift;
@@ -359,9 +395,9 @@ L<SNMP::Info::MAU/"TABLE METHODS">.
 
 =back
 
-=head2 Link Layer Discovery Protocol (LLDP) Overrides
+=head2 Time Filter Table Index Overrides
 
-The LLDP table time filter implementation continuously increments when
+The time filter C<TimeFilter> implementation continuously increments when
 walked and we may never reach the end of the table.  This behavior can be
 modified with the C<"set snmp timefilter break disable"> command,
 unfortunately it is not the default.  These methods are overridden to
@@ -369,6 +405,12 @@ supply a partial value of zero which means no time filter.
 
 =over
 
+=item $enterasys->qb_fdb_index()
+
+=item $enterasys->i_vlan_membership()
+
+=item $enterasys->i_vlan_membership_untagged()
+
 =item $enterasys->lldp_if()
 
 =item $enterasys->lldp_ip()
diff --git a/Info/Layer3/Extreme.pm b/Info/Layer3/Extreme.pm
index 0332ce3..93f4578 100644
--- a/Info/Layer3/Extreme.pm
+++ b/Info/Layer3/Extreme.pm
@@ -46,18 +46,19 @@ use SNMP::Info::EDP;
 
 use vars qw/$VERSION %GLOBALS %FUNCS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::MIBS,
     %SNMP::Info::MAU::MIBS,
     %SNMP::Info::LLDP::MIBS,
     %SNMP::Info::EDP::MIBS,
-    'EXTREME-BASE-MIB'   => 'extremeAgent',
-    'EXTREME-SYSTEM-MIB' => 'extremeSystem',
-    'EXTREME-FDB-MIB'    => 'extremeSystem',
-    'EXTREME-VLAN-MIB'   => 'extremeVlan',
-    'EXTREME-POE-MIB'    => 'extremePethSystemAdminEnable',
+    'EXTREME-BASE-MIB'           => 'extremeAgent',
+    'EXTREME-SYSTEM-MIB'         => 'extremeSystem',
+    'EXTREME-FDB-MIB'            => 'extremeFdbMacFdbMacAddress',
+    'EXTREME-VLAN-MIB'           => 'extremeVlan',
+    'EXTREME-POE-MIB'            => 'extremePethSystemAdminEnable',
+    'EXTREME-STP-EXTENSIONS-MIB' => 'extremeStpDomainBridgeId',
 );
 
 %GLOBALS = (
@@ -97,6 +98,20 @@ $VERSION = '3.20';
     'peth_power_watts'  => 'extremePethSlotPowerLimit',
     # EXTREME-POE-MIB::extremePethPsePortTable
     'peth_port_power'   => 'extremePethPortMeasuredPower',
+    # EXTREME-STP-EXTENSIONS-MIB::extremeStpDomainTable
+    'stp_i_time'      => 'extremeStpDomainTimeSinceTopologyChange',
+    'stp_i_ntop'      => 'extremeStpDomainTopChanges',
+    'stp_i_root'      => 'extremeStpDomainDesignatedRoot',
+    'stp_i_root_port' => 'extremeStpDomainRootPortIfIndex',
+    'stp_i_priority'  => 'extremeStpDomainBridgePriority',
+    'ex_stp_i_mac'    => 'extremeStpDomainBridgeId',
+    # EXTREME-STP-EXTENSIONS-MIB::extremeStpPortTable
+    'stp_p_priority' => 'extremeStpPortPortPriority',
+    'stp_p_state'    => 'extremeStpPortPortState',
+    'stp_p_cost'     => 'extremeStpPortPathCost',
+    'stp_p_root'     => 'extremeStpPortDesignatedRoot',
+    'stp_p_bridge'   => 'extremeStpPortDesignatedBridge',
+    'stp_p_port'     => 'extremeStpPortDesignatedPort',
 );
 
 %MUNGE = (
@@ -114,6 +129,11 @@ $VERSION = '3.20';
     'fan_state'        => \&munge_true_ok,
     'ex_vlan_untagged' => \&SNMP::Info::munge_port_list,
     'ex_vlan_tagged'   => \&SNMP::Info::munge_port_list,
+    'ex_stp_i_mac'     => \&SNMP::Info::munge_prio_mac,
+    'stp_i_root'       => \&SNMP::Info::munge_prio_mac,
+    'stp_p_root'       => \&SNMP::Info::munge_prio_mac,
+    'stp_p_bridge'     => \&SNMP::Info::munge_prio_mac,
+    'stp_p_port'       => \&SNMP::Info::munge_prio_port,
 );
 
 # Method OverRides
@@ -542,6 +562,78 @@ sub _extremeware_i_vlan_membership {
     return \%i_vlan_membership;
 }
 
+sub i_vlan_membership_untagged {
+    my $extreme = shift;
+    my $partial = shift;
+
+    # Some devices support Q-Bridge, if so short circuit and return it
+    my $q_bridge = $extreme->SUPER::i_vlan_membership_untagged($partial);
+    return $q_bridge if (ref {} eq ref $q_bridge and scalar keys %$q_bridge);
+
+    # Next we try extremeVlanOpaqueTable
+    my $xos = $extreme->_xos_i_vlan_membership_untagged($partial);
+    return $xos if (ref {} eq ref $xos and scalar keys %$xos);
+    
+    # Try older ifStack method
+    my $extremeware = $extreme->_extremeware_i_vlan_membership_untagged($partial);
+    return $extremeware if (ref {} eq ref $extremeware and scalar keys %$extremeware);
+    
+    return;
+}
+
+sub _xos_i_vlan_membership_untagged {
+    my $extreme = shift;
+    my $partial = shift;
+
+    my $index   = $extreme->i_index();
+    my $vlans   = $extreme->ex_vlan_id();
+    my $slotx   = $extreme->_slot_factor() || 1000;
+    my $u_ports = $extreme->ex_vlan_untagged() || {};
+
+    my $i_vlan_membership = {};
+    foreach my $idx ( keys %$u_ports ) {
+        next unless ( defined $u_ports->{$idx} );
+        my $u_portlist = $u_ports->{$idx};
+        my $ret        = [];
+
+        my ( $vlan_if, $slot ) = $idx =~ /^(\d+)\.(\d+)/;
+        my $vlan = $vlans->{$vlan_if} || '';
+
+        foreach my $portlist ( $u_portlist ) {
+
+            # Convert portlist bit array to bp_index array
+            for ( my $i = 0; $i <= $#$portlist; $i++ ) {
+                push( @{$ret}, ( $slotx * $slot + $i + 1 ) )
+                    if ( @$portlist[$i] );
+            }
+        }
+
+        #Create HoA ifIndex -> VLAN array
+        foreach my $port ( @{$ret} ) {
+            my $ifindex = $index->{$port};
+            next unless ( defined($ifindex) );    # shouldn't happen
+            next if ( defined $partial and $ifindex !~ /^$partial$/ );
+            push( @{ $i_vlan_membership->{$ifindex} }, $vlan );
+        }
+    }
+    return $i_vlan_membership;
+}
+
+# Assuming Cisco-like trunk behavior that native VLAN is transmitted untagged
+sub _extremeware_i_vlan_membership_untagged {
+    my $extreme  = shift;
+    my $partial = shift;
+
+    my $vlans = $extreme->_extremeware_i_vlan($partial);
+    my $i_vlan_membership = {};
+    foreach my $port (keys %$vlans) {
+        my $vlan = $vlans->{$port};
+        push( @{ $i_vlan_membership->{$port} }, $vlan );
+    }
+
+    return $i_vlan_membership;
+}
+
 # VLAN management.
 # See extreme-vlan.mib for a detailed description of
 # Extreme's use of ifStackTable and EXTREME-VLAN-MIB.
@@ -711,6 +803,75 @@ sub lldp_if {
     return \%lldp_if;
 }
 
+# extremeStpDomainStpdInstance not accessible, so we need to extract from iid
+sub stp_i_id {
+    my $extreme  = shift;
+    my $partial  = shift;
+
+    my $stp_i_roots = $extreme->stp_i_root($partial);
+
+    my %stp_i_id;
+    foreach my $iid ( keys %$stp_i_roots ) {
+        $stp_i_id{$iid} = $iid;
+    }
+    return \%stp_i_id;
+}
+
+# extremeStpDomainBridgeId returns priority and mac,
+# for cross class compatibility we just need mac
+sub stp_i_mac {
+    my $extreme  = shift;
+    my $partial  = shift;
+
+    my $stp_i_bids = $extreme->ex_stp_i_mac($partial);
+
+    my %stp_i_mac;
+    foreach my $iid ( keys %$stp_i_bids ) {
+        my $mac = $stp_i_bids->{$iid};
+        next unless $mac;
+        
+        $mac =~ s/^([0-9A-F][0-9A-F]:){2}//;
+        
+        $stp_i_mac{$iid} = $mac;
+    }
+    return \%stp_i_mac;
+}
+
+# Break up the extremeStpPortEntry INDEX into Stpd Instance and IfIndex.
+sub _ex_stpport_index {
+    my $idx    = shift;
+    my ( $id, $ifindex ) = split( /\./, $idx);
+    return ($id, $ifindex);
+}
+
+# extremeStpPortPortIfIndex not-accessible, extract from iid
+sub stp_p_id {
+    my $extreme  = shift;
+    my $partial  = shift;
+
+    my $stp_port = $extreme->stp_p_root($partial);
+    my $stp_p_id  = {};
+    foreach my $idx ( keys %$stp_port ) {
+        my ( $id, $ifindex ) = _ex_stpport_index($idx);
+        $stp_p_id->{$idx} = $ifindex;
+    }
+    return $stp_p_id;
+}
+
+# extremeStpDomainStpdInstance not-accessible, extract from iid
+sub stp_p_stg_id {
+    my $extreme  = shift;
+    my $partial  = shift;
+
+    my $stp_port = $extreme->stp_p_root($partial);
+    my $stp_p_stg_id  = {};
+    foreach my $idx ( keys %$stp_port ) {
+        my ( $id, $ifindex ) = _ex_stpport_index($idx);
+        $stp_p_stg_id->{$idx} = $id;
+    }
+    return $stp_p_stg_id;
+}
+
 1;
 
 __END__
@@ -927,6 +1088,12 @@ IDs.  These are the VLANs which are members of the egress list for the port.
     print "Port: $port VLAN: $vlan\n";
   }
 
+=item $extreme->i_vlan_membership_untagged()
+
+Returns reference to hash of arrays: key = C<ifIndex>, value = array of VLAN
+IDs.  These are the VLANs which are members of the untagged egress list for
+the port.
+
 =item $extreme->v_index()
 
 Returns VLAN IDs
@@ -959,6 +1126,98 @@ The configured maximum amount of in-line power available to the slot.
 
 =back
 
+=head2 Spanning Tree Instance Globals
+
+=over
+
+=item $extreme->stp_i_mac()
+
+Returns the MAC extracted from (C<extremeStpDomainBridgeId>).
+
+=item $extreme->stp_i_id()
+
+Returns the unique identifier of the STP domain.
+
+(C<extremeStpDomainStpdInstance>)
+
+=item $extreme->stp_i_time()
+
+Returns time since last topology change detected. (100ths/second)
+
+(C<extremeStpDomainTimeSinceTopologyChange>)
+
+=item $extreme->stp_i_time()
+
+Returns time since last topology change detected. (100ths/second)
+
+(C<extremeStpDomainTimeSinceTopologyChange>)
+
+=item $extreme->stp_i_time()
+
+Returns the total number of topology changes detected.
+
+(C<extremeStpDomainTopChanges>)
+
+=item $extreme->stp_i_root()
+
+Returns root of STP.
+
+(C<extremeStpDomainDesignatedRoot>)
+
+=item $extreme->stp_i_root_port()
+
+Returns the port number of the port that offers the lowest cost path
+to the root bridge.
+
+(C<extremeStpDomainRootPortIfIndex>)
+
+=item $extreme->stp_i_priority()
+
+Returns the port number of the port that offers the lowest cost path
+to the root bridge.
+
+(C<extremeStpDomainBridgePriority>)
+
+=back
+
+=head2 Spanning Tree Protocol Port Table
+
+=over
+
+=item $extreme->stp_p_id()
+
+(C<extremeStpPortPortIfIndex>)
+
+=item $extreme->stp_p_stg_id()
+
+(C<extremeStpDomainStpdInstance>)
+
+=item $extreme->stp_p_priority()
+
+(C<extremeStpPortPortPriority>)
+
+=item $extreme->stp_p_state()
+
+(C<extremeStpPortPortState>)
+
+=item $extreme->stp_p_cost()
+
+(C<extremeStpPortPathCost>)
+
+=item $extreme->stp_p_root()
+
+(C<extremeStpPortDesignatedRoot>)
+
+=item $extreme->stp_p_bridge()
+
+(C<extremeStpPortDesignatedBridge>)
+
+=item $extreme->stp_p_port()
+
+(C<extremeStpPortDesignatedPort>)
+
+=back
+
 =head2 Table Methods imported from SNMP::Info::Layer3
 
 See documentation in L<SNMP::Info::Layer3/"TABLE METHODS"> for details.
diff --git a/Info/Layer3/F5.pm b/Info/Layer3/F5.pm
index b4f1960..5b09366 100644
--- a/Info/Layer3/F5.pm
+++ b/Info/Layer3/F5.pm
@@ -38,7 +38,7 @@ use SNMP::Info::Layer3;
 
 use vars qw/$VERSION %GLOBALS %FUNCS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::MIBS,
@@ -255,6 +255,37 @@ sub i_vlan_membership {
     return $i_vlan_membership;
 }
 
+sub i_vlan_membership_untagged {
+    my $f5      = shift;
+    my $partial = shift;
+
+    my $index  = $f5->i_index($partial) || {};
+    my $tagged = $f5->sys_vm_tagged()   || {};
+    my $vlans  = $f5->v_index()         || {};
+
+    my $i_vlan_membership = {};
+    foreach my $iid ( keys %$tagged ) {
+        
+        next unless $tagged->{$iid} eq 'false';
+        # IID is length.vlan name index.length.interface index
+        # Split out and use as the IID to get the VLAN ID and ifIndex
+        my @iid_array = split /\./, $iid;
+        my $len       = $iid_array[0];
+        my $v_idx     = join '.', ( splice @iid_array, 0, $len + 1 );
+        my $idx       = join '.', @iid_array;
+
+        # Check to make sure we can map to a port
+        my $p_idx = $index->{$idx};
+        next unless $p_idx;
+
+        my $vlan = $vlans->{$v_idx};
+        next unless $vlan;
+
+        push( @{ $i_vlan_membership->{$idx} }, $vlan );
+    }
+    return $i_vlan_membership;
+}
+
 1;
 __END__
 
@@ -391,6 +422,12 @@ IDs.
     print "Port: $port VLAN: $vlan\n";
   }
 
+=item $f5->i_vlan_membership_untagged()
+
+Returns reference to hash of arrays: key = C<ifIndex>, value = array of VLAN
+IDs.  These are the VLANs which are members of the untagged egress list for
+the port.
+
 =item $f5->v_index()
 
 Returns VLAN IDs
diff --git a/Info/Layer3/Force10.pm b/Info/Layer3/Force10.pm
index 879f0e5..3c6d6c1 100644
--- a/Info/Layer3/Force10.pm
+++ b/Info/Layer3/Force10.pm
@@ -43,7 +43,7 @@ use SNMP::Info::LLDP;
 
 use vars qw/$VERSION $DEBUG %GLOBALS %MIBS %FUNCS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::MIBS,
@@ -121,29 +121,25 @@ sub i_vlan {
     return $i_vlan;
 }
 
-sub i_vlan_membership {
+# Apparently index doesn't use VLAN ID, so override the HOA private
+# method here to correct the mapping 
+sub _vlan_hoa {
     my $force10 = shift;
-    my $partial = shift;
+    my ( $v_ports, $partial ) = @_;
 
-    my $index = $force10->bp_index();
+    my $index   = $force10->bp_index();
     my $v_index = $force10->v_index();
 
-    my $v_ports  = $force10->qb_v_egress();
-
-    # If given a partial it will be an ifIndex, we need to use dot1dBasePort
-    if ($partial) {
-        my %r_index = reverse %$index;
-        $partial    = $r_index{$partial};
-    }
-
-    my $i_vlan_membership = {};
-
+    my $vlan_hoa = {};
     foreach my $idx ( sort keys %{$v_ports} ) {
         next unless ( defined $v_ports->{$idx} );
         my $portlist = $v_ports->{$idx}; # is an array reference
         my $ret      = [];
         my $vlan_ndx = $idx;
 
+        # Strip TimeFilter if we're using VlanCurrentTable
+        ( $vlan_ndx = $idx ) =~ s/^\d+\.//;
+
         # Convert portlist bit array to bp_index array
         for ( my $i = 0; $i <= $#$portlist; $i++ ) {
             push( @{$ret}, $i + 1 ) if ( @$portlist[$i] );
@@ -160,11 +156,10 @@ sub i_vlan_membership {
             # the mapping from Q-BRIDGE-MIB::dot1qVlanFdbId 
             my $mod = $vlan_tag % 4096;
 
-            push ( @{ $i_vlan_membership->{$ifindex} }, ($mod) );
+            push ( @{ $vlan_hoa->{$ifindex} }, ($mod) );
         }
     }
-
-    return $i_vlan_membership;
+    return $vlan_hoa;
 }
 
 1;
@@ -278,12 +273,6 @@ Returns the VLAN names.
 
 Currently not implemented.
 
-=item $force10->i_vlan_membership()
-
-Returns reference to hash of arrays:
-key = C<ifIndex>, value = array of VLAN IDs.
-These are the VLANs which are members of the egress list for the port.
-
 =item $force10->i_duplex_admin()
 
 Returns info from F<MAU-MIB>
diff --git a/Info/Layer3/Steelhead.pm b/Info/Layer3/Fortinet.pm
similarity index 72%
copy from Info/Layer3/Steelhead.pm
copy to Info/Layer3/Fortinet.pm
index 85d5e88..4466095 100644
--- a/Info/Layer3/Steelhead.pm
+++ b/Info/Layer3/Fortinet.pm
@@ -1,6 +1,6 @@
-# SNMP::Info::Layer3::Steelhead
+# SNMP::Info::Layer3::Fortinet
 #
-# Copyright (c) 2013 Eric Miller
+# Copyright (c) 2014 Eric Miller
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -27,29 +27,28 @@
 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 # POSSIBILITY OF SUCH DAMAGE.
 
-package SNMP::Info::Layer3::Steelhead;
+package SNMP::Info::Layer3::Fortinet;
 
 use strict;
 use Exporter;
 use SNMP::Info::Layer3;
 
- at SNMP::Info::Layer3::Steelhead::ISA
+ at SNMP::Info::Layer3::Fortinet::ISA
     = qw/SNMP::Info::Layer3 Exporter/;
- at SNMP::Info::Layer3::Steelhead::EXPORT_OK = qw//;
+ at SNMP::Info::Layer3::Fortinet::EXPORT_OK = qw//;
 
 use vars qw/$VERSION %GLOBALS %FUNCS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::MIBS,
-    'STEELHEAD-MIB' => 'serialNumber',
+    'FORTINET-CORE-MIB'      => 'fnSysSerial',
+    'FORTINET-FORTIGATE-MIB' => 'fgVdMaxVdoms',
 );
 
 %GLOBALS = (
     %SNMP::Info::Layer3::GLOBALS,
-    # Fully qualified to remove ambiguity of 'model'
-    'rb_model' => 'STEELHEAD-MIB::model',
 );
 
 %FUNCS = (
@@ -60,33 +59,30 @@ $VERSION = '3.20';
     %SNMP::Info::Layer3::MUNGE,
 );
 
-sub layers {
-    return '01001100';
-}
-
 sub vendor {
-    return 'riverbed';
+    return 'fortinet';
 }
 
 sub model {
-    my $riverbed = shift;
+    my $fortinet = shift;
+    my $id = $fortinet->id() || '';
 
-    my $model = $riverbed->rb_model() || '';
-    
-    if ($model =~ /^(\d+)/) {
-        return $1;
-    }
+    my $model = &SNMP::translateObj($id);
+
+    return $id unless defined $model;
+
+    $model =~ s/^f[grsw][tfw]?//i;
     return $model;
 }
 
 sub os {
-    return 'steelhead';
+    return 'fortios';
 }
 
 sub os_ver {
-    my $riverbed = shift;
+    my $fortinet = shift;
     
-    my $ver = $riverbed->systemVersion() || '';
+    my $ver = $fortinet->fgSysVersion() || '';
 
     if ( $ver =~ /(\d+[\.\d]+)/ ) {
         return $1;
@@ -96,9 +92,9 @@ sub os_ver {
 }
 
 sub serial {
-    my $riverbed = shift;
+    my $fortinet = shift;
     
-    return $riverbed->serialNumber();
+    return $fortinet->fnSysSerial();
 }
 
 1;
@@ -106,8 +102,7 @@ __END__
 
 =head1 NAME
 
-SNMP::Info::Layer3::Steelhead - SNMP Interface to Riverbed Steelhead WAN
-optimization appliances.
+SNMP::Info::Layer3::Fortinet - SNMP Interface to Fortinet network devices.
 
 =head1 AUTHOR
 
@@ -116,7 +111,7 @@ Eric Miller
 =head1 SYNOPSIS
 
  # Let SNMP::Info determine the correct subclass for you. 
- my $riverbed = new SNMP::Info(
+ my $fortinet = new SNMP::Info(
                           AutoSpecify => 1,
                           Debug       => 1,
                           DestHost    => 'myswitch',
@@ -125,17 +120,17 @@ Eric Miller
                         ) 
     or die "Can't connect to DestHost.\n";
 
- my $class = $riverbed->class();
+ my $class = $fortinet->class();
  print "SNMP::Info determined this device to fall under subclass : $class\n";
 
 =head1 DESCRIPTION
 
-Abstraction subclass for Riverbed Steelhead WAN optimization appliances.
+Abstraction subclass for Fortinet network devices.
 
 For speed or debugging purposes you can call the subclass directly, but not
 after determining a more specific class using the method above. 
 
- my $riverbed = new SNMP::Info::Layer3::Steelhead(...);
+ my $fortinet = new SNMP::Info::Layer3::Fortinet(...);
 
 =head2 Inherited Classes
 
@@ -147,10 +142,12 @@ after determining a more specific class using the method above.
 
 =head2 Required MIBs
 
-F<STEELHEAD-MIB>
-
 =over
 
+=item F<FORTINET-CORE-MIB>
+
+=item F<FORTINET-FORTIGATE-MIB>
+
 =item Inherited Classes' MIBs
 
 See L<SNMP::Info::Layer3/"Required MIBs"> for its own MIB requirements.
@@ -163,40 +160,27 @@ These are methods that return scalar value from SNMP
 
 =over
 
-=item $riverbed->vendor()
+=item $fortinet->vendor()
 
-Returns 'riverbed'
+Returns 'fortinet'
 
-=item $riverbed->model()
+=item $fortinet->model()
 
 Returns the chassis model.
 
-(C<STEELHEAD-MIB::model>)
-
-=item $riverbed->os()
+=item $fortinet->os()
 
-Returns 'steelhead'
+Returns 'fortios'
 
-=item $riverbed->os_ver()
+=item $fortinet->os_ver()
 
 Returns the software version extracted from (C<systemVersion>).
 
-=item $riverbed->serial()
+=item $fortinet->serial()
 
 Returns the chassis serial number.
 
-(C<serialNumber>)
-
-=back
-
-=head2 Overrides
-
-=over
-
-=item $riverbed->layers()
-
-Returns 01001100.  Steelhead does not support bridge MIB, so override reported
-layers.
+(C<fnSysSerial>)
 
 =back
 
diff --git a/Info/Layer3/Foundry.pm b/Info/Layer3/Foundry.pm
index 8166849..dde12db 100644
--- a/Info/Layer3/Foundry.pm
+++ b/Info/Layer3/Foundry.pm
@@ -48,7 +48,7 @@ use SNMP::Info::LLDP;
 
 use vars qw/$VERSION %GLOBALS %FUNCS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::MIBS,
@@ -97,6 +97,24 @@ $VERSION = '3.20';
     # FOUNDRY-SN-AGENT-MIB::snAgentConfigModuleTable
     'ag_mod_type' => 'snAgentConfigModuleType',
 
+    # FOUNDRY-SN-AGENT-MIB::snVLanByPortTable
+    'stp_i_id'        => 'snVLanByPortVLanId',
+    'stp_i_mac'       => 'snVLanByPortBaseBridgeAddress',
+    'stp_i_time'      => 'snVLanByPortStpTimeSinceTopologyChange',
+    'stp_i_ntop'      => 'snVLanByPortStpTopChanges',
+    'stp_i_root'      => 'snVLanByPortStpDesignatedRoot',
+    'stp_i_root_port' => 'snVLanByPortStpRootPort',
+    'stp_i_priority'  => 'snVLanByPortStpPriority',
+
+    # FOUNDRY-SN-AGENT-MIB::snPortStpTable
+    'stp_p_id'       => 'snPortStpPortNum',
+    'stp_p_stg_id'   => 'snPortStpVLanId',
+    'stp_p_priority' => 'snPortStpPortPriority',
+    'stp_p_state'    => 'snPortStpPortState',
+    'stp_p_cost'     => 'snPortStpPortDesignatedCost',
+    'stp_p_root'     => 'snPortStpPortDesignatedRoot',
+    'stp_p_bridge'   => 'snPortStpPortDesignatedBridge',
+    'stp_p_port'     => 'snPortStpPortDesignatedPort',
 );
 
 %MUNGE = (
@@ -106,6 +124,11 @@ $VERSION = '3.20';
 
     'ag_mod2_type' => \&SNMP::Info::munge_e_type,
     'ag_mod_type'  => \&SNMP::Info::munge_e_type,
+    'stp_i_mac'    => \&SNMP::Info::munge_mac,
+    'stp_i_root'   => \&SNMP::Info::munge_prio_mac,
+    'stp_p_root'   => \&SNMP::Info::munge_prio_mac,
+    'stp_p_bridge' => \&SNMP::Info::munge_prio_mac,
+    'stp_p_port'   => \&SNMP::Info::munge_prio_port,
 );
 
 sub i_ignore {
@@ -277,20 +300,6 @@ sub interfaces {
     return $i_descr;
 }
 
-# Reported hangs on a EdgeIron 24G
-sub stp_p_state {
-    my $foundry = shift;
-    my $partial = shift;
-
-    my $descr = $foundry->description();
-    if ( $descr =~ m/\bEdgeIron 24G\b/ ) {
-        return;
-    }
-
-    return $foundry->SUPER::stp_p_state($partial) || {};
-
-}
-
 # Entity MIB is supported on the Brocade NetIron XMR, NetIron MLX, MLXe,
 # NetIron CES, NetIron CER, and older EdgeIron series devices.
 # Try Entity MIB methods first and fall back to Pseudo ENTITY-MIB methods for
@@ -817,6 +826,26 @@ sub agg_ports {
   return $ret;
 }
 
+sub i_stp_state {
+    my $foundry  = shift;
+    my $partial = shift;
+
+    my $bp_index    = $foundry->bp_index($partial);
+    my $stp_p_state = $foundry->dot1dStpPortState($partial);
+
+    my %i_stp_state;
+
+    foreach my $index ( keys %$stp_p_state ) {
+        my $state = $stp_p_state->{$index};
+        my $iid   = $bp_index->{$index};
+        next unless defined $iid;
+        next unless defined $state;
+        $i_stp_state{$iid} = $state;
+    }
+
+    return \%i_stp_state;
+}
+
 1;
 __END__
 
@@ -1007,14 +1036,10 @@ Returns reference to hash of interface link duplex status.
 
 Crosses $foundry->sw_duplex() with $foundry->sw_index()
 
-=item $foundry->stp_p_state()
-
-"The port's current state as defined by application of the Spanning Tree
-Protocol.
-
-Skipped if device is an EdgeIron 24G due to reports of hangs.
-
-(C<dot1dStpPortState>)
+=item $foundry->i_stp_state()
+ 
+Returns the mapping of (C<dot1dStpPortState>) to the interface
+index (iid).
 
 =item $foundry->agg_ports()
 
diff --git a/Info/Layer3/H3C.pm b/Info/Layer3/H3C.pm
index 68073b2..386f788 100644
--- a/Info/Layer3/H3C.pm
+++ b/Info/Layer3/H3C.pm
@@ -47,7 +47,7 @@ use SNMP::Info::IEEE802dot3ad 'agg_ports_lag';
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::MIBS,
diff --git a/Info/Layer3/HP9300.pm b/Info/Layer3/HP9300.pm
index dac1d50..ecc4db0 100644
--- a/Info/Layer3/HP9300.pm
+++ b/Info/Layer3/HP9300.pm
@@ -42,7 +42,7 @@ use SNMP::Info::LLDP;
 
 use vars qw/$VERSION %GLOBALS %FUNCS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::MIBS,
diff --git a/Info/Layer3/H3C.pm b/Info/Layer3/Huawei.pm
similarity index 68%
copy from Info/Layer3/H3C.pm
copy to Info/Layer3/Huawei.pm
index 68073b2..becceba 100644
--- a/Info/Layer3/H3C.pm
+++ b/Info/Layer3/Huawei.pm
@@ -1,6 +1,6 @@
-# SNMP::Info::Layer3::H3C
+# SNMP::Info::Layer3::Huawei
 #
-# Copyright (c) 2012 Jeroen van Ingen
+# Copyright (c) 2015 Jeroen van Ingen
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 # POSSIBILITY OF SUCH DAMAGE.
 
-package SNMP::Info::Layer3::H3C;
+package SNMP::Info::Layer3::Huawei;
 
 use strict;
 use Exporter;
@@ -35,43 +35,35 @@ use SNMP::Info::Layer3;
 use SNMP::Info::LLDP;
 use SNMP::Info::IEEE802dot3ad 'agg_ports_lag';
 
- at SNMP::Info::Layer3::H3C::ISA = qw/
+ at SNMP::Info::Layer3::Huawei::ISA = qw/
   SNMP::Info::IEEE802dot3ad
   SNMP::Info::LLDP
   SNMP::Info::Layer3
   Exporter
 /;
- at SNMP::Info::Layer3::H3C::EXPORT_OK = qw/
+ at SNMP::Info::Layer3::Huawei::EXPORT_OK = qw/
   agg_ports
 /;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::MIBS,
     %SNMP::Info::LLDP::MIBS,
     %SNMP::Info::IEEE802dot3ad::MIBS,
-    'HH3C-LswDEVM-MIB'     => 'hh3cDevMFanStatus',
-    'HH3C-LswINF-MIB'      => 'hh3cSlotPortMax',
-    'HH3C-LSW-DEV-ADM-MIB' => 'hh3cLswSysVersion',
-    'HH3C-PRODUCT-ID-MIB'  => 'hh3c-s5500-28C-EI',
-    'HH3C-ENTITY-VENDORTYPE-OID-MIB' => 'hh3cevtOther',
+    'HUAWEI-MIB' => 'quidway',
 );
 
 %GLOBALS = (
     %SNMP::Info::Layer3::GLOBALS,
     %SNMP::Info::LLDP::GLOBALS,
-    'fan' => 'hh3cDevMFanStatus.1',
-    'ps1_status' => 'hh3cDevMPowerStatus.1',
-    'ps2_status' => 'hh3cDevMPowerStatus.2',
 );
 
 %FUNCS = (
     %SNMP::Info::Layer3::FUNCS,
     %SNMP::Info::LLDP::FUNCS,
-    i_duplex_admin => 'hh3cifEthernetDuplex',
 );
 
 %MUNGE = (
@@ -80,30 +72,25 @@ $VERSION = '3.20';
 );
 
 sub vendor {
-    my $h3c = shift;
-    my $mfg = $h3c->entPhysicalMfgName(1) || {};
-    return $mfg->{1} || "H3C";
+    return "Huawei";
 }
 
 sub os {
-    my $h3c = shift;
-    my $descr   = $h3c->description();
+    my $huawei = shift;
+    my $descr  = $huawei->description();
 
-    return $1 if ( $descr =~ /(\S+)\s+Platform Software/ );
-    return "H3C";
+    return $1 if ( $descr =~ /\b(VRP)\b/ );
+    return "huawei";
 }
 
 sub os_ver {
-    my $h3c = shift;
-    my $descr   = $h3c->description();
-#    my $version = $h3c->hh3cLswSysVersion(); # Don't use, indicates base version only, no release details
-    my $ver_release = $h3c->entPhysicalSoftwareRev(2) || {};
-    my $os_ver  = undef;
+    my $huawei = shift;
+    my $descr  = $huawei->description();
+    my $os_ver = undef;
 
-    $os_ver = "$1 $2" if ( $descr =~ /Software Version ([^,]+),.*(Release\s\S+)/i );
-    $os_ver = "$1" if ( $descr =~ /Product Version ([0-9.]+)/i );
+    $os_ver = "$1" if ( $descr =~ /\bVersion ([0-9.]+)/i );
 
-    return $ver_release->{2} || $os_ver;
+    return $os_ver;
 }
 
 sub i_ignore {
@@ -116,7 +103,7 @@ sub i_ignore {
     foreach my $if ( keys %$interfaces ) {
 
         # lo0 etc
-        if ( $interfaces->{$if} =~ /\blo\d*\b/i ) {
+        if ( $interfaces->{$if} =~ /\b(inloopback|console)\d*\b/i ) {
             $i_ignore{$if}++;
         }
     }
@@ -130,7 +117,7 @@ __END__
 
 =head1 NAME
 
-SNMP::Info::Layer3::H3C - SNMP Interface to L3 Devices, H3C & HP A-series
+SNMP::Info::Layer3::Huawei - SNMP Interface to Huawei Layer 3 switches and routers.
 
 =head1 AUTHORS
 
@@ -139,7 +126,7 @@ Jeroen van Ingen
 =head1 SYNOPSIS
 
  # Let SNMP::Info determine the correct subclass for you. 
- my $h3c = new SNMP::Info(
+ my $huawei = new SNMP::Info(
                           AutoSpecify => 1,
                           Debug       => 1,
                           DestHost    => 'myrouter',
@@ -148,12 +135,12 @@ Jeroen van Ingen
                         ) 
     or die "Can't connect to DestHost.\n";
 
- my $class      = $h3c->class();
+ my $class      = $huawei->class();
  print "SNMP::Info determined this device to fall under subclass : $class\n";
 
 =head1 DESCRIPTION
 
-Subclass for H3C & HP A-series devices
+Subclass for Huawei Quidway switches
 
 =head2 Inherited Classes
 
@@ -163,21 +150,15 @@ Subclass for H3C & HP A-series devices
 
 =item SNMP::Info::LLDP
 
+=item SNMP::Info::IEEE802dot3ad
+
 =back
 
 =head2 Required MIBs
 
 =over
 
-=item F<HH3C-LswDEVM-MIB>
-
-=item F<HH3C-LswINF-MIB>
-
-=item F<HH3C-LSW-DEV-ADM-MIB>
-
-=item F<HH3C-PRODUCT-ID-MIB>
-
-=item F<HH3C-ENTITY-VENDORTYPE-OID-MIB>
+=item F<HUAWEI-MIB>
 
 =item Inherited Classes' MIBs
 
@@ -185,6 +166,8 @@ See L<SNMP::Info::Layer3> for its own MIB requirements.
 
 See L<SNMP::Info::LLDP> for its own MIB requirements.
 
+See L<SNMP::Info::IEEE802dot3ad> for its own MIB requirements.
+
 =back
 
 =head1 GLOBALS
@@ -193,18 +176,17 @@ These are methods that return scalar value from SNMP
 
 =over
 
-=item $h3c->vendor()
+=item $huawei->vendor()
 
-Returns value for C<entPhysicalMfgName.1>.
+Returns 'Huawei'.
 
-=item $h3c->os()
+=item $huawei->os()
 
-Returns the OS extracted from C<sysDescr>.
+Returns 'VRP' if contained in C<sysDescr>, 'huawei' otherwise.
 
-=item $h3c->os_ver()
+=item $huawei->os_ver()
 
-Returns the software version. Either C<entPhysicalSoftwareRev.2> or extracted from 
-C<sysDescr>.
+Returns the software version extracted from C<sysDescr>.
 
 =back
 
@@ -225,11 +207,11 @@ to a hash.
 
 =over
 
-=item $h3c->i_ignore()
+=item $huawei->i_ignore()
 
 Returns reference to hash.  Increments value of IID if port is to be ignored.
 
-Ignores loopback
+Ignores InLoopback and Console interfaces
 
 =item C<agg_ports>
 
diff --git a/Info/Layer3/IBMGbTor.pm b/Info/Layer3/IBMGbTor.pm
index 8e65196..045c0c7 100644
--- a/Info/Layer3/IBMGbTor.pm
+++ b/Info/Layer3/IBMGbTor.pm
@@ -41,7 +41,7 @@ use SNMP::Info::LLDP;
 
 use vars qw/$VERSION %GLOBALS %FUNCS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::MIBS,
diff --git a/Info/Layer3/Juniper.pm b/Info/Layer3/Juniper.pm
index 1cfe4bd..94d1372 100644
--- a/Info/Layer3/Juniper.pm
+++ b/Info/Layer3/Juniper.pm
@@ -40,7 +40,7 @@ use SNMP::Info::LLDP;
 
 use vars qw/$VERSION $DEBUG %GLOBALS %MIBS %FUNCS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::MIBS,
@@ -163,6 +163,13 @@ sub i_trunk {
     return \%i_trunk;
 }
 
+sub qb_fdb_index {
+    my $juniper  = shift;
+    my $partial = shift;
+
+    return $juniper->jnxExVlanTag($partial);
+}
+
 # 'v_type'     => 'jnxExVlanType',
 sub v_type {
     my $juniper = shift;
@@ -214,22 +221,24 @@ sub i_vlan {
     return $i_vlan;
 }
 
-sub i_vlan_membership {
-    my $juniper  = shift;
-    my $partial = shift;
-
-    my $index = $juniper->bp_index();
-    my ($v_index)  = $juniper->jnxExVlanTag($partial);
-
-    my $v_ports = $juniper->qb_v_egress() || {};
+# Index doesn't use VLAN ID, so override the HOA private method here to
+# correct the mapping 
+sub _vlan_hoa {
+    my $juniper = shift;
+    my ( $v_ports, $partial ) = @_;
 
-    my $i_vlan_membership = {};
+    my $index    = $juniper->bp_index();
+    my $v_index  = $juniper->jnxExVlanTag($partial);
 
-    foreach my $idx ( sort keys %$v_ports ) {
+    my $vlan_hoa = {};
+    foreach my $idx ( keys %$v_ports ) {
         next unless ( defined $v_ports->{$idx} );
-        my $portlist = $v_ports->{$idx}; # is an array reference
+        my $portlist = $v_ports->{$idx};
         my $ret      = [];
-        my $vlan_ndx = $idx;
+        my $vlan_ndx;
+
+        # Strip TimeFilter if we're using VlanCurrentTable
+        ( $vlan_ndx = $idx ) =~ s/^\d+\.//;
 
         # Convert portlist bit array to bp_index array
         for ( my $i = 0; $i <= $#$portlist; $i++ ) {
@@ -241,11 +250,10 @@ sub i_vlan_membership {
             my $ifindex = $index->{$port};
             next unless ( defined($ifindex) );    # shouldn't happen
             next if ( defined $partial and $ifindex !~ /^$partial$/ );
-            push ( @{ $i_vlan_membership->{$ifindex} }, $v_index->{$vlan_ndx} );
+            push( @{ $vlan_hoa->{$ifindex} }, $v_index->{$vlan_ndx} );
         }
     }
-
-    return $i_vlan_membership;
+    return $vlan_hoa;
 }
 
 # Pseudo ENTITY-MIB methods
@@ -655,6 +663,10 @@ to a hash.
 
 =over
 
+=item $juniper->qb_fdb_index()
+
+Returns reference to hash: key = VLAN ID, value = FDB ID.
+
 =item $juniper->v_index()
 
 (C<jnxExVlanTag>)
@@ -675,11 +687,6 @@ to a hash.
 
 Returns a mapping between C<ifIndex> and the PVID or default VLAN.
 
-=item $juniper->i_vlan_membership()
-
-Returns reference to hash of arrays: key = C<ifIndex>, value = array of VLAN
-IDs.  These are the VLANs which are members of the egress list for the port.
-
 =back
 
 =head2 Pseudo F<ENTITY-MIB> information
diff --git a/Info/Layer3/Lantronix.pm b/Info/Layer3/Lantronix.pm
index f906d9b..cf63eb6 100644
--- a/Info/Layer3/Lantronix.pm
+++ b/Info/Layer3/Lantronix.pm
@@ -41,7 +41,7 @@ use SNMP::Info::Layer3;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::MIBS,
diff --git a/Info/Layer3/Microsoft.pm b/Info/Layer3/Microsoft.pm
index 53fbace..7fefaa2 100644
--- a/Info/Layer3/Microsoft.pm
+++ b/Info/Layer3/Microsoft.pm
@@ -39,7 +39,7 @@ use SNMP::Info::Layer3;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = ( %SNMP::Info::Layer3::MIBS, );
 
diff --git a/Info/Layer3/Mikrotik.pm b/Info/Layer3/Mikrotik.pm
index 3babfbd..d5883fc 100644
--- a/Info/Layer3/Mikrotik.pm
+++ b/Info/Layer3/Mikrotik.pm
@@ -39,7 +39,7 @@ use SNMP::Info::Layer3;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::MIBS,
diff --git a/Info/Layer3/N1600.pm b/Info/Layer3/N1600.pm
index 8c172b7..3df3d5e 100644
--- a/Info/Layer3/N1600.pm
+++ b/Info/Layer3/N1600.pm
@@ -41,7 +41,7 @@ use SNMP::Info::SONMP;
 
 use vars qw/$VERSION %GLOBALS %FUNCS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::MIBS,
diff --git a/Info/Layer3/NetSNMP.pm b/Info/Layer3/NetSNMP.pm
index 730f2bb..a99c74a 100644
--- a/Info/Layer3/NetSNMP.pm
+++ b/Info/Layer3/NetSNMP.pm
@@ -40,7 +40,7 @@ use SNMP::Info::LLDP;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::MIBS,
diff --git a/Info/Layer3/Netscreen.pm b/Info/Layer3/Netscreen.pm
index c6e7f3c..1289798 100644
--- a/Info/Layer3/Netscreen.pm
+++ b/Info/Layer3/Netscreen.pm
@@ -40,7 +40,7 @@ use SNMP::Info::IEEE802dot11;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::MIBS,
diff --git a/Info/Layer3/Nexus.pm b/Info/Layer3/Nexus.pm
index d76e0f5..a352ebb 100644
--- a/Info/Layer3/Nexus.pm
+++ b/Info/Layer3/Nexus.pm
@@ -46,7 +46,7 @@ use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 # NOTE: Order creates precedence
 #       Example: v_name exists in Bridge.pm and CiscoVTP.pm
diff --git a/Info/Layer3/PacketFront.pm b/Info/Layer3/PacketFront.pm
index 67fdb0b..b66e8de 100644
--- a/Info/Layer3/PacketFront.pm
+++ b/Info/Layer3/PacketFront.pm
@@ -39,7 +39,7 @@ use SNMP::Info::Layer3;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::MIBS,
diff --git a/Info/Layer3/Passport.pm b/Info/Layer3/Passport.pm
index 2ef1def..6953b6c 100644
--- a/Info/Layer3/Passport.pm
+++ b/Info/Layer3/Passport.pm
@@ -43,7 +43,7 @@ use SNMP::Info::Layer3;
 
 use vars qw/$VERSION %GLOBALS %FUNCS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::MIBS, %SNMP::Info::RapidCity::MIBS,
@@ -573,6 +573,9 @@ sub index_factor {
     # Older Accelar models use base 16 instead of 64
     $index_factor = 16
         if ( defined $model and $model =~ /^1[012][05]0/ );
+    # Newer VSP 4K uses 192?
+    $index_factor = 192
+        if ( defined $model and $model =~ /^VSP4/ );
     return $index_factor;
 }
 
diff --git a/Info/Layer3/Pf.pm b/Info/Layer3/Pf.pm
index 58ae19c..c59304a 100644
--- a/Info/Layer3/Pf.pm
+++ b/Info/Layer3/Pf.pm
@@ -41,7 +41,7 @@ use SNMP::Info::LLDP;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::MIBS,
diff --git a/Info/Layer3/Pica8.pm b/Info/Layer3/Pica8.pm
index c480a19..2cea992 100644
--- a/Info/Layer3/Pica8.pm
+++ b/Info/Layer3/Pica8.pm
@@ -39,7 +39,7 @@ use SNMP::Info::LLDP;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::MIBS,
diff --git a/Info/Layer3/SonicWALL.pm b/Info/Layer3/SonicWALL.pm
index ce98c91..efda412 100644
--- a/Info/Layer3/SonicWALL.pm
+++ b/Info/Layer3/SonicWALL.pm
@@ -36,7 +36,7 @@ use SNMP::Info::Layer3;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer2::MIBS, %SNMP::Info::Layer3::MIBS,
diff --git a/Info/Layer3/Steelhead.pm b/Info/Layer3/Steelhead.pm
index 85d5e88..609067e 100644
--- a/Info/Layer3/Steelhead.pm
+++ b/Info/Layer3/Steelhead.pm
@@ -39,7 +39,7 @@ use SNMP::Info::Layer3;
 
 use vars qw/$VERSION %GLOBALS %FUNCS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::MIBS,
diff --git a/Info/Layer3/Sun.pm b/Info/Layer3/Sun.pm
index 488f239..a3e4923 100644
--- a/Info/Layer3/Sun.pm
+++ b/Info/Layer3/Sun.pm
@@ -39,7 +39,7 @@ use SNMP::Info::Layer3;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = ( %SNMP::Info::Layer3::MIBS, );
 
diff --git a/Info/Layer3/Tasman.pm b/Info/Layer3/Tasman.pm
index 70107d0..4194fb3 100644
--- a/Info/Layer3/Tasman.pm
+++ b/Info/Layer3/Tasman.pm
@@ -42,7 +42,7 @@ use SNMP::Info::MAU;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer3::MIBS,
diff --git a/Info/Layer3/Timetra.pm b/Info/Layer3/Timetra.pm
index 0bd089f..13869f0 100644
--- a/Info/Layer3/Timetra.pm
+++ b/Info/Layer3/Timetra.pm
@@ -40,7 +40,7 @@ use SNMP::Info::Layer3;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = ( %SNMP::Info::Layer3::MIBS, 'TIMETRA-GLOBAL-MIB' => 'timetraReg', );
 
diff --git a/Info/Layer7.pm b/Info/Layer7.pm
index 72c98a4..5058a63 100644
--- a/Info/Layer7.pm
+++ b/Info/Layer7.pm
@@ -39,7 +39,7 @@ use SNMP::Info;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::MIBS,
@@ -100,23 +100,6 @@ sub interfaces {
     return $interfaces;
 }
 
-sub i_ignore {
-    my $l7      = shift;
-    my $partial = shift;
-
-    my $i_type = $l7->i_type($partial) || {};
-
-    my %i_ignore = ();
-
-    foreach my $if ( keys %$i_type ) {
-        my $type = $i_type->{$if};
-        $i_ignore{$if}++
-            if $type =~ /(loopback|other|cpu)/i;
-    }
-
-    return \%i_ignore;
-}
-
 1;
 __END__
 
@@ -229,12 +212,6 @@ to a hash.
 
 Returns reference to the map between IID and physical Port.
 
-=item $l7->i_ignore()
-
-Returns reference to hash.  Increments value of IID if port is to be ignored.
-
-Ignores loopback, other, and cpu
-
 =back
 
 =head2 Table Methods imported from SNMP::Info
diff --git a/Info/Layer7/APC.pm b/Info/Layer7/APC.pm
index 240821b..820e587 100644
--- a/Info/Layer7/APC.pm
+++ b/Info/Layer7/APC.pm
@@ -40,7 +40,7 @@ use SNMP::Info::Layer7;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer7::MIBS,
diff --git a/Info/Layer7/Neoteris.pm b/Info/Layer7/Neoteris.pm
index 4c03633..fa61248 100644
--- a/Info/Layer7/Neoteris.pm
+++ b/Info/Layer7/Neoteris.pm
@@ -38,7 +38,7 @@ use SNMP::Info::Layer7;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer7::MIBS,
diff --git a/Info/Layer7/Netscaler.pm b/Info/Layer7/Netscaler.pm
index a487706..39a56fc 100644
--- a/Info/Layer7/Netscaler.pm
+++ b/Info/Layer7/Netscaler.pm
@@ -38,7 +38,7 @@ use SNMP::Info::Layer7;
 
 use vars qw/$VERSION %GLOBALS %MIBS %FUNCS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     %SNMP::Info::Layer7::MIBS,
diff --git a/Info/MAU.pm b/Info/MAU.pm
index 44cb401..0c2ac98 100644
--- a/Info/MAU.pm
+++ b/Info/MAU.pm
@@ -41,7 +41,7 @@ use SNMP::Info;
 
 use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = ( 'MAU-MIB' => 'mauMod', 'IANA-MAU-MIB' => 'dot3MauType' );
 
diff --git a/Info/MRO.pm b/Info/MRO.pm
index a41da05..904eb64 100644
--- a/Info/MRO.pm
+++ b/Info/MRO.pm
@@ -3,6 +3,9 @@ package SNMP::Info::MRO;
 use warnings;
 use strict;
 
+use vars qw/$VERSION/;
+$VERSION = '3.28';
+ 
 use PPI;
 use Class::ISA;
 use Module::Info;
@@ -267,7 +270,7 @@ sub globals { _walk_global_data(shift, 'GLOBALS') }
 Returns a data structure showing how L<SNMP::Info> will resolve MIB Tables
 configured through the C<%FUNCS> hashes in C<$module>.
 
-See L</globals> for further detail.
+See L<SNMP::Info::Layer3/"GLOBALS"> for further detail.
 
 =cut
 
@@ -360,7 +363,7 @@ Pretty print the output of C<superclasses()>.
 =cut
 
 sub print_superclasses {
-    print join ("\n", (shift)->superclasses), "\n";
+    print join ("\n", superclasses(@_)), "\n";
 }
 
 =back
@@ -370,9 +373,9 @@ sub print_superclasses {
 Oliver Gorwits <oliver at cpan.org>
 
 =head1 COPYRIGHT AND LICENSE
- 
+
 This software is copyright (c) 2014 by The SNMP::Info Project.
-  
+
  # Redistribution and use in source and binary forms, with or without
  # modification, are permitted provided that the following conditions are met:
  #
diff --git a/Info/NortelStack.pm b/Info/NortelStack.pm
index 6e77b9a..af6a7b5 100644
--- a/Info/NortelStack.pm
+++ b/Info/NortelStack.pm
@@ -39,7 +39,7 @@ use SNMP::Info;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
 
diff --git a/Info/PowerEthernet.pm b/Info/PowerEthernet.pm
index 950687f..69f9e1e 100644
--- a/Info/PowerEthernet.pm
+++ b/Info/PowerEthernet.pm
@@ -39,7 +39,7 @@ use SNMP::Info;
 
 use vars qw/$VERSION %MIBS %FUNCS %GLOBALS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = ( 'POWER-ETHERNET-MIB' => 'pethPsePortDetectionStatus' );
 
diff --git a/Info/RapidCity.pm b/Info/RapidCity.pm
index 25027d8..02a5847 100644
--- a/Info/RapidCity.pm
+++ b/Info/RapidCity.pm
@@ -1,7 +1,7 @@
 # SNMP::Info::RapidCity
 # $Id$
 #
-# Copyright (c) 2008 Eric Miller
+# Copyright (c) 2014 Eric Miller
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -39,9 +39,15 @@ use SNMP::Info;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
-%MIBS = ( 'RAPID-CITY' => 'rapidCity', );
+%MIBS = (
+    'RAPID-CITY' => 'rapidCity',
+    # These are distinct from RAPID-CITY but are potentially used by
+    # classes which inherit the RAPID-CITY class
+    'NORTEL-NETWORKS-RAPID-SPANNING-TREE-MIB'    => 'nnRstDot1dStpVersion',
+    'NORTEL-NETWORKS-MULTIPLE-SPANNING-TREE-MIB' => 'nnMstBrgAddress',
+);
 
 %GLOBALS = (
     'rc_serial'    => 'rcChasSerialNumber',
@@ -153,6 +159,30 @@ $VERSION = '3.20';
     'rc_mlt_ports'    => 'rcMltPortMembers',
     'rc_mlt_index'    => 'rcMltIfIndex',
     'rc_mlt_dp'       => 'rcMltDesignatedPort',
+
+    # From RAPID-CITY::rcBridgeSpbmMacTable
+    'rc_spbm_fw_port'   => 'rcBridgeSpbmMacCPort',
+    'rc_spbm_fw_status' => 'rcBridgeSpbmMacStatus',
+    'rc_spbm_fw_vlan'   => 'rcBridgeSpbmMacCVlanId',
+
+    # From RAPID-CITY::rcStgTable
+    'stp_i_id'           => 'rcStgId',
+    'rc_stp_i_mac'       => 'rcStgBridgeAddress',
+    'rc_stp_i_time'      => 'rcStgTimeSinceTopologyChange',
+    'rc_stp_i_ntop'      => 'rcStgTopChanges',
+    'rc_stp_i_root'      => 'rcStgDesignatedRoot',
+    'rc_stp_i_root_port' => 'rcStgRootPort',
+    'rc_stp_i_priority'  => 'rcStgPriority',
+
+    # From RAPID-CITY::rcStgPortTable
+    'rc_stp_p_id'       => 'rcStgPort',
+    'stp_p_stg_id'      => 'rcStgPortStgId',
+    'rc_stp_p_priority' => 'rcStgPortPriority',
+    'rc_stp_p_state'    => 'rcStgPortState',
+    'rc_stp_p_cost'     => 'rcStgPortPathCost',
+    'rc_stp_p_root'     => 'rcStgPortDesignatedRoot',
+    'rc_stp_p_bridge'   => 'rcStgPortDesignatedBridge',
+    'rc_stp_p_port'     => 'rcStgPortDesignatedPort',
 );
 
 %MUNGE = (
@@ -162,6 +192,11 @@ $VERSION = '3.20';
     'rc_vlan_members' => \&SNMP::Info::munge_port_list,
     'rc_vlan_no_join' => \&SNMP::Info::munge_port_list,
     'rc_mlt_ports'    => \&SNMP::Info::munge_port_list,
+    'rc_stp_i_mac'       => \&SNMP::Info::munge_mac,
+    'rc_stp_i_root'      => \&SNMP::Info::munge_prio_mac,
+    'rc_stp_p_root'      => \&SNMP::Info::munge_prio_mac,
+    'rc_stp_p_bridge'    => \&SNMP::Info::munge_prio_mac,
+    'rc_stp_p_port'      => \&SNMP::Info::munge_prio_port,
 );
 
 # Need to override here since overridden in Layer2 and Layer3 classes
@@ -328,6 +363,71 @@ sub i_vlan_membership {
     return $i_vlan_membership;
 }
 
+sub i_vlan_membership_untagged {
+    my $rapidcity = shift;
+
+    # Traditionally access ports have one VLAN untagged and trunk ports have
+    # one or more VLANs all tagged
+    # Newer VOSS device trunks have PerformTagging true or false and also can
+    # UntagDefaultVlan
+    # Newer BOSS device trunks have four PerformTagging options true, false,
+    # tagPvidOnly, and untagPvidOnly
+
+    my $p_members = $rapidcity->i_vlan_membership();
+    my $i_vlan = $rapidcity->i_vlan();
+    my $p_tag_opt = $rapidcity->rcVlanPortPerformTagging() || {};
+    my $p_untag_def = $rapidcity->rcVlanPortUntagDefaultVlan() || {};
+    my $p_type = $rapidcity->rcVlanPortType() || {};
+
+    my $members_untagged = {};
+    foreach my $port ( keys %$p_type ) {
+        my $type = $p_type->{$port};
+        next unless $type;
+
+        # Easiest case first access ports
+        if ($type eq 'access') {
+            # Access ports should only have one VLAN and it should be
+            # untagged
+            $members_untagged->{$port} = $p_members->{$port};
+        }
+        else {
+            # If PerformTagging has a value do all checks otherwise we're
+            # just a trunk and everything is tagged
+            if ($p_tag_opt->{$port}) {
+                if ($p_tag_opt->{$port} eq 'untagPvidOnly') {
+                    my $vlan = $i_vlan->{$port};
+                    push( @{ $members_untagged->{$port} }, $vlan );                    
+                }
+                elsif (($p_tag_opt->{$port} eq 'true') and
+                       ($p_untag_def->{$port} and $p_untag_def->{$port} eq 'true'))
+                {
+                    my $vlan = $i_vlan->{$port};
+                    push( @{ $members_untagged->{$port} }, $vlan );                     
+                }
+                elsif ($p_tag_opt->{$port} eq 'tagPvidOnly') {
+                    my $vlan = $i_vlan->{$port};
+                    my @arr = $p_members->{$port};
+                    my $index = 0;
+                    my $count = scalar @arr;
+                    $index++ until $arr[$index] eq $vlan or $index==$count;
+                    splice(@arr, $index, 1);
+                    $members_untagged->{$port} = @arr;
+                }
+                # Don't know if this is a legal configuration, but included
+                # for completeness
+                elsif ($p_tag_opt->{$port} eq 'false') {
+                    $members_untagged->{$port} = $p_members->{$port};
+                }
+                else {
+                    next;
+                }
+            }
+        }
+    }
+ 
+    return $members_untagged;
+}
+
 sub set_i_pvid {
     my $rapidcity = shift;
     my ( $vlan_id, $ifindex ) = @_;
@@ -601,6 +701,174 @@ sub agg_ports {
     return $ret;
 }
 
+# break up the rcBridgeSpbmMacEntry INDEX into ISID and MAC Address.
+sub _spbm_fdbtable_index {
+    my $idx    = shift;
+    my @values = split( /\./, $idx );
+    my $isid = shift(@values);
+    return ( $isid, join( ':', map { sprintf "%02x", $_ } @values ) );
+}
+
+sub rc_spbm_fw_mac {
+    my $rapidcity  = shift;
+    my $partial = shift;
+
+    my $spbm_fw_ports = $rapidcity->rc_spbm_fw_port($partial);
+    my $spbm_fw_mac  = {};
+    foreach my $idx ( keys %$spbm_fw_ports ) {
+        my ( $isid, $mac ) = _spbm_fdbtable_index($idx);
+        $spbm_fw_mac->{$idx} = $mac;
+    }
+    return $spbm_fw_mac;
+}
+
+sub rc_spbm_fw_isid {
+    my $rapidcity  = shift;
+    my $partial = shift;
+
+    my $spbm_fw_ports = $rapidcity->rc_spbm_fw_port($partial);
+    my $spbm_fw_isid  = {};
+    foreach my $idx ( keys %$spbm_fw_ports ) {
+        my ( $isid, $mac ) = _spbm_fdbtable_index($idx);
+        $spbm_fw_isid->{$idx} = $isid;
+    }
+    return $spbm_fw_isid;
+}
+
+sub stp_ver {
+    my $rapidcity = shift;
+
+    return $rapidcity->rcSysSpanningTreeOperMode()
+      || $rapidcity->SUPER::stp_ver();
+}
+
+# RSTP and ieee8021d operating modes do not populate RAPID-CITY::rcStgTable
+# or RAPID-CITY::rcStgPortTable but do populate BRIDGE-MIB so check both
+sub stp_i_mac {
+    my $rapidcity = shift;
+
+    return $rapidcity->rc_stp_i_mac()
+      || $rapidcity->SUPER::stp_i_mac();
+}
+
+sub stp_i_time {
+    my $rapidcity = shift;
+
+    return $rapidcity->rc_stp_i_time()
+      || $rapidcity->SUPER::stp_i_time();
+}
+
+sub stp_i_ntop {
+    my $rapidcity = shift;
+
+    return $rapidcity->rc_stp_i_ntop()
+      || $rapidcity->SUPER::stp_i_ntop();
+}
+
+sub stp_i_root {
+    my $rapidcity = shift;
+
+    return $rapidcity->rc_stp_i_root()
+      || $rapidcity->SUPER::stp_i_root();
+}
+
+sub stp_i_root_port {
+    my $rapidcity = shift;
+
+    return $rapidcity->rc_stp_i_root_port()
+      || $rapidcity->SUPER::stp_i_root_port();
+}
+
+sub stp_i_priority {
+    my $rapidcity = shift;
+
+    return $rapidcity->rc_stp_i_priority()
+      || $rapidcity->SUPER::stp_i_priority();
+}
+
+sub stp_p_id {
+    my $rapidcity = shift;
+
+    return $rapidcity->rc_stp_p_id()
+      || $rapidcity->SUPER::stp_p_id();
+}
+
+sub stp_p_priority {
+    my $rapidcity = shift;
+
+    return $rapidcity->rc_stp_p_priority()
+      || $rapidcity->SUPER::stp_p_priority();
+}
+
+sub stp_p_state {
+    my $rapidcity = shift;
+
+    return $rapidcity->rc_stp_p_state()
+      || $rapidcity->SUPER::stp_p_state();
+}
+
+sub stp_p_cost {
+    my $rapidcity = shift;
+
+    return $rapidcity->rc_stp_p_cost()
+      || $rapidcity->SUPER::stp_p_cost();
+}
+
+sub stp_p_root {
+    my $rapidcity = shift;
+
+    return $rapidcity->rc_stp_p_root()
+      || $rapidcity->SUPER::stp_p_root();
+}
+
+sub stp_p_bridge {
+    my $rapidcity = shift;
+
+    return $rapidcity->rc_stp_p_bridge()
+      || $rapidcity->SUPER::stp_p_bridge();
+}
+
+sub stp_p_port {
+    my $rapidcity = shift;
+
+    return $rapidcity->rc_stp_p_port()
+      || $rapidcity->SUPER::stp_p_port();
+}
+
+sub mst_vlan2instance {
+    my $rapidcity = shift;
+    my $partial   = shift;
+
+    return $rapidcity->rcVlanStgId($partial);
+}
+
+sub i_bpduguard_enabled {
+    my $rapidcity    = shift;
+    my $partial = shift;
+
+    return $rapidcity->rcPortBpduFilteringOperEnabled();
+}
+
+sub i_stp_state {
+    my $rapidcity = shift;
+    my $partial   = shift;
+
+    my $bp_index    = $rapidcity->bp_index($partial);
+    my $stp_p_state = $rapidcity->dot1dStpPortState($partial);
+
+    my %i_stp_state;
+
+    foreach my $index ( keys %$stp_p_state ) {
+        my $state = $stp_p_state->{$index};
+        my $iid   = $bp_index->{$index};
+        next unless defined $iid;
+        next unless defined $state;
+        $i_stp_state{$iid} = $state;
+    }
+
+    return \%i_stp_state;
+}
+
 1;
 
 __END__
@@ -710,6 +978,14 @@ These are methods that return scalar values from SNMP
 
 Returns serial number of the chassis
 
+=item $rapidcity->stp_ver()
+
+Returns the particular STP version running on this device.  
+
+Values: C<nortelStpg>, C<pvst>, C<rstp>, C<mstp>, C<ieee8021d>
+
+(C<rcSysSpanningTreeOperMode>)
+
 =back
 
 =head1 TABLE METHODS
@@ -746,6 +1022,12 @@ IDs.  These are the VLANs which are members of the egress list for the port.
     print "Port: $port VLAN: $vlan\n";
   }
 
+=item $rapidcity->i_vlan_membership_untagged()
+
+Returns reference to hash of arrays: key = C<ifIndex>, value = array of VLAN
+IDs.  These are the VLANs which are members of the untagged egress list for
+the port.
+
 =item $rapidcity->v_index()
 
 Returns VLAN IDs
@@ -758,6 +1040,25 @@ Returns a HASH reference mapping from slave to master port for each member of
 a port bundle (MLT) on the device. Keys are ifIndex of the slave ports,
 Values are ifIndex of the corresponding master ports.
 
+=item $rapidcity->i_stp_state()
+
+Returns the mapping of (C<dot1dStpPortState>) to the interface
+index (iid).
+
+=item $rapidcity->mst_vlan2instance()
+
+Returns the mapping of VLAN to Spanning Tree Group (STG) instance in the
+form of a hash reference with key = VLAN id, value = STG instance
+
+(C<rcVlanStgId>)
+
+=item $rapidcity->i_bpduguard_enabled()
+
+Returns true or false depending on whether C<BpduGuard> is enabled on a given
+port.  Format is a hash reference with key = C<ifIndex>, value = [true|false]
+
+(C<rcPortBpduFilteringOperEnabled>)
+
 =back
 
 =head2 RAPID-CITY Port Table (C<rcPortTable>)
@@ -1090,6 +1391,126 @@ Values are ifIndex of the corresponding master ports.
 
 =back
 
+=head2 RAPID-CITY Bridge SPBM MAC Table (C<rcBridgeSpbmMacTable>)
+
+=over
+
+=item $rapidcity->rc_spbm_fw_mac()
+
+Returns reference to hash of forwarding table MAC Addresses
+
+(C<rcBridgeSpbmMacAddr>)
+
+=item $rapidcity->rc_spbm_fw_port()
+
+Returns reference to hash of forwarding table entries port interface
+identifier (iid)
+
+(C<rcBridgeSpbmMacCPort>)
+
+=item $rapidcity->rc_spbm_fw_status()
+
+Returns reference to hash of forwarding table entries status
+
+(C<rcBridgeSpbmMacStatus>)
+
+=item $rapidcity->rc_spbm_fw_vlan()
+
+Returns reference to hash of forwarding table entries Customer VLAN ID
+
+(C<rcBridgeSpbmMacCVlanId>)
+
+=item $rapidcity->rc_spbm_fw_isid()
+
+Returns reference to hash of forwarding table entries ISID
+
+(C<rcBridgeSpbmMacIsid>)
+
+=back
+
+=head2 Spanning Tree Instance Globals
+
+C<RSTP> and C<ieee8021d> operating modes do not populate the
+C<RAPID-CITY::rcStgTable> but do populate F<BRIDGE-MIB>.  These methods check
+F<RAPID-CITY> first and fall back to F<BRIDGE-MIB>.
+
+=over
+
+=item $rapidcity->stp_i_mac()
+
+Returns the bridge address
+
+=item $rapidcity->stp_i_time()
+
+Returns time since last topology change detected. (100ths/second)
+
+=item $rapidcity->stp_i_ntop()
+
+Returns the total number of topology changes detected.
+
+=item $rapidcity->stp_i_root()
+
+Returns root of STP.
+
+=item $rapidcity->stp_i_root_port()
+
+Returns the port number of the port that offers the lowest cost path
+to the root bridge.
+
+=item $rapidcity->stp_i_priority()
+
+Returns the port number of the port that offers the lowest cost path
+to the root bridge.
+
+=back
+
+=head2 Spanning Tree Protocol Port Table
+
+C<RSTP> and C<ieee8021d> operating modes do not populate the
+C<RAPID-CITY::rcStgPortTable> but do populate F<BRIDGE-MIB>.  These methods
+check F<RAPID-CITY> first and fall back to F<BRIDGE-MIB>.
+
+=over
+
+=item $rapidcity->stp_p_id()
+
+"The port number of the port for which this entry contains Spanning Tree
+Protocol management information."
+
+=item $rapidcity->stp_p_priority()
+
+"The value of the priority field which is contained in the first
+(in network byte order) octet of the (2 octet long) Port ID.  The other octet
+of the Port ID is given by the value of C<dot1dStpPort>."
+
+=item $rapidcity->stp_p_state()
+
+"The port's current state as defined by application of the Spanning Tree
+Protocol."  
+
+=item $rapidcity->stp_p_cost()
+
+"The contribution of this port to the path cost of paths towards the spanning
+tree root which include this port."
+
+=item $rapidcity->stp_p_root()
+
+"The unique Bridge Identifier of the Bridge recorded as the Root in the
+Configuration BPDUs transmitted by the Designated Bridge for the segment to
+which the port is attached."
+
+=item $rapidcity->stp_p_bridge()
+
+"The Bridge Identifier of the bridge which this port considers to be the
+Designated Bridge for this port's segment."
+
+=item $rapidcity->stp_p_port()
+
+"The Port Identifier of the port on the Designated Bridge for this port's
+segment."
+
+=back
+
 =head1 SET METHODS
 
 These are methods that provide SNMP set functionality for overridden methods
diff --git a/Info/SONMP.pm b/Info/SONMP.pm
index 7f772ad..8744223 100644
--- a/Info/SONMP.pm
+++ b/Info/SONMP.pm
@@ -39,7 +39,7 @@ use SNMP::Info;
 
 use vars qw/$VERSION %FUNCS %GLOBALS %MIBS %MUNGE/;
 
-$VERSION = '3.20';
+$VERSION = '3.28';
 
 %MIBS = (
     'SYNOPTICS-ROOT-MIB'           => 'synoptics',
diff --git a/MANIFEST b/MANIFEST
index 3ec860b..4f3851b 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -78,9 +78,11 @@ Info/Layer3/Enterasys.pm
 Info/Layer3/Extreme.pm
 Info/Layer3/F5.pm
 Info/Layer3/Force10.pm
+Info/Layer3/Fortinet.pm
 Info/Layer3/Foundry.pm
 Info/Layer3/H3C.pm
 Info/Layer3/HP9300.pm
+Info/Layer3/Huawei.pm
 Info/Layer3/IBMGbTor.pm
 Info/Layer3/Juniper.pm
 Info/Layer3/Lantronix.pm
diff --git a/META.json b/META.json
index 4a7d0ba..51c4ce6 100644
--- a/META.json
+++ b/META.json
@@ -4,7 +4,7 @@
       "Eric A. Miller <emiller at cpan.org>"
    ],
    "dynamic_config" : 1,
-   "generated_by" : "ExtUtils::MakeMaker version 6.66, CPAN::Meta::Converter version 2.112621",
+   "generated_by" : "ExtUtils::MakeMaker version 7.04, CPAN::Meta::Converter version 2.150001",
    "license" : [
       "bsd"
    ],
@@ -22,22 +22,22 @@
    "prereqs" : {
       "build" : {
          "requires" : {
-            "ExtUtils::MakeMaker" : 0
+            "ExtUtils::MakeMaker" : "0"
          }
       },
       "configure" : {
          "requires" : {
-            "ExtUtils::MakeMaker" : 0
+            "ExtUtils::MakeMaker" : "0"
          }
       },
       "runtime" : {
          "requires" : {
-            "Math::BigInt" : 0,
-            "SNMP" : 0,
-            "Test::More" : 0
+            "Math::BigInt" : "0",
+            "SNMP" : "0",
+            "Test::More" : "0"
          }
       }
    },
    "release_status" : "stable",
-   "version" : "3.20"
+   "version" : "3.28"
 }
diff --git a/META.yml b/META.yml
index 75bba6b..7d92781 100644
--- a/META.yml
+++ b/META.yml
@@ -3,22 +3,22 @@ abstract: 'OO Interface to Network devices and MIBs through SNMP'
 author:
   - 'Eric A. Miller <emiller at cpan.org>'
 build_requires:
-  ExtUtils::MakeMaker: 0
+  ExtUtils::MakeMaker: '0'
 configure_requires:
-  ExtUtils::MakeMaker: 0
+  ExtUtils::MakeMaker: '0'
 dynamic_config: 1
-generated_by: 'ExtUtils::MakeMaker version 6.66, CPAN::Meta::Converter version 2.112621'
+generated_by: 'ExtUtils::MakeMaker version 7.04, CPAN::Meta::Converter version 2.150001'
 license: bsd
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
-  version: 1.4
+  version: '1.4'
 name: SNMP-Info
 no_index:
   directory:
     - t
     - inc
 requires:
-  Math::BigInt: 0
-  SNMP: 0
-  Test::More: 0
-version: 3.20
+  Math::BigInt: '0'
+  SNMP: '0'
+  Test::More: '0'
+version: '3.28'
diff --git a/README b/README
index 9cff5b3..ec3057d 100644
--- a/README
+++ b/README
@@ -4,7 +4,7 @@ NAME
 
 VERSION
 
-    SNMP::Info - Version 3.20
+    SNMP::Info - Version 3.28
 
 AUTHOR
 
@@ -336,6 +336,11 @@ SUBCLASSES
 
         See documentation in SNMP::Info::MAU for details.
 
+    SNMP::Info::MRO
+        Method resolution introspection for SNMP::Info
+
+        See documentation in SNMP::Info::MRO for details.
+
     SNMP::Info::NortelStack
         S5-AGENT-MIB, S5-CHASSIS-MIB.
 
@@ -661,6 +666,11 @@ SUBCLASSES
 
             See documentation in SNMP::Info::Layer3::Force10 for details.
 
+        SNMP::Info::Layer3::Fortinet
+            Subclass for Fortinet devices.
+
+            See documentation in SNMP::Info::Layer3::Fortinet for details.
+
         SNMP::Info::Layer3::Foundry
             Subclass for Brocade (Foundry) Network devices.
 
@@ -678,6 +688,11 @@ SUBCLASSES
 
             See documentation in SNMP::Info::Layer3::HP9300 for details.
 
+        SNMP::Info::Layer3::Huawei
+            SNMP Interface to Huawei Layer 3 switches and routers.
+
+            See documentation in SNMP::Info::Layer3::Huawei for details.
+
         SNMP::Info::Layer3::IBMGbTor
             SNMP Interface to IBM Rackswitch (formerly Blade Network
             Technologies) network devices.
@@ -1876,6 +1891,10 @@ SNMP::INFO INTERNALS
         ASCII hex string.
 
     munge_prio_mac()
+        Takes an 2-byte octet stream (HEX-STRING) and returns a colon
+        separated ASCII hex string.
+
+    munge_prio_port()
         Takes an 8-byte octet stream (HEX-STRING) and returns a colon
         separated ASCII hex string.
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-perl/packages/libsnmp-info-perl.git



More information about the Pkg-perl-cvs-commits mailing list