Add support for RSTP (RFC4318) to the SNMP bridge monitoring module.

Approved by:	bz (mentor)
This commit is contained in:
Shteryana Shopova 2006-12-07 22:36:17 +00:00
parent 0e0521a153
commit b5906f8eed
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=164997
10 changed files with 1170 additions and 47 deletions

View File

@ -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
-- ---------------------------------------------------------- --
@ -619,6 +662,148 @@ begemotBridgeStpPortForwardTransitions OBJECT-TYPE
from the Learning state to the Forwarding state."
::= { 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
-- ---------------------------------------------------------- --

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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;
@ -534,9 +549,134 @@ op_dot1d_stp_port(struct snmp_context *ctx, struct snmp_value *val,
return (ret);
}
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;
@ -1101,6 +1240,114 @@ op_begemot_stp_port(struct snmp_context *ctx, struct snmp_value *val,
return (ret);
}
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)

View File

@ -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;
}

View File

@ -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);

View File

@ -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,10 +878,123 @@ 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
}
/*
* Add a bridge member port.
*/
@ -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);

View File

@ -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

View File

@ -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