summaryrefslogtreecommitdiffstats
path: root/usr.sbin/bsnmpd
diff options
context:
space:
mode:
authorsyrinx <syrinx@FreeBSD.org>2006-12-07 22:36:17 +0000
committersyrinx <syrinx@FreeBSD.org>2006-12-07 22:36:17 +0000
commitd7ca8e25c239adadb43ab46a196d798c39e00d1e (patch)
tree289115050b8763ac1fd31f699c72aed347629d8a /usr.sbin/bsnmpd
parentaa38c7c3474274f240c1a4b23a939de6a2b1be80 (diff)
downloadFreeBSD-src-d7ca8e25c239adadb43ab46a196d798c39e00d1e.zip
FreeBSD-src-d7ca8e25c239adadb43ab46a196d798c39e00d1e.tar.gz
Add support for RSTP (RFC4318) to the SNMP bridge monitoring module.
Approved by: bz (mentor)
Diffstat (limited to 'usr.sbin/bsnmpd')
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_bridge/BEGEMOT-BRIDGE-MIB.txt191
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_bridge/Makefile2
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_bridge/RSTP-MIB.txt325
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_bridge/bridge_if.c77
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_bridge/bridge_port.c255
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_bridge/bridge_snmp.c10
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_bridge/bridge_snmp.h45
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_bridge/bridge_sys.c263
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_bridge/bridge_tree.def40
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_bridge/snmp_bridge.39
10 files changed, 1170 insertions, 47 deletions
diff --git a/usr.sbin/bsnmpd/modules/snmp_bridge/BEGEMOT-BRIDGE-MIB.txt b/usr.sbin/bsnmpd/modules/snmp_bridge/BEGEMOT-BRIDGE-MIB.txt
index fdba57b..4de407c 100644
--- a/usr.sbin/bsnmpd/modules/snmp_bridge/BEGEMOT-BRIDGE-MIB.txt
+++ b/usr.sbin/bsnmpd/modules/snmp_bridge/BEGEMOT-BRIDGE-MIB.txt
@@ -41,7 +41,7 @@ IMPORTS
FROM BEGEMOT-MIB;
begemotBridge MODULE-IDENTITY
- LAST-UPDATED "200608100000Z"
+ LAST-UPDATED "200611210000Z"
ORGANIZATION "Sofia University St. Kliment Ohridski"
CONTACT-INFO
" Shteryana Shopova
@@ -56,7 +56,13 @@ begemotBridge MODULE-IDENTITY
E-Mail: syrinx@FreeBSD.org"
DESCRIPTION
"The Begemot MIB for managing bridge interfaces."
-
+ REVISION "200611210000Z"
+ DESCRIPTION
+ "Second revision adds support for monitoring RSTP
+ specific variables."
+ REVISION "200607270000Z"
+ DESCRIPTION
+ "Initial revision."
::= { begemot 205 }
-- ---------------------------------------------------------- --
@@ -303,7 +309,9 @@ BegemotBridgeStpEntry ::= SEQUENCE {
begemotBridgeStpForwardDelay Timeout,
begemotBridgeStpBridgeMaxAge Timeout,
begemotBridgeStpBridgeHelloTime Timeout,
- begemotBridgeStpBridgeForwardDelay Timeout
+ begemotBridgeStpBridgeForwardDelay Timeout,
+ begemotBridgeStpVersion INTEGER,
+ begemotBridgeStpTxHoldCount Integer32
}
begemotBridgeStpProtocolSpecification OBJECT-TYPE
@@ -466,6 +474,41 @@ begemotBridgeStpBridgeForwardDelay OBJECT-TYPE
bridge was the root of the spanning tree."
::= { begemotBridgeStpEntry 14 }
+begemotBridgeStpVersion OBJECT-TYPE
+ SYNTAX INTEGER {
+ stpCompatible(0),
+ rstp(2)
+ }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "The version of Spanning Tree Protocol the bridge is
+ currently running. The value 'stpCompatible(0)'
+ indicates the Spanning Tree Protocol specified in
+ IEEE 802.1D-1998 and 'rstp(2)' indicates the Rapid
+ Spanning Tree Protocol specified in IEEE 802.1w and
+ clause 17 of 802.1D-2004. The values are directly from
+ the IEEE standard. New values may be defined as future
+ versions of the protocol become available.
+
+ The value of this object MUST be retained across
+ reinitializations of the management system."
+ DEFVAL { rstp }
+ ::= { begemotBridgeStpEntry 15 }
+
+begemotBridgeStpTxHoldCount OBJECT-TYPE
+ SYNTAX Integer32 (1..10)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "The value used by the Port Transmit state machine to limit
+ the maximum transmission rate of BPDUs on the bridge interface.
+
+ The value of this object MUST be retained across
+ reinitializations of the management system."
+ DEFVAL { 3 }
+ ::= { begemotBridgeStpEntry 16 }
+
-- ---------------------------------------------------------- --
-- the Bridge STP ports table
-- ---------------------------------------------------------- --
@@ -620,6 +663,148 @@ begemotBridgeStpPortForwardTransitions OBJECT-TYPE
::= { begemotBridgeStpPortEntry 10 }
-- ---------------------------------------------------------- --
+-- the Bridge STP extended ports table
+-- ---------------------------------------------------------- --
+
+begemotBridgeStpExtPortTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF BegemotBridgeStpExtPortEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "A table that contains port-specific Rapid Spanning Tree
+ information for the bridge interface members."
+ ::= { begemotBridgeStp 3 }
+
+begemotBridgeStpExtPortEntry OBJECT-TYPE
+ SYNTAX BegemotBridgeStpExtPortEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "A list of Rapid Spanning Tree information maintained by
+ each bridge interface member."
+ AUGMENTS { begemotBridgeStpPortEntry }
+ ::= { begemotBridgeStpExtPortTable 1 }
+
+BegemotBridgeStpExtPortEntry ::= SEQUENCE {
+ begemotBridgeStpPortProtocolMigration TruthValue,
+ begemotBridgeStpPortAdminEdgePort TruthValue,
+ begemotBridgeStpPortOperEdgePort TruthValue,
+ begemotBridgeStpPortAdminPointToPoint INTEGER,
+ begemotBridgeStpPortOperPointToPoint TruthValue,
+ begemotBridgeStpPortAdminPathCost Integer32
+}
+
+begemotBridgeStpPortProtocolMigration OBJECT-TYPE
+ SYNTAX TruthValue
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "When operating in RSTP (version 2) mode, writing true(1)
+ to this object forces this port to transmit RSTP BPDUs.
+ Any other operation on this object has no effect and
+ it always returns false(2) when read."
+ ::= { begemotBridgeStpExtPortEntry 1 }
+
+begemotBridgeStpPortAdminEdgePort OBJECT-TYPE
+ SYNTAX TruthValue
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "The administrative value of the Edge Port parameter. A
+ value of true(1) indicates that this port should be
+ assumed as an edge-port, and a value of false(2) indicates
+ that this port should be assumed as a non-edge-port.
+ Setting this object will also cause the corresponding
+ instance of begemotBridgeStpPortOperEdgePort to change to
+ the same value. Note that even when this object's value
+ is true, the value of the corresponding instance of
+ begemotBridgeStpPortOperEdgePort can be false if a BPDU
+ has been received.
+
+ The value of this object MUST be retained across
+ reinitializations of the management system."
+ ::= { begemotBridgeStpExtPortEntry 2 }
+
+begemotBridgeStpPortOperEdgePort OBJECT-TYPE
+ SYNTAX TruthValue
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The operational value of the Edge Port parameter. The
+ object is initialized to the value of the corresponding
+ instance of begemotBridgeStpPortAdminEdgePort. When the
+ corresponding instance of begemotBridgeStpPortAdminEdgePort
+ is set, this object will be changed as well. This object
+ will also be changed to false on reception of a BPDU."
+ ::= { begemotBridgeStpExtPortEntry 3 }
+
+begemotBridgeStpPortAdminPointToPoint OBJECT-TYPE
+ SYNTAX INTEGER {
+ forceTrue(0),
+ forceFalse(1),
+ auto(2)
+ }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "The administrative point-to-point status of the LAN segment
+ attached to this port, using the enumeration values of the
+ IEEE 802.1w clause. A value of forceTrue(0) indicates
+ that this port should always be treated as if it is
+ connected to a point-to-point link. A value of
+ forceFalse(1) indicates that this port should be treated as
+ having a shared media connection. A value of auto(2)
+ indicates that this port is considered to have a
+ point-to-point link if it is an Aggregator and all of its
+ members are aggregatable, or if the MAC entity
+ is configured for full duplex operation, either through
+ auto-negotiation or by management means. Manipulating this
+ object changes the underlying adminPortToPortMAC.
+
+ The value of this object MUST be retained across
+ reinitializations of the management system."
+ ::= { begemotBridgeStpExtPortEntry 4 }
+
+begemotBridgeStpPortOperPointToPoint OBJECT-TYPE
+ SYNTAX TruthValue
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The operational point-to-point status of the LAN segment
+ attached to this port. It indicates whether a port is
+ considered to have a point-to-point connection.
+ If adminPointToPointMAC is set to auto(2), then the value
+ of operPointToPointMAC is determined in accordance with the
+ specific procedures defined for the MAC entity concerned,
+ as defined in IEEE 802.1w, clause 6.5. The value is
+ determined dynamically; that is, it is re-evaluated whenever
+ the value of adminPointToPointMAC changes, and whenever
+ the specific procedures defined for the MAC entity evaluates
+ a change in its point-to-point status."
+ ::= { begemotBridgeStpExtPortEntry 5 }
+
+begemotBridgeStpPortAdminPathCost OBJECT-TYPE
+ SYNTAX Integer32 (0..200000000)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "The administratively assigned value for the contribution
+ of this port to the path cost of paths toward the spanning
+ tree root.
+
+ Writing a value of '0' assigns the automatically calculated
+ default Path Cost value to the port. If the default Path
+ Cost is being used, this object returns '0' when read.
+
+ This complements the object begemotBridgeStpPortPathCost or
+ begemotBridgeStpPortPathCost32, which returns the operational
+ value of the path cost.
+
+ The value of this object MUST be retained across
+ reinitializations of the management system."
+ ::= { begemotBridgeStpExtPortEntry 6 }
+
+-- ---------------------------------------------------------- --
-- the Bridge interface Transparent bridging table
-- ---------------------------------------------------------- --
diff --git a/usr.sbin/bsnmpd/modules/snmp_bridge/Makefile b/usr.sbin/bsnmpd/modules/snmp_bridge/Makefile
index 873151c..5d0afec 100644
--- a/usr.sbin/bsnmpd/modules/snmp_bridge/Makefile
+++ b/usr.sbin/bsnmpd/modules/snmp_bridge/Makefile
@@ -12,7 +12,7 @@ XSYM= dot1dBridge newRoot topologyChange begemotBridgeNewRoot \
MAN= snmp_bridge.3
-BMIBS= BRIDGE-MIB.txt BEGEMOT-BRIDGE-MIB.txt
+BMIBS= BRIDGE-MIB.txt BEGEMOT-BRIDGE-MIB.txt RSTP-MIB.txt
DEFS= ${MOD}_tree.def
INCS= ${MOD}_snmp.h
diff --git a/usr.sbin/bsnmpd/modules/snmp_bridge/RSTP-MIB.txt b/usr.sbin/bsnmpd/modules/snmp_bridge/RSTP-MIB.txt
new file mode 100644
index 0000000..ea6648e
--- /dev/null
+++ b/usr.sbin/bsnmpd/modules/snmp_bridge/RSTP-MIB.txt
@@ -0,0 +1,325 @@
+--
+-- Copyright (C) The Internet Society (2005).
+--
+-- This document is subject to the rights, licenses and restrictions
+-- contained in BCP 78, and except as set forth therein, the authors
+-- retain all their rights.
+--
+-- This document and the information contained herein are provided on an
+-- "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
+-- OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET
+-- ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
+-- INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
+-- INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+-- WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+--
+-- $FreeBSD$
+--
+
+RSTP-MIB DEFINITIONS ::= BEGIN
+
+-- -------------------------------------------------------------
+-- MIB for IEEE 802.1w Rapid Spanning Tree Protocol
+-- -------------------------------------------------------------
+
+IMPORTS
+ MODULE-IDENTITY, OBJECT-TYPE, Integer32, mib-2
+ FROM SNMPv2-SMI
+ TruthValue
+ FROM SNMPv2-TC
+ MODULE-COMPLIANCE, OBJECT-GROUP
+ FROM SNMPv2-CONF
+ dot1dStp, dot1dStpPortEntry
+ FROM BRIDGE-MIB;
+
+rstpMIB MODULE-IDENTITY
+ LAST-UPDATED "200512070000Z"
+ ORGANIZATION "IETF Bridge MIB Working Group"
+ CONTACT-INFO
+ "Email: Bridge-mib@ietf.org"
+ DESCRIPTION
+ "The Bridge MIB Extension module for managing devices
+ that support the Rapid Spanning Tree Protocol defined
+ by IEEE 802.1w.
+
+ Copyright (C) The Internet Society (2005). This version of
+ this MIB module is part of RFC 4318; See the RFC itself for
+ full legal notices."
+
+ REVISION "200512070000Z"
+ DESCRIPTION
+ "The initial version of this MIB module as published in
+ RFC 4318."
+ ::= { mib-2 134 }
+
+-- ---------------------------------------------------------- --
+-- subtrees in the RSTP-MIB
+-- ---------------------------------------------------------- --
+
+rstpNotifications OBJECT IDENTIFIER ::= { rstpMIB 0 }
+rstpObjects OBJECT IDENTIFIER ::= { rstpMIB 1 }
+rstpConformance OBJECT IDENTIFIER ::= { rstpMIB 2 }
+
+-- -------------------------------------------------------------
+-- Addition to the dot1dStp group
+-- -------------------------------------------------------------
+
+dot1dStpVersion OBJECT-TYPE
+ SYNTAX INTEGER {
+ stpCompatible(0),
+ rstp(2)
+ }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "The version of Spanning Tree Protocol the bridge is
+ currently running. The value 'stpCompatible(0)'
+ indicates the Spanning Tree Protocol specified in
+ IEEE 802.1D-1998 and 'rstp(2)' indicates the Rapid
+ Spanning Tree Protocol specified in IEEE 802.1w and
+ clause 17 of 802.1D-2004. The values are directly from
+ the IEEE standard. New values may be defined as future
+ versions of the protocol become available.
+
+ The value of this object MUST be retained across
+ reinitializations of the management system."
+ REFERENCE
+ "IEEE 802.1w clause 14.8.1, 17.12, 17.16.1"
+ DEFVAL { rstp }
+ ::= { dot1dStp 16 }
+
+dot1dStpTxHoldCount OBJECT-TYPE
+ SYNTAX Integer32 (1..10)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "The value used by the Port Transmit state machine to limit
+ the maximum transmission rate.
+
+ The value of this object MUST be retained across
+ reinitializations of the management system."
+
+ REFERENCE
+ "IEEE 802.1w clause 17.16.6"
+ DEFVAL { 3 }
+ ::= { dot1dStp 17 }
+
+--
+-- { dot1dStp 18 } was used to represent dot1dStpPathCostDefault
+-- in an earlier version of this MIB. It has since been
+-- obsoleted, and should not be used.
+--
+
+dot1dStpExtPortTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF Dot1dStpExtPortEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "A table that contains port-specific Rapid Spanning Tree
+ information."
+ ::= { dot1dStp 19 }
+
+dot1dStpExtPortEntry OBJECT-TYPE
+ SYNTAX Dot1dStpExtPortEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "A list of Rapid Spanning Tree information maintained by
+ each port."
+ AUGMENTS { dot1dStpPortEntry }
+ ::= { dot1dStpExtPortTable 1 }
+
+Dot1dStpExtPortEntry ::=
+ SEQUENCE {
+ dot1dStpPortProtocolMigration
+ TruthValue,
+ dot1dStpPortAdminEdgePort
+ TruthValue,
+ dot1dStpPortOperEdgePort
+ TruthValue,
+ dot1dStpPortAdminPointToPoint
+ INTEGER,
+ dot1dStpPortOperPointToPoint
+ TruthValue,
+ dot1dStpPortAdminPathCost
+ Integer32
+ }
+
+dot1dStpPortProtocolMigration OBJECT-TYPE
+ SYNTAX TruthValue
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "When operating in RSTP (version 2) mode, writing true(1)
+ to this object forces this port to transmit RSTP BPDUs.
+ Any other operation on this object has no effect and
+ it always returns false(2) when read."
+ REFERENCE
+ "IEEE 802.1w clause 14.8.2.4, 17.18.10, 17.26"
+ ::= { dot1dStpExtPortEntry 1 }
+
+dot1dStpPortAdminEdgePort OBJECT-TYPE
+ SYNTAX TruthValue
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "The administrative value of the Edge Port parameter. A
+ value of true(1) indicates that this port should be
+ assumed as an edge-port, and a value of false(2) indicates
+ that this port should be assumed as a non-edge-port.
+ Setting this object will also cause the corresponding
+ instance of dot1dStpPortOperEdgePort to change to the
+ same value. Note that even when this object's value
+ is true, the value of the corresponding instance of
+ dot1dStpPortOperEdgePort can be false if a BPDU has
+ been received.
+
+ The value of this object MUST be retained across
+ reinitializations of the management system."
+
+ REFERENCE
+ "IEEE 802.1t clause 14.8.2, 18.3.3"
+ ::= { dot1dStpExtPortEntry 2 }
+
+dot1dStpPortOperEdgePort OBJECT-TYPE
+ SYNTAX TruthValue
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The operational value of the Edge Port parameter. The
+ object is initialized to the value of the corresponding
+ instance of dot1dStpPortAdminEdgePort. When the
+ corresponding instance of dot1dStpPortAdminEdgePort is
+ set, this object will be changed as well. This object
+ will also be changed to false on reception of a BPDU."
+
+ REFERENCE
+ "IEEE 802.1t clause 14.8.2, 18.3.4"
+ ::= { dot1dStpExtPortEntry 3 }
+
+dot1dStpPortAdminPointToPoint OBJECT-TYPE
+ SYNTAX INTEGER {
+ forceTrue(0),
+ forceFalse(1),
+ auto(2)
+ }
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "The administrative point-to-point status of the LAN segment
+ attached to this port, using the enumeration values of the
+ IEEE 802.1w clause. A value of forceTrue(0) indicates
+ that this port should always be treated as if it is
+ connected to a point-to-point link. A value of
+ forceFalse(1) indicates that this port should be treated as
+ having a shared media connection. A value of auto(2)
+ indicates that this port is considered to have a
+ point-to-point link if it is an Aggregator and all of its
+ members are aggregatable, or if the MAC entity
+ is configured for full duplex operation, either through
+ auto-negotiation or by management means. Manipulating this
+ object changes the underlying adminPortToPortMAC.
+
+ The value of this object MUST be retained across
+ reinitializations of the management system."
+
+ REFERENCE
+ "IEEE 802.1w clause 6.4.3, 6.5, 14.8.2"
+ ::= { dot1dStpExtPortEntry 4 }
+
+dot1dStpPortOperPointToPoint OBJECT-TYPE
+ SYNTAX TruthValue
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The operational point-to-point status of the LAN segment
+ attached to this port. It indicates whether a port is
+ considered to have a point-to-point connection.
+ If adminPointToPointMAC is set to auto(2), then the value
+ of operPointToPointMAC is determined in accordance with the
+ specific procedures defined for the MAC entity concerned,
+ as defined in IEEE 802.1w, clause 6.5. The value is
+ determined dynamically; that is, it is re-evaluated whenever
+ the value of adminPointToPointMAC changes, and whenever
+ the specific procedures defined for the MAC entity evaluate
+ a change in its point-to-point status."
+ REFERENCE
+ "IEEE 802.1w clause 6.4.3, 6.5, 14.8.2"
+ ::= { dot1dStpExtPortEntry 5 }
+
+dot1dStpPortAdminPathCost OBJECT-TYPE
+ SYNTAX Integer32 (0..200000000)
+ MAX-ACCESS read-write
+ STATUS current
+ DESCRIPTION
+ "The administratively assigned value for the contribution
+ of this port to the path cost of paths toward the spanning
+ tree root.
+
+ Writing a value of '0' assigns the automatically calculated
+ default Path Cost value to the port. If the default Path
+ Cost is being used, this object returns '0' when read.
+
+ This complements the object dot1dStpPortPathCost or
+ dot1dStpPortPathCost32, which returns the operational value
+ of the path cost.
+
+ The value of this object MUST be retained across
+ reinitializations of the management system."
+ REFERENCE
+ "IEEE 802.1D-1998: Section 8.5.5.3"
+ ::= { dot1dStpExtPortEntry 6 }
+
+-- -------------------------------------------------------------
+-- rstpMIB - Conformance Information
+-- -------------------------------------------------------------
+
+rstpGroups OBJECT IDENTIFIER ::= { rstpConformance 1 }
+
+rstpCompliances OBJECT IDENTIFIER ::= { rstpConformance 2 }
+
+-- -------------------------------------------------------------
+-- Units of conformance
+-- -------------------------------------------------------------
+
+rstpBridgeGroup OBJECT-GROUP
+ OBJECTS {
+ dot1dStpVersion,
+ dot1dStpTxHoldCount
+ }
+ STATUS current
+ DESCRIPTION
+ "Rapid Spanning Tree information for the bridge."
+ ::= { rstpGroups 1 }
+
+rstpPortGroup OBJECT-GROUP
+ OBJECTS {
+ dot1dStpPortProtocolMigration,
+ dot1dStpPortAdminEdgePort,
+ dot1dStpPortOperEdgePort,
+ dot1dStpPortAdminPointToPoint,
+ dot1dStpPortOperPointToPoint,
+ dot1dStpPortAdminPathCost
+ }
+ STATUS current
+ DESCRIPTION
+ "Rapid Spanning Tree information for individual ports."
+ ::= { rstpGroups 2 }
+
+-- -------------------------------------------------------------
+-- Compliance statements
+-- -------------------------------------------------------------
+
+rstpCompliance MODULE-COMPLIANCE
+ STATUS current
+ DESCRIPTION
+ "The compliance statement for device support of Rapid
+ Spanning Tree Protocol (RSTP) bridging services."
+ MODULE
+ MANDATORY-GROUPS {
+ rstpBridgeGroup,
+ rstpPortGroup
+ }
+ ::= { rstpCompliances 1 }
+
+END
diff --git a/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_if.c b/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_if.c
index d188ab5..2805d85 100644
--- a/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_if.c
+++ b/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_if.c
@@ -674,6 +674,7 @@ int
op_dot1d_stp(struct snmp_context *ctx, struct snmp_value *value,
uint sub, uint iidx __unused, enum snmp_op op)
{
+ int ret;
struct bridge_if *bif;
if ((bif = bridge_get_default()) == NULL)
@@ -743,6 +744,11 @@ op_dot1d_stp(struct snmp_context *ctx, struct snmp_value *value,
case LEAF_dot1dStpBridgeForwardDelay:
value->v.integer = bif->bridge_fwd_delay;
break;
+ case LEAF_dot1dStpVersion:
+ value->v.integer = bif->stp_version;
+ break;
+ case LEAF_dot1dStpTxHoldCount:
+ value->v.integer = bif->tx_hold_count;
}
return (SNMP_ERR_NOERROR);
@@ -754,26 +760,32 @@ op_dot1d_stp(struct snmp_context *ctx, struct snmp_value *value,
switch (value->var.subs[sub - 1]) {
case LEAF_dot1dStpPriority:
ctx->scratch->int1 = bif->priority;
- if (bridge_set_priority(bif, value->v.integer) < 0)
- return (SNMP_ERR_GENERR);
+ ret = bridge_set_priority(bif, value->v.integer);
break;
case LEAF_dot1dStpBridgeMaxAge:
ctx->scratch->int1 = bif->bridge_max_age;
- if (bridge_set_maxage(bif, value->v.integer) < 0)
- return (SNMP_ERR_GENERR);
+ ret = bridge_set_maxage(bif, value->v.integer);
break;
case LEAF_dot1dStpBridgeHelloTime:
ctx->scratch->int1 = bif->bridge_hello_time;
- if (bridge_set_hello_time(bif, value->v.integer) < 0)
- return (SNMP_ERR_GENERR);
+ ret = bridge_set_hello_time(bif, value->v.integer);
break;
case LEAF_dot1dStpBridgeForwardDelay:
ctx->scratch->int1 = bif->bridge_fwd_delay;
- if (bridge_set_forward_delay(bif, value->v.integer) < 0)
- return (SNMP_ERR_GENERR);
+ ret = bridge_set_forward_delay(bif, value->v.integer);
+ break;
+
+ case LEAF_dot1dStpVersion:
+ ctx->scratch->int1 = bif->stp_version;
+ ret = bridge_set_stp_version(bif, value->v.integer);
+ break;
+
+ case LEAF_dot1dStpTxHoldCount:
+ ctx->scratch->int1 = bif->tx_hold_count;
+ ret = bridge_set_tx_hold_count(bif, value->v.integer);
break;
case LEAF_dot1dStpProtocolSpecification:
@@ -787,24 +799,35 @@ op_dot1d_stp(struct snmp_context *ctx, struct snmp_value *value,
case LEAF_dot1dStpHoldTime:
case LEAF_dot1dStpForwardDelay:
return (SNMP_ERR_NOT_WRITEABLE);
+ default:
+ return (SNMP_ERR_NOSUCHNAME);
}
+ if (ret == -2)
+ return (SNMP_ERR_WRONG_VALUE);
+ else if (ret < 0)
+ return (SNMP_ERR_GENERR);
return (SNMP_ERR_NOERROR);
case SNMP_OP_ROLLBACK:
switch (value->var.subs[sub - 1]) {
case LEAF_dot1dStpPriority:
- (void) bridge_set_priority(bif, ctx->scratch->int1);
+ bridge_set_priority(bif, ctx->scratch->int1);
break;
case LEAF_dot1dStpBridgeMaxAge:
- (void) bridge_set_maxage(bif, ctx->scratch->int1);
+ bridge_set_maxage(bif, ctx->scratch->int1);
break;
case LEAF_dot1dStpBridgeHelloTime:
- (void) bridge_set_hello_time(bif, ctx->scratch->int1);
+ bridge_set_hello_time(bif, ctx->scratch->int1);
break;
case LEAF_dot1dStpBridgeForwardDelay:
- (void) bridge_set_forward_delay(bif,
- ctx->scratch->int1);
+ bridge_set_forward_delay(bif, ctx->scratch->int1);
+ break;
+ case LEAF_dot1dStpVersion:
+ bridge_set_stp_version(bif, ctx->scratch->int1);
+ break;
+ case LEAF_dot1dStpTxHoldCount:
+ bridge_set_tx_hold_count(bif, ctx->scratch->int1);
break;
}
return (SNMP_ERR_NOERROR);
@@ -854,7 +877,7 @@ op_dot1d_tp(struct snmp_context *ctx, struct snmp_value *value,
case SNMP_OP_ROLLBACK:
if (value->var.subs[sub - 1] == LEAF_dot1dTpAgingTime)
- (void) bridge_set_aging_time(bif, ctx->scratch->int1);
+ bridge_set_aging_time(bif, ctx->scratch->int1);
return (SNMP_ERR_NOERROR);
case SNMP_OP_COMMIT:
@@ -1181,6 +1204,16 @@ op_begemot_stp(struct snmp_context *ctx, struct snmp_value *val,
ret = bridge_set_forward_delay(bif, val->v.integer);
break;
+ case LEAF_begemotBridgeStpVersion:
+ ctx->scratch->int1 = bif->stp_version;
+ ret = bridge_set_stp_version(bif, val->v.integer);
+ break;
+
+ case LEAF_begemotBridgeStpTxHoldCount:
+ ctx->scratch->int1 = bif->tx_hold_count;
+ ret = bridge_set_tx_hold_count(bif, val->v.integer);
+ break;
+
case LEAF_begemotBridgeStpProtocolSpecification:
case LEAF_begemotBridgeStpTimeSinceTopologyChange:
case LEAF_begemotBridgeStpTopChanges:
@@ -1220,6 +1253,14 @@ op_begemot_stp(struct snmp_context *ctx, struct snmp_value *val,
case LEAF_begemotBridgeStpBridgeForwardDelay:
bridge_set_forward_delay(bif, ctx->scratch->int1);
break;
+
+ case LEAF_begemotBridgeStpVersion:
+ bridge_set_stp_version(bif, ctx->scratch->int1);
+ break;
+
+ case LEAF_begemotBridgeStpTxHoldCount:
+ bridge_set_tx_hold_count(bif, ctx->scratch->int1);
+ break;
}
return (SNMP_ERR_NOERROR);
@@ -1284,6 +1325,14 @@ op_begemot_stp(struct snmp_context *ctx, struct snmp_value *val,
case LEAF_begemotBridgeStpBridgeForwardDelay:
val->v.integer = bif->bridge_fwd_delay;
break;
+
+ case LEAF_begemotBridgeStpVersion:
+ val->v.integer = bif->stp_version;
+ break;
+
+ case LEAF_begemotBridgeStpTxHoldCount:
+ val->v.integer = bif->tx_hold_count;
+ break;
}
return (ret);
diff --git a/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_port.c b/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_port.c
index 35b2100..44ea959 100644
--- a/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_port.c
+++ b/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_port.c
@@ -274,6 +274,17 @@ bridge_new_port(struct mibif *mif, struct bridge_if *bif)
strlcpy(bp->p_name, mif->name, IFNAMSIZ);
bp->circuit = oid_zeroDotZero;
+ /*
+ * Initialize all rstpMib specific values to false/default.
+ * These will be set to their true values later if the bridge
+ * supports RSTP.
+ */
+ bp->proto_migr = TruthValue_false;
+ bp->admin_edge = TruthValue_false;
+ bp->oper_edge = TruthValue_false;
+ bp->oper_p2p = TruthValue_false;
+ bp->admin_p2p = StpPortAdminPointToPointType_auto;
+
bridge_port_memif_insert(&bridge_ports, bp, &(bif->f_bp));
return (bp);
@@ -411,7 +422,6 @@ op_dot1d_stp_port(struct snmp_context *ctx, struct snmp_value *val,
return (SNMP_ERR_NOSUCHNAME);
bp = NULL; /* Make the compiler happy. */
- ret = SNMP_ERR_NOERROR;
switch (op) {
case SNMP_OP_GET:
@@ -437,6 +447,8 @@ op_dot1d_stp_port(struct snmp_context *ctx, struct snmp_value *val,
break;
case SNMP_OP_SET:
+ if (val->var.len - sub != 1)
+ return (SNMP_ERR_NOSUCHNAME);
if ((bp = bridge_port_find(val->var.subs[sub],
bif)) == NULL)
return (SNMP_ERR_NOSUCHNAME);
@@ -465,6 +477,8 @@ op_dot1d_stp_port(struct snmp_context *ctx, struct snmp_value *val,
case LEAF_dot1dStpPortDesignatedPort:
case LEAF_dot1dStpPortForwardTransitions:
return (SNMP_ERR_NOT_WRITEABLE);
+ default:
+ return (SNMP_ERR_NOSUCHNAME);
}
if (ret == 0)
return (SNMP_ERR_NOERROR);
@@ -495,7 +509,8 @@ op_dot1d_stp_port(struct snmp_context *ctx, struct snmp_value *val,
case SNMP_OP_COMMIT:
return (SNMP_ERR_NOERROR);
}
-
+
+ ret = SNMP_ERR_NOERROR;
switch (val->var.subs[sub - 1]) {
case LEAF_dot1dStpPort:
val->v.integer = bp->port_no;
@@ -535,8 +550,133 @@ op_dot1d_stp_port(struct snmp_context *ctx, struct snmp_value *val,
}
int
+op_dot1d_stp_ext_port(struct snmp_context *ctx, struct snmp_value *val,
+ uint sub, uint iidx __unused, enum snmp_op op)
+{
+ int ret;
+ struct bridge_if *bif;
+ struct bridge_port *bp;
+
+ if ((bif = bridge_get_default()) == NULL)
+ return (SNMP_ERR_NOSUCHNAME);
+
+ if (time(NULL) - bif->ports_age > bridge_get_data_maxage() &&
+ bridge_update_memif(bif) <= 0)
+ return (SNMP_ERR_NOSUCHNAME);
+
+ bp = NULL; /* Make the compiler happy. */
+ switch (op) {
+ case SNMP_OP_GET:
+ if (val->var.len - sub != 1)
+ return (SNMP_ERR_NOSUCHNAME);
+ if ((bp = bridge_port_find(val->var.subs[sub],
+ bif)) == NULL)
+ return (SNMP_ERR_NOSUCHNAME);
+ break;
+
+ case SNMP_OP_GETNEXT:
+ if (val->var.len - sub == 0) {
+ if ((bp = bridge_port_bif_first(bif)) == NULL)
+ return (SNMP_ERR_NOSUCHNAME);
+ } else {
+ if ((bp = bridge_port_find(val->var.subs[sub],
+ bif)) == NULL ||
+ (bp = bridge_port_bif_next(bp)) == NULL)
+ return (SNMP_ERR_NOSUCHNAME);
+ }
+ val->var.len = sub + 1;
+ val->var.subs[sub] = bp->port_no;
+ break;
+
+ case SNMP_OP_SET:
+ if (val->var.len - sub != 1)
+ return (SNMP_ERR_NOSUCHNAME);
+ if ((bp = bridge_port_find(val->var.subs[sub],
+ bif)) == NULL)
+ return (SNMP_ERR_NOSUCHNAME);
+
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_dot1dStpPortAdminEdgePort:
+ ctx->scratch->int1 = bp->admin_edge;
+ ret = bridge_port_set_admin_edge(bif->bif_name, bp,
+ val->v.integer);
+ break;
+ case LEAF_dot1dStpPortAdminPointToPoint:
+ ctx->scratch->int1 = bp->admin_p2p;
+ ret = bridge_port_set_admin_p2p(bif->bif_name, bp,
+ val->v.integer);
+ break;
+ case LEAF_dot1dStpPortAdminPathCost:
+ ctx->scratch->int1 = bp->admin_path_cost;
+ ret = bridge_port_set_path_cost(bif->bif_name, bp,
+ val->v.integer);
+ break;
+ case LEAF_dot1dStpPortProtocolMigration:
+ case LEAF_dot1dStpPortOperEdgePort:
+ case LEAF_dot1dStpPortOperPointToPoint:
+ return (SNMP_ERR_NOT_WRITEABLE);
+ default:
+ return (SNMP_ERR_NOSUCHNAME);
+ }
+
+ if (ret == 0)
+ return (SNMP_ERR_NOERROR);
+ else if (ret == -2)
+ return (SNMP_ERR_WRONG_VALUE);
+ return (SNMP_ERR_GENERR);
+
+ case SNMP_OP_ROLLBACK:
+ if ((bp = bridge_port_find(val->var.subs[sub],
+ bif)) == NULL)
+ return (SNMP_ERR_GENERR);
+
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_dot1dStpPortAdminEdgePort:
+ bridge_port_set_admin_edge(bif->bif_name, bp,
+ ctx->scratch->int1);
+ break;
+ case LEAF_dot1dStpPortAdminPointToPoint:
+ bridge_port_set_admin_p2p(bif->bif_name, bp,
+ ctx->scratch->int1);
+ break;
+ case LEAF_dot1dStpPortAdminPathCost:
+ bridge_port_set_path_cost(bif->bif_name, bp,
+ ctx->scratch->int1);
+ break;
+ }
+ return (SNMP_ERR_NOERROR);
+
+ case SNMP_OP_COMMIT:
+ return (SNMP_ERR_NOERROR);
+ }
+
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_dot1dStpPortProtocolMigration:
+ val->v.integer = bp->proto_migr;
+ break;
+ case LEAF_dot1dStpPortAdminEdgePort:
+ val->v.integer = bp->admin_edge;
+ break;
+ case LEAF_dot1dStpPortOperEdgePort:
+ val->v.integer = bp->oper_edge;
+ break;
+ case LEAF_dot1dStpPortAdminPointToPoint:
+ val->v.integer = bp->admin_p2p;
+ break;
+ case LEAF_dot1dStpPortOperPointToPoint:
+ val->v.integer = bp->oper_p2p;
+ break;
+ case LEAF_dot1dStpPortAdminPathCost:
+ val->v.integer = bp->admin_path_cost;
+ break;
+ }
+
+ return (SNMP_ERR_NOERROR);
+}
+
+int
op_dot1d_tp_port(struct snmp_context *c __unused, struct snmp_value *val,
- uint sub, uint iidx __unused, enum snmp_op op)
+ uint sub, uint iidx __unused, enum snmp_op op)
{
struct bridge_if *bif;
struct bridge_port *bp;
@@ -1064,7 +1204,6 @@ op_begemot_stp_port(struct snmp_context *ctx, struct snmp_value *val,
}
ret = SNMP_ERR_NOERROR;
-
switch (val->var.subs[sub - 1]) {
case LEAF_begemotBridgeStpPort:
val->v.integer = bp->port_no;
@@ -1102,6 +1241,114 @@ op_begemot_stp_port(struct snmp_context *ctx, struct snmp_value *val,
}
int
+op_begemot_stp_ext_port(struct snmp_context *ctx, struct snmp_value *val,
+ uint sub, uint iidx __unused, enum snmp_op op)
+{
+ int ret;
+ struct bridge_port *bp = NULL;
+ const char *b_name;
+
+ if (time(NULL) - ports_list_age > bridge_get_data_maxage())
+ bridge_update_all_ports();
+
+ switch (op) {
+ case SNMP_OP_GET:
+ if ((bp = bridge_port_index_get(&val->var, sub, 0)) == NULL)
+ return (SNMP_ERR_NOSUCHNAME);
+ break;
+
+ case SNMP_OP_GETNEXT:
+ if ((bp = bridge_port_index_getnext(&val->var, sub, 0)) ==
+ NULL || bridge_port_index_append(&val->var, sub, bp) < 0)
+ return (SNMP_ERR_NOSUCHNAME);
+ break;
+
+ case SNMP_OP_SET:
+ if ((bp = bridge_port_index_get(&val->var, sub, 0)) == NULL)
+ return (SNMP_ERR_NOSUCHNAME);
+ if ((b_name = bridge_if_find_name(bp->sysindex)) == NULL)
+ return (SNMP_ERR_GENERR);
+
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_begemotBridgeStpPortAdminEdgePort:
+ ctx->scratch->int1 = bp->admin_edge;
+ ret = bridge_port_set_admin_edge(b_name, bp,
+ val->v.integer);
+ break;
+ case LEAF_begemotBridgeStpPortAdminPointToPoint:
+ ctx->scratch->int1 = bp->admin_p2p;
+ ret = bridge_port_set_admin_p2p(b_name, bp,
+ val->v.integer);
+ break;
+ case LEAF_begemotBridgeStpPortAdminPathCost:
+ ctx->scratch->int1 = bp->admin_path_cost;
+ ret = bridge_port_set_path_cost(b_name, bp,
+ val->v.integer);
+ break;
+ case LEAF_begemotBridgeStpPortProtocolMigration:
+ case LEAF_begemotBridgeStpPortOperEdgePort:
+ case LEAF_begemotBridgeStpPortOperPointToPoint:
+ return (SNMP_ERR_NOT_WRITEABLE);
+ default:
+ return (SNMP_ERR_NOSUCHNAME);
+ }
+
+ if (ret == 0)
+ return (SNMP_ERR_NOERROR);
+ else if (ret == -2)
+ return (SNMP_ERR_WRONG_VALUE);
+ return (SNMP_ERR_GENERR);
+
+ case SNMP_OP_ROLLBACK:
+ if ((bp = bridge_port_index_get(&val->var, sub, 0)) == NULL ||
+ (b_name = bridge_if_find_name(bp->sysindex)) == NULL)
+ return (SNMP_ERR_GENERR);
+
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_begemotBridgeStpPortAdminEdgePort:
+ bridge_port_set_admin_edge(b_name, bp,
+ ctx->scratch->int1);
+ break;
+ case LEAF_begemotBridgeStpPortAdminPointToPoint:
+ bridge_port_set_admin_p2p(b_name, bp,
+ ctx->scratch->int1);
+ break;
+ case LEAF_begemotBridgeStpPortAdminPathCost:
+ bridge_port_set_path_cost(b_name, bp,
+ ctx->scratch->int1);
+ break;
+ }
+ return (SNMP_ERR_NOERROR);
+
+ case SNMP_OP_COMMIT:
+ return (SNMP_ERR_NOERROR);
+ }
+
+ switch (val->var.subs[sub - 1]) {
+ case LEAF_begemotBridgeStpPortProtocolMigration:
+ val->v.integer = bp->proto_migr;
+ break;
+ case LEAF_begemotBridgeStpPortAdminEdgePort:
+ val->v.integer = bp->admin_edge;
+ break;
+ case LEAF_begemotBridgeStpPortOperEdgePort:
+ val->v.integer = bp->oper_edge;
+ break;
+ case LEAF_begemotBridgeStpPortAdminPointToPoint:
+ val->v.integer = bp->admin_p2p;
+ break;
+ case LEAF_begemotBridgeStpPortOperPointToPoint:
+ val->v.integer = bp->oper_p2p;
+ break;
+ case LEAF_begemotBridgeStpPortAdminPathCost:
+ val->v.integer = bp->admin_path_cost;
+ break;
+ }
+
+ return (SNMP_ERR_NOERROR);
+}
+
+int
op_begemot_tp_port(struct snmp_context *c __unused, struct snmp_value *val,
uint sub, uint iidx __unused, enum snmp_op op)
{
diff --git a/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_snmp.c b/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_snmp.c
index dfcd1f9..6a13bca 100644
--- a/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_snmp.c
+++ b/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_snmp.c
@@ -119,8 +119,10 @@ bridge_set_default_name(const char *bif_name, uint len)
bcopy(bif_name, bif_default_name, len);
bif_default_name[len] = '\0';
- if ((bif = bridge_if_find_ifname(bif_default_name)) == NULL)
+ if ((bif = bridge_if_find_ifname(bif_default_name)) == NULL) {
+ bif_default = NULL;
return (0);
+ }
bif_default = bif;
return (1);
@@ -197,10 +199,16 @@ op_begemot_bridge_config(struct snmp_context *ctx, struct snmp_value *val,
return (SNMP_ERR_BADVALUE);
break;
case LEAF_begemotBridgeDataUpdate:
+ if (val->v.integer < SNMP_BRIDGE_DATA_MAXAGE_MIN ||
+ val->v.integer > SNMP_BRIDGE_DATA_MAXAGE_MAX)
+ return (SNMP_ERR_WRONG_VALUE);
ctx->scratch->int1 = bridge_data_maxage;
bridge_data_maxage = val->v.integer;
break;
case LEAF_begemotBridgeDataPoll:
+ if (val->v.integer < SNMP_BRIDGE_POLL_INTERVAL_MIN ||
+ val->v.integer > SNMP_BRIDGE_POLL_INTERVAL_MAX)
+ return (SNMP_ERR_WRONG_VALUE);
ctx->scratch->int1 = val->v.integer;
break;
}
diff --git a/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_snmp.h b/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_snmp.h
index 75d4096..6d77420 100644
--- a/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_snmp.h
+++ b/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_snmp.h
@@ -41,11 +41,32 @@ typedef u_char bridge_id[SNMP_BRIDGE_ID_LEN];
#define SNMP_BRIDGE_MIN_AGE_TIME 10
#define SNMP_BRIDGE_MAX_AGE_TIME 1000000
+#define SNMP_BRIDGE_MIN_TXHC 1
+#define SNMP_BRIDGE_MAX_TXHC 10
+
+#define SNMP_BRIDGE_MIN_MAGE 600
+#define SNMP_BRIDGE_MAX_MAGE 4000
+
+#define SNMP_BRIDGE_MIN_HTIME 100
+#define SNMP_BRIDGE_MAX_HTIME 1000
+
+#define SNMP_BRIDGE_MIN_FDELAY 400
+#define SNMP_BRIDGE_MAX_FDELAY 3000
+
#define SNMP_PORT_PATHCOST_OBSOLETE 65535
+#define SNMP_PORT_MIN_PATHCOST 0
+#define SNMP_PORT_MAX_PATHCOST 200000000
+#define SNMP_PORT_PATHCOST_AUTO 0
#define SNMP_BRIDGE_DATA_MAXAGE 10
+#define SNMP_BRIDGE_DATA_MAXAGE_MIN 1
+#define SNMP_BRIDGE_DATA_MAXAGE_MAX 300
+
/* By default poll kernel data every 5 minutes. */
#define SNMP_BRIDGE_POLL_INTERVAL (5 * 60)
+#define SNMP_BRIDGE_POLL_INTERVAL_MIN 1
+#define SNMP_BRIDGE_POLL_INTERVAL_MAX 3600
+
/* Poll for a topology change once every 30 seconds. */
#define SNMP_BRIDGE_TC_POLL_INTERVAL 30
@@ -98,6 +119,14 @@ struct bridge_port {
bridge_id design_root;
bridge_id design_bridge;
+ /* rstpMib extensions. */
+ int32_t admin_path_cost;
+ enum TruthValue proto_migr;
+ enum TruthValue admin_edge;
+ enum TruthValue oper_edge;
+ enum TruthValue oper_p2p;
+ enum StpPortAdminPointToPointType admin_p2p;
+
/* dot1dTp subtree objects. */
int32_t max_info;
int32_t in_frames;
@@ -135,7 +164,9 @@ struct bridge_if {
int32_t bridge_max_age; /* Configured max age. */
int32_t bridge_hello_time; /* Configured hello time. */
int32_t bridge_fwd_delay; /* Configured forward delay. */
+ int32_t tx_hold_count;
uint32_t top_changes;
+ enum dot1dStpVersion stp_version;
enum dot1dStpProtocolSpecification prot_spec;
struct timeval last_tc_time;
bridge_id design_root;
@@ -268,6 +299,12 @@ int bridge_set_aging_time(struct bridge_if *bif, int32_t age_time);
/* Set the max number of entries in the bridge address cache. */
int bridge_set_max_cache(struct bridge_if *bif, int32_t max_cache);
+/* Set the bridge TX hold count. */
+int bridge_set_tx_hold_count(struct bridge_if *bif, int32_t tx_hc);
+
+/* Set the bridge STP protocol version. */
+int bridge_set_stp_version(struct bridge_if *bif, int32_t stp_proto);
+
/* Set the bridge interface status to up/down. */
int bridge_set_if_up(const char* b_name, int8_t up);
@@ -292,6 +329,14 @@ int bridge_port_set_stp_enable(const char *bif_name, struct bridge_port *bp,
int bridge_port_set_path_cost(const char *bif_name, struct bridge_port *bp,
int32_t path_cost);
+/* Set admin point-to-point link. */
+int bridge_port_set_admin_p2p(const char *bif_name, struct bridge_port *bp,
+ uint32_t admin_p2p);
+
+/* Set admin edge. */
+int bridge_port_set_admin_edge(const char *bif_name, struct bridge_port *bp,
+ uint32_t enable);
+
/* Add a bridge member port. */
int bridge_port_addm(struct bridge_port *bp, const char *b_name);
diff --git a/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_sys.c b/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_sys.c
index 13b3007..585a4e2 100644
--- a/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_sys.c
+++ b/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_sys.c
@@ -238,6 +238,10 @@ bridge_get_op_param(struct bridge_if *bif)
bif->max_age = 100 * b_req.ifbop_maxage;
bif->hello_time = 100 * b_req.ifbop_hellotime;
bif->fwd_delay = 100 * b_req.ifbop_fwddelay;
+#if __FreeBSD_version > 700024
+ bif->stp_version = b_req.ifbop_protocol;
+ bif->tx_hold_count = b_req.ifbop_holdcount;
+#endif
if (b_req.ifbop_root_port == 0 &&
bif->root_port != b_req.ifbop_root_port)
@@ -312,11 +316,14 @@ bridge_set_priority(struct bridge_if *bif, int32_t priority)
* To convert a Timeout value into a value in units of
* 1/256 seconds, the following algorithm should be used:
* b = floor( (n * 256) / 100)
+ * The conversion to 1/256 of a second happens in the kernel -
+ * just make sure we correctly convert the seconds to Timout
+ * and vice versa.
*/
static uint32_t
-snmp_hundred_secs2_256(int32_t h_secs)
+snmp_timeout2_sec(int32_t secs)
{
- return ((h_secs * 256) / 100);
+ return (secs / 100);
}
int
@@ -325,10 +332,14 @@ bridge_set_maxage(struct bridge_if *bif, int32_t max_age)
struct ifdrv ifd;
struct ifbrparam b_param;
+ if (max_age < SNMP_BRIDGE_MIN_MAGE ||
+ max_age > SNMP_BRIDGE_MAX_MAGE)
+ return (-2);
+
strlcpy(ifd.ifd_name, bif->bif_name, IFNAMSIZ);
ifd.ifd_len = sizeof(b_param);
ifd.ifd_data = &b_param;
- b_param.ifbrp_maxage = (uint32_t) max_age;
+ b_param.ifbrp_maxage = snmp_timeout2_sec(max_age);
ifd.ifd_cmd = BRDGSMA;
if (ioctl(sock, SIOCSDRVSPEC, &ifd) < 0) {
@@ -347,10 +358,14 @@ bridge_set_hello_time(struct bridge_if *bif, int32_t hello_time)
struct ifdrv ifd;
struct ifbrparam b_param;
+ if (hello_time < SNMP_BRIDGE_MIN_HTIME ||
+ hello_time > SNMP_BRIDGE_MAX_HTIME)
+ return (-2);
+
strlcpy(ifd.ifd_name, bif->bif_name, IFNAMSIZ);
ifd.ifd_len = sizeof(b_param);
ifd.ifd_data = &b_param;
- b_param.ifbrp_hellotime = snmp_hundred_secs2_256(hello_time);
+ b_param.ifbrp_hellotime = snmp_timeout2_sec(hello_time);
ifd.ifd_cmd = BRDGSHT;
if (ioctl(sock, SIOCSDRVSPEC, &ifd) < 0) {
@@ -369,10 +384,14 @@ bridge_set_forward_delay(struct bridge_if *bif, int32_t fwd_delay)
struct ifdrv ifd;
struct ifbrparam b_param;
+ if (fwd_delay < SNMP_BRIDGE_MIN_FDELAY ||
+ fwd_delay > SNMP_BRIDGE_MAX_FDELAY)
+ return (-2);
+
strlcpy(ifd.ifd_name, bif->bif_name, IFNAMSIZ);
ifd.ifd_len = sizeof(b_param);
ifd.ifd_data = &b_param;
- b_param.ifbrp_fwddelay = snmp_hundred_secs2_256(fwd_delay);
+ b_param.ifbrp_fwddelay = snmp_timeout2_sec(fwd_delay);
ifd.ifd_cmd = BRDGSFD;
if (ioctl(sock, SIOCSDRVSPEC, &ifd) < 0) {
@@ -434,6 +453,67 @@ bridge_set_max_cache(struct bridge_if *bif, int32_t max_cache)
return (0);
}
+int
+bridge_set_tx_hold_count(struct bridge_if *bif __unused,
+ int32_t tx_hc __unused)
+{
+#if __FreeBSD_version > 700024
+ struct ifdrv ifd;
+ struct ifbrparam b_param;
+
+ if (tx_hc < SNMP_BRIDGE_MIN_TXHC || tx_hc > SNMP_BRIDGE_MAX_TXHC)
+ return (-1);
+
+ strlcpy(ifd.ifd_name, bif->bif_name, IFNAMSIZ);
+ ifd.ifd_len = sizeof(b_param);
+ ifd.ifd_data = &b_param;
+ b_param.ifbrp_txhc = tx_hc;
+ ifd.ifd_cmd = BRDGSTXHC;
+
+ if (ioctl(sock, SIOCSDRVSPEC, &ifd) < 0) {
+ syslog(LOG_ERR, "set bridge param: ioctl(BRDGSTXHC) "
+ "failed: %s", strerror(errno));
+ return (-1);
+ }
+
+ bif->tx_hold_count = b_param.ifbrp_txhc;
+ return (0);
+#else
+ return (-1);
+#endif
+}
+
+int
+bridge_set_stp_version(struct bridge_if *bif __unused,
+ int32_t stp_proto __unused)
+{
+#if __FreeBSD_version > 700024
+ struct ifdrv ifd;
+ struct ifbrparam b_param;
+
+ if (stp_proto != dot1dStpVersion_stpCompatible &&
+ stp_proto != dot1dStpVersion_rstp)
+ return (-2);
+
+ strlcpy(ifd.ifd_name, bif->bif_name, IFNAMSIZ);
+ ifd.ifd_len = sizeof(b_param);
+ ifd.ifd_data = &b_param;
+ b_param.ifbrp_proto = stp_proto;
+ ifd.ifd_cmd = BRDGSPROTO;
+
+ if (ioctl(sock, SIOCSDRVSPEC, &ifd) < 0) {
+ syslog(LOG_ERR, "set bridge param: ioctl(BRDGSPROTO) "
+ "failed: %s", strerror(errno));
+ return (-1);
+ }
+
+ bif->stp_version = b_param.ifbrp_proto;
+ return (0);
+#else
+ return (-1);
+#endif
+}
+
/*
* Set the bridge interface status to up/down.
*/
@@ -580,6 +660,9 @@ state2snmp_st(uint8_t ifbr_state)
case BSTP_IFSTATE_FORWARDING:
return (StpPortState_forwarding);
case BSTP_IFSTATE_BLOCKING:
+#if __FreeBSD_version > 700024
+ case BSTP_IFSTATE_DISCARDING:
+#endif
return (StpPortState_blocking);
}
@@ -605,20 +688,12 @@ bridge_port_getinfo_conf(struct ifbreq *k_info, struct bridge_port *bp)
* the maximum value."
*/
-#if 0
- /*
- * Kernel variable is a 32-bit integer but the ioctl supports
- * only getting/setting a 8-bit value.
- */
-
- if (k_info->ifbr_path_cost > SNMP_PORT_PATHCOST_OBSOLETE) {
- bp->path_cost = SNMP_PORT_PATHCOST_OBSOLETE;
- bp->path_cost32 = k_info->ifbr_path_cost;
- } else
-
- bp->path_cost = bp->path_cost32 = k_info->ifbr_path_cost;
+#if __FreeBSD_version > 700024
+ if (k_info->ifbr_ifsflags & IFBIF_BSTP_ADMCOST)
+ bp->admin_path_cost = k_info->ifbr_path_cost;
+ else
+ bp->admin_path_cost = 0;
#endif
-
bp->path_cost = k_info->ifbr_path_cost;
if (k_info->ifbr_ifsflags & IFBIF_STP)
@@ -631,6 +706,32 @@ bridge_port_getinfo_conf(struct ifbreq *k_info, struct bridge_port *bp)
bp->span_enable = begemotBridgeBaseSpanEnabled_enabled;
else
bp->span_enable = begemotBridgeBaseSpanEnabled_disabled;
+
+#if __FreeBSD_version > 700024
+ if (k_info->ifbr_ifsflags & IFBIF_BSTP_ADMEDGE)
+ bp->admin_edge = TruthValue_true;
+ else
+ bp->admin_edge = TruthValue_false;
+
+ if (k_info->ifbr_ifsflags & IFBIF_BSTP_EDGE)
+ bp->oper_edge = TruthValue_true;
+ else
+ bp->oper_edge = TruthValue_false;
+
+ if (k_info->ifbr_ifsflags & IFBIF_BSTP_AUTOP2P) {
+ bp->admin_p2p = StpPortAdminPointToPointType_auto;
+ if (k_info->ifbr_ifsflags & IFBIF_BSTP_P2P)
+ bp->oper_p2p = TruthValue_true;
+ else
+ bp->oper_p2p = TruthValue_false;
+ } else if (k_info->ifbr_ifsflags & IFBIF_BSTP_P2P) {
+ bp->admin_p2p = StpPortAdminPointToPointType_forceTrue;
+ bp->oper_p2p = TruthValue_true;
+ } else {
+ bp->admin_p2p = StpPortAdminPointToPointType_forceFalse;
+ bp->oper_p2p = TruthValue_false;
+ }
+#endif
}
/*
@@ -753,15 +854,22 @@ bridge_port_set_path_cost(const char *bif_name, struct bridge_port *bp,
struct ifdrv ifd;
struct ifbreq b_req;
- if (path_cost > SNMP_PORT_PATHCOST_OBSOLETE)
+#if __FreeBSD_version > 700024
+ if (path_cost < SNMP_PORT_MIN_PATHCOST ||
+ path_cost > SNMP_PORT_MAX_PATHCOST)
+ return (-2);
+#else
+ if (path_cost < SNMP_PORT_MIN_PATHCOST ||
+ path_cost > SNMP_PORT_PATHCOST_OBSOLETE)
return (-2);
+#endif
strlcpy(ifd.ifd_name, bif_name, sizeof(ifd.ifd_name));
ifd.ifd_len = sizeof(b_req);
ifd.ifd_data = &b_req;
strlcpy(b_req.ifbr_ifsname, bp->p_name, sizeof(b_req.ifbr_ifsname));
- b_req.ifbr_path_cost = (uint16_t) path_cost;
+ b_req.ifbr_path_cost = path_cost;
ifd.ifd_cmd = BRDGSIFCOST;
if (ioctl(sock, SIOCSDRVSPEC, &ifd) < 0) {
@@ -770,8 +878,121 @@ bridge_port_set_path_cost(const char *bif_name, struct bridge_port *bp,
return (-1);
}
+#if __FreeBSD_version > 700024
+ bp->admin_path_cost = path_cost;
+#else
bp->path_cost = path_cost;
+#endif
+
+ return (0);
+}
+
+/*
+ * Set the PonitToPoint status of the link administratively.
+ */
+int
+bridge_port_set_admin_p2p(const char *bif_name __unused,
+ struct bridge_port *bp __unused, uint32_t admin_p2p __unused)
+{
+#if __FreeBSD_version > 700024
+ struct ifdrv ifd;
+ struct ifbreq b_req;
+
+ if (bp->admin_p2p == admin_p2p)
+ return (0);
+
+ if (admin_p2p > StpPortAdminPointToPointType_auto)
+ return (-2);
+
+ bzero(&b_req, sizeof(b_req));
+ strlcpy(ifd.ifd_name, bif_name, sizeof(ifd.ifd_name));
+ ifd.ifd_len = sizeof(b_req);
+ ifd.ifd_data = &b_req;
+ strlcpy(b_req.ifbr_ifsname, bp->p_name, sizeof(b_req.ifbr_ifsname));
+ ifd.ifd_cmd = BRDGGIFFLGS;
+
+ if (ioctl(sock, SIOCGDRVSPEC, &ifd) < 0) {
+ syslog(LOG_ERR, "get member %s param: ioctl(BRDGGIFFLGS) "
+ "failed: %s", bp->p_name, strerror(errno));
+ return (-1);
+ }
+
+ switch (admin_p2p) {
+ case StpPortAdminPointToPointType_forceTrue:
+ b_req.ifbr_ifsflags &= ~IFBIF_BSTP_AUTOP2P;
+ b_req.ifbr_ifsflags |= IFBIF_BSTP_P2P;
+ break;
+ case StpPortAdminPointToPointType_forceFalse:
+ b_req.ifbr_ifsflags &= ~IFBIF_BSTP_AUTOP2P;
+ b_req.ifbr_ifsflags &= ~IFBIF_BSTP_P2P;
+ break;
+ case StpPortAdminPointToPointType_auto:
+ b_req.ifbr_ifsflags |= IFBIF_BSTP_AUTOP2P;
+ break;
+ }
+
+ ifd.ifd_cmd = BRDGSIFFLGS;
+ if (ioctl(sock, SIOCSDRVSPEC, &ifd) < 0) {
+ syslog(LOG_ERR, "set member %s param: ioctl(BRDGSIFFLGS) "
+ "failed: %s", bp->p_name, strerror(errno));
+ return (-1);
+ }
+
+ bp->admin_p2p = admin_p2p;
return (0);
+#else
+ return (-1);
+#endif
+}
+
+/*
+ * Set admin edge.
+ */
+int
+bridge_port_set_admin_edge(const char *bif_name __unused,
+ struct bridge_port *bp __unused, uint32_t enable __unused)
+{
+#if __FreeBSD_version > 700024
+ struct ifdrv ifd;
+ struct ifbreq b_req;
+
+ if (bp->admin_edge == enable)
+ return (0);
+
+ if (enable != TruthValue_true && enable != TruthValue_false)
+ return (-2);
+
+ bzero(&b_req, sizeof(b_req));
+ strlcpy(ifd.ifd_name, bif_name, sizeof(ifd.ifd_name));
+ ifd.ifd_len = sizeof(b_req);
+ ifd.ifd_data = &b_req;
+ strlcpy(b_req.ifbr_ifsname, bp->p_name, sizeof(b_req.ifbr_ifsname));
+ ifd.ifd_cmd = BRDGGIFFLGS;
+
+ if (ioctl(sock, SIOCGDRVSPEC, &ifd) < 0) {
+ syslog(LOG_ERR, "get member %s param: ioctl(BRDGGIFFLGS) "
+ "failed: %s", bp->p_name, strerror(errno));
+ return (-1);
+ }
+
+ if (enable == TruthValue_true) {
+ b_req.ifbr_ifsflags &= ~IFBIF_BSTP_AUTOEDGE;
+ b_req.ifbr_ifsflags |= IFBIF_BSTP_EDGE;
+ } else
+ b_req.ifbr_ifsflags &= ~IFBIF_BSTP_EDGE;
+
+ ifd.ifd_cmd = BRDGSIFFLGS;
+ if (ioctl(sock, SIOCSDRVSPEC, &ifd) < 0) {
+ syslog(LOG_ERR, "set member %s param: ioctl(BRDGSIFFLGS) "
+ "failed: %s", bp->p_name, strerror(errno));
+ return (-1);
+ }
+
+ bp->admin_edge = enable;
+ return (0);
+#else
+ return (-1);
+#endif
}
/*
@@ -899,7 +1120,7 @@ bridge_port_get_ifstplist(struct bridge_if *bif, char **buf)
struct ifbpstpconf ifbstp;
struct ifdrv ifd;
- *buf = NULL;
+ *buf = NULL;
strlcpy(ifd.ifd_name, bif->bif_name, IFNAMSIZ);
ifd.ifd_cmd = BRDGGIFSSTP;
ifd.ifd_len = sizeof(ifbstp);
diff --git a/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_tree.def b/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_tree.def
index 892615b..5a161af 100644
--- a/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_tree.def
+++ b/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_tree.def
@@ -51,6 +51,12 @@ typedef StpPortState ENUM (
6 broken
)
+typedef StpPortAdminPointToPointType ENUM (
+ 0 forceTrue
+ 1 forceFalse
+ 2 auto
+)
+
typedef BaseType ENUM (
1 unknown
2 transparent-only
@@ -115,6 +121,17 @@ typedef TpFdbStatus ENUM (
(9 dot1dStpPortDesignatedPort OCTETSTRING | BridgePortId GET)
(10 dot1dStpPortForwardTransitions COUNTER GET)
))
+ (16 dot1dStpVersion ENUM ( 0 stpCompatible 2 rstp ) op_dot1d_stp GET SET)
+ (17 dot1dStpTxHoldCount INTEGER op_dot1d_stp GET SET)
+ (19 dot1dStpExtPortTable
+ (1 dot1dStpExtPortEntry : INTEGER op_dot1d_stp_ext_port
+ (1 dot1dStpPortProtocolMigration TruthValue GET) # SET
+ (2 dot1dStpPortAdminEdgePort TruthValue GET SET)
+ (3 dot1dStpPortOperEdgePort TruthValue GET)
+ (4 dot1dStpPortAdminPointToPoint StpPortAdminPointToPointType GET SET)
+ (5 dot1dStpPortOperPointToPoint TruthValue GET)
+ (6 dot1dStpPortAdminPathCost INTEGER GET SET)
+ ))
)
(3 dot1dSr
)
@@ -144,6 +161,18 @@ typedef TpFdbStatus ENUM (
(2 dot1dCompliances
)
)
+ )
+ (134 rstpMIB
+ (0 rstpNotifications
+ )
+ (1 rstpObjects
+ )
+ (2 rstpConformance
+ (1 rstpGroups
+ )
+ (2 rstpCompliances
+ )
+ )
)))
(4 private
(1 enterprises
@@ -190,6 +219,8 @@ typedef TpFdbStatus ENUM (
(12 begemotBridgeStpBridgeMaxAge INTEGER GET SET)
(13 begemotBridgeStpBridgeHelloTime INTEGER GET SET)
(14 begemotBridgeStpBridgeForwardDelay INTEGER GET SET)
+ (15 begemotBridgeStpVersion ENUM ( 0 stpCompatible 2 rstp ) GET SET)
+ (16 begemotBridgeStpTxHoldCount INTEGER GET SET)
))
(2 begemotBridgeStpPortTable
(1 begemotBridgeStpPortEntry : OCTETSTRING | BridgeIfName INTEGER op_begemot_stp_port
@@ -204,6 +235,15 @@ typedef TpFdbStatus ENUM (
(9 begemotBridgeStpPortDesignatedPort OCTETSTRING | BridgePortId GET)
(10 begemotBridgeStpPortForwardTransitions COUNTER GET)
))
+ (3 begemotBridgeStpExtPortTable
+ (1 begemotBridgeStpExtPortEntry : OCTETSTRING | BridgeIfName INTEGER op_begemot_stp_ext_port
+ (1 begemotBridgeStpPortProtocolMigration TruthValue GET) # SET
+ (2 begemotBridgeStpPortAdminEdgePort TruthValue GET SET)
+ (3 begemotBridgeStpPortOperEdgePort TruthValue GET)
+ (4 begemotBridgeStpPortAdminPointToPoint StpPortAdminPointToPointType GET SET)
+ (5 begemotBridgeStpPortOperPointToPoint TruthValue GET)
+ (6 begemotBridgeStpPortAdminPathCost INTEGER GET SET)
+ ))
)
(3 begemotBridgeTp
(1 begemotBridgeTpTable
diff --git a/usr.sbin/bsnmpd/modules/snmp_bridge/snmp_bridge.3 b/usr.sbin/bsnmpd/modules/snmp_bridge/snmp_bridge.3
index cc942b4..204912a 100644
--- a/usr.sbin/bsnmpd/modules/snmp_bridge/snmp_bridge.3
+++ b/usr.sbin/bsnmpd/modules/snmp_bridge/snmp_bridge.3
@@ -25,7 +25,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd August 18, 2006
+.Dd December 8, 2006
.Dt snmp_bridge 3
.Os
.Sh NAME
@@ -36,8 +36,9 @@
.Sh DESCRIPTION
The
.Nm snmp_bridge
-module implements the BRIDGE-MIB as standardized in RFC 4188 and a private
-BEGEMOT-BRIDGE-MIB, which allows management of multiple bridge interfaces.
+module implements the BRIDGE-MIB as standardized in RFC 4188, the RSTP-MIB
+standardized in RFC4318 and a private BEGEMOT-BRIDGE-MIB, which allows
+management of multiple bridge interfaces.
Most of the objects defined in the private BEGEMOT-BRIDGE-MIB are duplicates
of the original objects defined by the standard BRIDGE-MIB, but the private
MIB also defines additional objects which make the functionality of
@@ -100,6 +101,8 @@ The description of the MIB tree implemented by
.Nm .
.It Pa /usr/share/snmp/mibs/BRIDGE-MIB.txt
This is the BRIDGE-MIB that is implemented by this module.
+.It Pa /usr/share/snmp/mibs/RSTP-MIB.txt
+This is the RSTP-MIB implemented by this module.
.It Pa /usr/share/snmp/mibs/BEGEMOT-BRIDGE-MIB.txt
This is the private BEGEMOT-BRIDGE-MIB that is implemented by this module.
.El
OpenPOWER on IntegriCloud