Index: usr.sbin/bsnmpd/modules/snmp_vlan/BEGEMOT-VLAN-MIB.txt =================================================================== --- usr.sbin/bsnmpd/modules/snmp_vlan/BEGEMOT-VLAN-MIB.txt (revision 0) +++ usr.sbin/bsnmpd/modules/snmp_vlan/BEGEMOT-VLAN-MIB.txt (working copy) @@ -0,0 +1,481 @@ +-- +-- Copyright (C) 2007-2008 Shteryana Shopova +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions +-- are met: +-- 1. Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND +-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +-- ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE +-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +-- SUCH DAMAGE. +-- +-- $FreeBSD$ +-- + +BEGEMOT-VLAN-MIB DEFINITIONS ::= BEGIN + +IMPORTS + MODULE-IDENTITY, OBJECT-TYPE, NOTIFICATION-TYPE, + Counter32, Integer32, TimeTicks, mib-2 + FROM SNMPv2-SMI + TEXTUAL-CONVENTION, MacAddress, TruthValue, + RowStatus, TimeStamp + FROM SNMPv2-TC + InterfaceIndexOrZero FROM IF-MIB + Timeout FROM BRIDGE-MIB + VlanId FROM Q-BRIDGE-MIB + EnabledStatus FROM P-BRIDGE-MIB + begemot + FROM BEGEMOT-MIB; + +begemotVlan MODULE-IDENTITY + LAST-UPDATED "200803040000Z" + ORGANIZATION "Sofia University St. Kliment Ohridski" + CONTACT-INFO + " + Shteryana Shopova + + Postal: Faculty of Mathematics and Informatics + 5 James Bourchier Blvd. + 1164 Sofia + Bulgaria + + Fax: +359 2 687 180 + + E-Mail: syrinx@FreeBSD.org" + DESCRIPTION + "The Begemot MIB for managing vlan interfaces." + REVISION "200803040000Z" + DESCRIPTION + "Added begemotVlanParentIfHwCSumSupported and + begemotVlanParentIfHwCSumEnabled objects." + REVISION "200701090000Z" + DESCRIPTION + "Initial revision." + ::= { begemot 206 } + +-- ---------------------------------------------------------- -- +BegemotVlanBitMap ::= TEXTUAL-CONVENTION + STATUS current + DESCRIPTION + "Each octet within this value specifies a set of eight + VlanIds, with the first octet specifying VlanIds 1 through + 8, the second octet specifying VlanIds 9 through 16, etc. + Within each octet, the most significant bit represents + the smallest VlanId, and the least significant bit + represents the biggest VlanId. Thus, each VlanId that can + be represented by a 12-bit Integer is represented by a + single bit within the value of this object. If that bit + has a value of '1' then that VlanId is included in the set + of VlanIds; the VlanId is not included if its bit has a + value of '0'." + SYNTAX OCTET STRING (SIZE(512)) + +-- ---------------------------------------------------------- -- +-- subtrees in the Begemot Vlan MIB +-- ---------------------------------------------------------- -- +begemotVlanConfig OBJECT IDENTIFIER ::= { begemotVlan 1 } + +begemotVlanTrunks OBJECT IDENTIFIER ::= { begemotVlan 2 } + +begemotVlanInterfaces OBJECT IDENTIFIER ::= { begemotVlan 3 } + +begemotVlanStatistics OBJECT IDENTIFIER ::= { begemotVlan 4 } + +-- ---------------------------------------------------------- -- +-- the begemotVlanConfig objects +-- ---------------------------------------------------------- -- + +begemotVlanMaxId OBJECT-TYPE + SYNTAX VlanId + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The maximum IEEE 802.1Q VLAN ID that the system + supports." + ::= { begemotVlanConfig 1 } + +begemotVlanNumVlans OBJECT-TYPE + SYNTAX INTEGER + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The current number of vlan interfaces on the system." + ::= { begemotVlanConfig 2 } + +begemotVlanDataPoll OBJECT-TYPE + SYNTAX Timeout (1..3600) + UNITS "seconds" + MAX-ACCESS read-write + STATUS current + DESCRIPTION + "The polling rate of data when the module is idle." + DEFVAL { 300 } + ::= { begemotVlanConfig 3 } + +begemotVlanSoftPad OBJECT-TYPE + SYNTAX EnabledStatus + MAX-ACCESS read-write + STATUS current + DESCRIPTION + "The value of this object indicates whether padding + of short frames before tagging them is enabled." + ::= { begemotVlanConfig 4 } + +-- ---------------------------------------------------------- -- +-- the begemot Vlan Trunk table +-- ---------------------------------------------------------- -- + +begemotVlanTrunkTable OBJECT-TYPE + SYNTAX SEQUENCE OF BegemotVlanTrunkEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "A table that contains information about physical + interfaces that are configured to demultiplex tagged + frames." + ::= { begemotVlanTrunks 1 } + +begemotVlanTrunkEntry OBJECT-TYPE + SYNTAX BegemotVlanTrunkEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "A list of information about physical interfaces that + are configured to demultiplex tagged frames." + INDEX { begemotVlanTrunkIndex } + ::= { begemotVlanTrunkTable 1 } + +BegemotVlanTrunkEntry ::= SEQUENCE { + begemotVlanTrunkIndex InterfaceIndexOrZero, + begemotVlanParentIfName OCTET STRING, + begemotVlanParentIfHwTagSupported TruthValue, + begemotVlanParentIfHwTagEnabled EnabledStatus, + begemotVlanParentIfHwMtuSupported TruthValue, + begemotVlanParentIfHwMtuEnabled EnabledStatus, + begemotVlanParentIfHwCSumSupported TruthValue, + begemotVlanParentIfHwCSumEnabled EnabledStatus, + begemotVlanTrunkMembers INTEGER, + begemotVlanTrunkMemberVids BegemotVlanBitMap +} + +begemotVlanTrunkIndex OBJECT-TYPE + SYNTAX InterfaceIndexOrZero + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The value of the instance of the ifIndex object, defined + in IF-MIB, for the parent interface corresponding to this + vlan trunk. A value of zero is reserved for a generic parent + interface for vlan interfaces that are in the process of + being configured and have no parent interface assigned." + ::= { begemotVlanTrunkEntry 1 } + +-- begemotVlanParentIfName object is redundant since its value can +-- be obtained by a SNMP client by invoking a GET on the ifName +-- object with an index of the corresponding value of +-- begemotVlanTrunkIndex, but is included for convenience. + +begemotVlanParentIfName OBJECT-TYPE + SYNTAX OCTET STRING (SIZE(1..16)) + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The value of the instance of the ifName object, defined + in IF-MIB, for the parent interface corresponding to this + vlan trunk." + ::= { begemotVlanTrunkEntry 2 } + +begemotVlanParentIfHwTagSupported OBJECT-TYPE + SYNTAX TruthValue + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The value of this object indicates whether the parent + interface of the vlan trunk supports vlan tagging + natively." + ::= { begemotVlanTrunkEntry 3 } + +begemotVlanParentIfHwTagEnabled OBJECT-TYPE + SYNTAX EnabledStatus + MAX-ACCESS read-write + STATUS current + DESCRIPTION + "The value of this object indicates whether the parent + interface of the vlan trunk is configured to do vlan + tagging natively." + ::= { begemotVlanTrunkEntry 4 } + +begemotVlanParentIfHwMtuSupported OBJECT-TYPE + SYNTAX TruthValue + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The value of this object indicates whether the parent + interface of the vlan trunk supports oversized frames + natively." + ::= { begemotVlanTrunkEntry 5 } + +begemotVlanParentIfHwMtuEnabled OBJECT-TYPE + SYNTAX EnabledStatus + MAX-ACCESS read-write + STATUS current + DESCRIPTION + "The value of this object indicates whether the parent + interface of the vlan trunk is configured to receive + extended frames in hardware." + ::= { begemotVlanTrunkEntry 6 } + +begemotVlanParentIfHwCSumSupported OBJECT-TYPE + SYNTAX TruthValue + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The value of this object indicates whether the parent + interface of the vlan trunk supports hardware checksum + on VLANs natively." + ::= { begemotVlanTrunkEntry 7 } + +begemotVlanParentIfHwCSumEnabled OBJECT-TYPE + SYNTAX EnabledStatus + MAX-ACCESS read-write + STATUS current + DESCRIPTION + "The value of this object indicates whether the parent + interface of the vlan trunk is configured to do + hardware checksums on VLANs." + ::= { begemotVlanTrunkEntry 8 } + +begemotVlanTrunkMembers OBJECT-TYPE + SYNTAX INTEGER (1..4096) + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of vlan interfaces currently belonging to + this trunk." + ::= { begemotVlanTrunkEntry 9 } + +begemotVlanTrunkMemberVids OBJECT-TYPE + SYNTAX BegemotVlanBitMap + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The set of VlanIds for which a frame, containing one + of these is being proccessed rather than discared by the + parent interface of the vlan trunk." + ::= { begemotVlanTrunkEntry 10 } + +-- ---------------------------------------------------------- -- +-- the begemot Vlan interfaces table +-- ---------------------------------------------------------- -- + +begemotVlanInterfaceTable OBJECT-TYPE + SYNTAX SEQUENCE OF BegemotVlanInterfaceEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "A table containing of information for the vlan + interfaces on the managed device." + ::= { begemotVlanInterfaces 1 } + +begemotVlanInterfaceEntry OBJECT-TYPE + SYNTAX BegemotVlanInterfaceEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "A list of information for the vlan interfaces on + the managed device." + INDEX { begemotVlanTrunkIndex, begemotVlanIfName } + ::= { begemotVlanInterfaceTable 1 } + +BegemotVlanInterfaceEntry ::= SEQUENCE { + begemotVlanIfName OCTET STRING, + begemotVlanIfVid INTEGER, + begemotVlanIfProto INTEGER, + begemotVlanIfStatus RowStatus, + begemotVlanIfEncaplen INTEGER, + begemotVlanIfMtuFudge INTEGER, + begemotVlanIfMinTU INTEGER +} + +begemotVlanIfName OBJECT-TYPE + SYNTAX OCTET STRING (SIZE(1..16)) + MAX-ACCESS read-write + STATUS current + DESCRIPTION + "The name of the vlan interface." + ::= { begemotVlanInterfaceEntry 1 } + +begemotVlanIfVid OBJECT-TYPE + SYNTAX INTEGER (1..4095) + MAX-ACCESS read-write + STATUS current + DESCRIPTION + "The vlan tag that is applied on packets leaving + this interface." + ::= { begemotVlanInterfaceEntry 2 } + +begemotVlanIfProto OBJECT-TYPE + SYNTAX INTEGER (1..65535) + MAX-ACCESS read-write + STATUS current + DESCRIPTION + "The encapsulation ethertype that is applied on + packets leaving this interface." + ::= { begemotVlanInterfaceEntry 3 } + +begemotVlanIfStatus OBJECT-TYPE + SYNTAX RowStatus + MAX-ACCESS read-create + STATUS current + DESCRIPTION + "Used to create/destroy vlan interfaces on the + managed device." + ::= { begemotVlanInterfaceEntry 4 } + +begemotVlanIfEncaplen OBJECT-TYPE + SYNTAX INTEGER + MAX-ACCESS read-write + STATUS current + DESCRIPTION + "The length of encapsulation data that is applied on + packets leaving this interface." + ::= { begemotVlanInterfaceEntry 5 } + +begemotVlanIfMtuFudge OBJECT-TYPE + SYNTAX INTEGER + MAX-ACCESS read-write + STATUS current + DESCRIPTION + "The value by which the MTU is reduced on the parent + interface of this vlan interface." + ::= { begemotVlanInterfaceEntry 6 } + +begemotVlanIfMinTU OBJECT-TYPE + SYNTAX INTEGER + MAX-ACCESS read-write + STATUS current + DESCRIPTION + "The minumum transmission unit of the vlan interface." + ::= { begemotVlanInterfaceEntry 7 } + +-- ---------------------------------------------------------- -- +-- the begemot Vlan interface statistics table +-- ---------------------------------------------------------- -- + +begemotVlanIfStatsTable OBJECT-TYPE + SYNTAX SEQUENCE OF BegemotVlanIfStatsEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "A table containing statistics for the vlan + interfaces on the managed device." + ::= { begemotVlanStatistics 1 } + +begemotVlanIfStatsEntry OBJECT-TYPE + SYNTAX BegemotVlanIfStatsEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "A list of statistics for a vlan interface on + the managed device." + AUGMENTS { begemotVlanInterfaceEntry } + ::= { begemotVlanIfStatsTable 1 } + +BegemotVlanIfStatsEntry ::= SEQUENCE { + begemotVlanIfInFrames Counter32, + begemotVlanIfOutFrames Counter32, + begemotVlanIfInDiscards Counter32, + begemotVlanIfInOverflowFrames Counter32, + begemotVlanIfOutOverflowFrames Counter32, + begemotVlanIfInOverflowDiscards Counter32, + begemotVlanIfDiscontinuityTime TimeStamp +} + +begemotVlanIfInFrames OBJECT-TYPE + SYNTAX Counter32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of valid frames received on this + vlan interface which were classified as belonging + to this VLAN." + ::= { begemotVlanIfStatsEntry 1 } + +begemotVlanIfOutFrames OBJECT-TYPE + SYNTAX Counter32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of valid frames transmitted by this + vlan interface." + ::= { begemotVlanIfStatsEntry 2 } + +begemotVlanIfInDiscards OBJECT-TYPE + SYNTAX Counter32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of valid frames received on this + vlan interface which were classified as belonging + to this VLAN but were discarded." + ::= { begemotVlanIfStatsEntry 3 } + +begemotVlanIfInOverflowFrames OBJECT-TYPE + SYNTAX Counter32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of times the associated + begemotVlanIfInFrames counter has overflowed." + ::= { begemotVlanIfStatsEntry 4 } + +begemotVlanIfOutOverflowFrames OBJECT-TYPE + SYNTAX Counter32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of times the associated + begemotVlanIfOutFrames counter has overflowed." + ::= { begemotVlanIfStatsEntry 5 } + +begemotVlanIfInOverflowDiscards OBJECT-TYPE + SYNTAX Counter32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of times the associated + begemotVlanIfInDiscards counter has overflowed." + ::= { begemotVlanIfStatsEntry 6 } + +begemotVlanIfDiscontinuityTime OBJECT-TYPE + SYNTAX TimeStamp + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The value of sysUpTime on the most recent occasion at which + any one or more of this interface's counters suffered a + discontinuity. The relevant counters are the specific + instances associated with this interface of any Counter32 + object contained in the begemotVlanIfStatsTable. If + no such discontinuities have occurred since the last re- + initialization of the local management subsystem, then this + object contains a zero value." + ::= { begemotVlanIfStatsEntry 7 } + +END + Index: usr.sbin/bsnmpd/modules/snmp_vlan/vlan_snmp.h =================================================================== --- usr.sbin/bsnmpd/modules/snmp_vlan/vlan_snmp.h (revision 0) +++ usr.sbin/bsnmpd/modules/snmp_vlan/vlan_snmp.h (working copy) @@ -0,0 +1,70 @@ +/*- + * Copyright (c) 2008 Shteryana Shopova + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * VLAN MIB implementation for SNMPd. + * + * $FreeBSD$ + */ + +#define VLAN_BITMAP_SZ 512 + +#define VLAN_ADD_MEMBER(vid, member_vids) ((member_vids)[(vid)/8] |= (vid) % 8) +#define VLAN_DEL_MEMBER(vid, member_vids) ((member_vids)[(vid)/8] &= ~((vid) % 8)) + +struct vlan_if { + /* begemotVlanInterfaceTable */ + char vlif_name[IFNAMSIZ]; + uint16_t vid; + uint32_t trunk_idx; + uint16_t vlif_proto; + enum RowStatus vlif_status; + uint32_t encaplen; + uint32_t mtu_fudge; + uint32_t min_tu; + /* begemotVlanIfStatsTable */ + uint32_t in_frames; + uint32_t out_frames; + uint32_t in_discards; + uint32_t in_overflows; + uint32_t out_overflows; + uint32_t overflow_discards; + uint32_t disc_time; + TAILQ_ENTRY(vlan_if) vlif; +}; + +struct vlan_trunk { + uint32_t trunk_idx; + char parent_ifname[IFNAMSIZ]; + enum TruthValue hwtag_supported; + enum EnabledStatus hwtag_enabled; + enum TruthValue hwmtu_supported; + enum EnabledStatus hwmtu_enabled; + enum TruthValue hwcsum_supported; + enum EnabledStatus hwcsum_endbaled; + uint32_t members; + char member_vids[VLAN_BITMAP_SZ]; + struct vlan_if *f_vlif; + TAILQ_ENTRY(vlan_trunk) vltrunk; +}; Index: usr.sbin/bsnmpd/modules/snmp_vlan/vlan_tree.def =================================================================== --- usr.sbin/bsnmpd/modules/snmp_vlan/vlan_tree.def (revision 0) +++ usr.sbin/bsnmpd/modules/snmp_vlan/vlan_tree.def (working copy) @@ -0,0 +1,101 @@ +#- +# Copyright (c) 2007-2008 Shteryana Shopova +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD$ +# + +#include "tc.def" + +typedef EnabledStatus ENUM ( + 1 enabled + 2 disabled +) + +typedef TruthValue ENUM ( + 1 true + 2 false +) + +typedef RowStatus ENUM ( + 1 active + 2 notInService + 3 notReady + 4 createAndGo + 5 createAndWait + 6 destroy +) + +(1 internet + (4 private + (1 enterprises + (12325 fokus + (1 begemot + (206 begemotVlan + (1 begemotVlanConfig + (1 begemotVlanMaxId INTEGER op_begemot_vlan_config GET) + (2 begemotVlanNumVlans INTEGER32 op_begemot_vlan_config GET) + (3 begemotVlanDataPoll INTEGER op_begemot_vlan_config GET SET) + (4 begemotVlanSoftPad EnabledStatus op_begemot_vlan_config GET SET) + ) + (2 begemotVlanTrunks + (1 begemotVlanTrunkTable + (1 begemotVlanTrunkEntry : INTEGER op_begemot_vlan_trunk + (1 begemotVlanTrunkIndex INTEGER GET) + (2 begemotVlanParentIfName OCTETSTRING GET) + (3 begemotVlanParentIfHwTagSupported TruthValue GET) + (4 begemotVlanParentIfHwTagEnabled EnabledStatus GET SET) + (5 begemotVlanParentIfHwMtuSupported TruthValue GET) + (6 begemotVlanParentIfHwMtuEnabled EnabledStatus GET SET) + (7 begemotVlanParentIfHwCSumSupported TruthValue GET) + (8 begemotVlanParentIfHwCSumEnabled EnabledStatus GET SET) + (9 begemotVlanTrunkMembers INTEGER GET) + (10 begemotVlanTrunkMemberVids OCTETSTRING | BegemotVlanBitMap GET) + )) + ) + (3 begemotVlanInterfaces + (1 begemotVlanInterfaceTable + (1 begemotVlanInterfaceEntry : INTEGER OCTETSTRING op_begemot_vlan_iface + (1 begemotVlanIfName OCTETSTRING GET SET) + (2 begemotVlanIfVid INTEGER GET SET) + (3 begemotVlanIfProto INTEGER GET SET) + (4 begemotVlanIfStatus RowStatus GET SET) + (5 begemotVlanIfEncaplen INTEGER32 GET SET) + (6 begemotVlanIfMtuFudge INTEGER32 GET SET) + (7 begemotVlanIfMinTU INTEGER32 GET SET) + )) + ) + (4 begemotVlanStatistics + (1 begemotVlanIfStatsTable + (1 begemotVlanIfStatsEntry : INTEGER OCTETSTRING op_begemot_vlan_if_stats + (1 begemotVlanIfInFrames COUNTER GET) + (2 begemotVlanIfOutFrames COUNTER GET) + (3 begemotVlanIfInDiscards COUNTER GET) + (4 begemotVlanIfInOverflowFrames COUNTER GET) + (5 begemotVlanIfOutOverflowFrames COUNTER GET) + (6 begemotVlanIfInOverflowDiscards COUNTER GET) + (7 begemotVlanIfDiscontinuityTime UNSIGNED32 GET) + )) + ) +)))))) Index: usr.sbin/bsnmpd/modules/snmp_vlan/Makefile =================================================================== --- usr.sbin/bsnmpd/modules/snmp_vlan/Makefile (revision 0) +++ usr.sbin/bsnmpd/modules/snmp_vlan/Makefile (working copy) @@ -0,0 +1,16 @@ +# +# $FreeBSD$ +# + +MOD= vlan +SRCS= vlan_snmp.c +CFLAGS+= -DSNMPTREE_TYPES + +XSYM= begemotVlan + +MAN= snmp_vlan.3 + +BMIBS= BEGEMOT-VLAN-MIB.txt +DEFS= ${MOD}_tree.def + +.include Index: usr.sbin/bsnmpd/modules/snmp_vlan/vlan_snmp.c =================================================================== --- usr.sbin/bsnmpd/modules/snmp_vlan/vlan_snmp.c (revision 0) +++ usr.sbin/bsnmpd/modules/snmp_vlan/vlan_snmp.c (working copy) @@ -0,0 +1,1125 @@ +/*- + * Copyright (c) 2007 Shteryana Shopova + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Vlan MIB implementation for SNMPd. + * + * $FreeBSD$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "vlan_tree.h" +#include "vlan_snmp.h" +#include "vlan_oid.h" + +static struct lmodule *vlan_module; + +/* For the registration. */ +static const struct asn_oid oid_begemotVlan = OIDX_begemotVlan; +/* The registration. */ +static uint reg_vlan; + +/* Periodic timer for polling vlan trunks' data. */ +static void *vlan_data_timer; + +/* begemotVlanConfig subtree objects */ +int vlan_num = 0; +int vlan_data_poll = (5 * 60); /* XXX */ + +/* The socket for the sysctl's */ +int vl_sock = -1; + +/* The global vlan trunks' list. */ +TAILQ_HEAD(vlan_trunks, vlan_trunk); +static struct vlan_trunks vlan_trunk_list = TAILQ_HEAD_INITIALIZER(vlan_trunk_list); + +/* The global vlan interfaces' list. */ +TAILQ_HEAD(vlan_ifs, vlan_if); +static struct vlan_ifs vlif_list = TAILQ_HEAD_INITIALIZER(vlif_list); + +/* + * Free the vlan trunks' list. + */ +static void +vlan_trunks_free(struct vlan_trunks *headp) +{ + struct vlan_trunk *vt; + + while ((vt = TAILQ_FIRST(headp)) != NULL) { + TAILQ_REMOVE(headp, vt, vltrunk); + free(vt); + } +} + +/* + * Insert an entry in the vlan trunk interface TAILQ. Keep the + * TAILQ sorted by the trunk's mibII interface index. + */ +static void +vlan_trunks_insert(struct vlan_trunks *headp, struct vlan_trunk *vt) +{ + struct vlan_trunk *temp; + + if ((temp = TAILQ_FIRST(headp)) == NULL || + vt->trunk_idx < temp->trunk_idx) { + TAILQ_INSERT_HEAD(headp, vt, vltrunk); + return; + } + + TAILQ_FOREACH(temp, headp, vltrunk) + if (vt->trunk_idx < temp->trunk_idx) + TAILQ_INSERT_BEFORE(temp, vt, vltrunk); + + TAILQ_INSERT_TAIL(headp, vt, vltrunk); +} + +/* + * Remove a vlan trunk. + */ +static void +vlan_trunk_remove(struct vlan_trunk *vt) +{ + TAILQ_REMOVE(&vlan_trunk_list, vt, vltrunk); + free(vt); +} + +/* + * Find a vlan trunk by its parent interface name. + */ +static struct vlan_trunk * +vlan_trunk_find(char *parent_ifname) +{ + struct vlan_trunk *vt; + + TAILQ_FOREACH(vt, &vlan_trunk_list, vltrunk) + if (strcmp(vt->parent_ifname, parent_ifname) == 0) + return (vt); + + return (NULL); +} + +/* + * Find a vlan trunk by its mibII interface index. + */ +static struct vlan_trunk * +vlan_trunk_find_ifindex(uint32_t trunk_idx) +{ + struct vlan_trunk *vt; + + TAILQ_FOREACH(vt, &vlan_trunk_list, vltrunk) + if (vt->trunk_idx == trunk_idx) + return (vt); + + return (NULL); +} + +static struct vlan_trunk * +vlan_trunk_first(void) +{ + return (TAILQ_FIRST(&vlan_trunk_list)); +} + +static struct vlan_trunk * +vlan_trunk_next(struct vlan_trunk *vltr) +{ + return (TAILQ_NEXT(vltr, vltrunk)); +} + +static struct vlan_if * +vlan_trunk_vlif_first(struct vlan_trunk *vt) +{ + return (vt->f_vlif); +} + +static struct vlan_if * +vlan_trunk_vlif_next(struct vlan_if *vl) +{ + struct vlan_if *vl_next; + + if ((vl_next = TAILQ_NEXT(vl, vlif)) == NULL || + vl_next->trunk_idx != vl->trunk_idx) + return (NULL); + + return (vl_next); +} + +static struct vlan_if * +vlan_vlif_next(struct vlan_if *vl) +{ + return (TAILQ_NEXT(vl, vlif)); +} + +struct vlan_if * +vlan_trunk_vlif_find_ifname(struct vlan_trunk *vt, char *vl_name) +{ + struct vlan_if *vlanif; + + for (vlanif = vlan_trunk_vlif_first(vt); vlanif != NULL; + vlanif = vlan_trunk_vlif_next(vlanif)) { + if (strcmp(vlanif->vlif_name, vl_name) == 0) + return (vlanif); + } + + return (NULL); +} + +/* + * Free the vlan interfaces' list. + */ +static void +vlan_vlifs_free(struct vlan_ifs *headp) +{ + struct vlan_if *vl; + + while ((vl = TAILQ_FIRST(headp)) != NULL) { + TAILQ_REMOVE(headp, vl, vlif); + free(vl); + } +} + +/* + * Insert an entry in the vlan interfaces' TAILQ. Keep the + * TAILQ sorted by the trunk's mibII interface index and + * the vlan interface name. + */ +static void +vlan_vlif_insert(struct vlan_ifs *headp, struct vlan_if *vl, + struct vlan_if **first_vl) +{ + struct vlan_if *temp; + + assert(first_vl != NULL); + + for (temp = *first_vl; + temp != NULL && vl->trunk_idx == temp->trunk_idx; + temp = TAILQ_NEXT(temp, vlif)) { + if (strcmp(vl->vlif_name, temp->vlif_name) < 0) { + TAILQ_INSERT_BEFORE(temp, vl, vlif); + if (*first_vl == temp) + *first_vl = vl; + return; + } + } + + /* + * Handle the case when our first vlan interface was actually the + * last element of the TAILQ. + */ + if (temp == NULL) + TAILQ_INSERT_TAIL(headp, vl, vlif); + else + TAILQ_INSERT_BEFORE(temp, vl, vlif); +} + +static void +vlan_vlif_remove(struct vlan_if *vl, struct vlan_trunk *vt) +{ + if (vt->f_vlif == vl) + vt->f_vlif = vlan_trunk_vlif_next(vl); + + TAILQ_REMOVE(&vlif_list, vl, vlif); + free(vl); +} + +static void +vlan_vlif_add(struct vlan_if *vl, struct vlan_trunk *vt) +{ + vlan_vlif_insert(&vlif_list, vl, &(vt->f_vlif)); + vt->members += 1; + VLAN_ADD_MEMBER(vl->vid, vt->member_vids); +} + +/* static */ void +vlan_vlif_delete(struct vlan_if *vl) +{ + struct vlan_trunk *vt; + + if ((vt = vlan_trunk_find_ifindex(vl->trunk_idx)) == NULL) { + syslog(LOG_ERR, "vlan delete interface failed: " + "parent not found"); + return; + } + + VLAN_DEL_MEMBER(vl->vid, vt->member_vids); + vlan_vlif_remove(vl, vt); + + /* If no other vlan interfaces attached, remove the trunk entry. */ + if (--(vt->members) == 0) + vlan_trunk_remove(vt); +} + +/* + * Create a new trunk interface and insert it in the global list. + */ +static struct vlan_trunk * +vlan_attach_trunk_if(char *vl_parent, int vl_tag) +{ + struct mibif *ifp; + struct vlan_trunk *trunk_if; + + if ((ifp = mib_find_if_name(vl_parent)) == NULL && vl_tag != 0) { + syslog(LOG_ERR, "vlan new trunk interface failed: " + "parent %s not found in mibII", vl_parent); + /* return (NULL); */ + } + + trunk_if = (struct vlan_trunk *) malloc(sizeof(struct vlan_trunk)); + if (trunk_if == NULL) { + syslog(LOG_ERR, "vlan new trunk interface failed: %s", + strerror(errno)); + return (NULL); + } + + bzero(trunk_if, sizeof(struct vlan_trunk)); + + if (ifp != NULL) + trunk_if->trunk_idx = ifp->index; + else + trunk_if->trunk_idx = 0; + + strcpy(trunk_if->parent_ifname, vl_parent); + + vlan_trunks_insert(&vlan_trunk_list, trunk_if); + + return (trunk_if); +} + +static int +vlan_vlif_getparent(char *vl_name, char *vl_parent) +{ + struct ifreq ifr; + struct vlanreq vreq; + + bzero(&ifr, sizeof(struct ifreq)); + bzero(&vreq, sizeof(struct vlanreq)); + + strcpy(ifr.ifr_name, vl_name); + ifr.ifr_data = (caddr_t) &vreq; + + if (ioctl(vl_sock, SIOCGETVLAN, (caddr_t) &ifr) < 0) { + syslog(LOG_ERR, "vlan get parent if: ioctl(SIOCGETVLAN) " + "failed: %s", strerror(errno)); + return (-1); + } + + strcpy(vl_parent, vreq.vlr_parent); + + return (vreq.vlr_tag); +} + +static int +vlan_attach_vlif(struct mibif *ifp) +{ + int vl_tag; + char vlr_parent[IFNAMSIZ]; + struct vlan_if *vl_if; + struct vlan_trunk *vl_trunk; + + /* Fetch the parent interface. */ + bzero(vlr_parent, IFNAMSIZ); + if ((vl_tag = vlan_vlif_getparent(ifp->name, vlr_parent)) < 0) + return (-1); + + /* Try to find the parent interface in the trunk list. */ + if ((vl_trunk = vlan_trunk_find(vlr_parent)) == NULL) { + /* Parent not found - create it. */ + vl_trunk = vlan_attach_trunk_if(vlr_parent, vl_tag); + if (vl_trunk == NULL) + return (-1); + } + + if ((vl_if = (struct vlan_if *)malloc(sizeof(struct vlan_if))) == NULL) { + syslog(LOG_ERR, "vlan new interface failed: %s", + strerror(errno)); + return (-1); + } + + bzero(vl_if, sizeof(struct vlan_if)); + bcopy(ifp->name, vl_if->vlif_name, IFNAMSIZ); + vl_if->trunk_idx = vl_trunk->trunk_idx; + vl_if->vid = vl_tag; + vlan_vlif_add(vl_if, vl_trunk); + + return (0); +} + +/* + * New interface creation hook for the vlan module. + */ +static int +vlan_attach_newif(struct mibif *ifp) +{ + if (ifp->mib.ifmd_data.ifi_type == IFT_L2VLAN) { + if (vlan_attach_vlif(ifp) < 0) + return (-1); + + vlan_num++; + } + + return (0); +} + +static int +vlan_update_vlif(struct vlan_if *vl_if) +{ + struct mibif *ifp; + int vl_tag; + char vlr_parent[IFNAMSIZ]; + + /* Walk through the mibII interface list. */ + for (ifp = mib_first_if(); ifp != NULL; ifp = mib_next_if(ifp)) + if (strcmp(ifp->name, vl_if->vlif_name) == 0) + break; + + if (ifp == NULL) { + /* Apparently the vlan interface was deleted. */ + vlan_vlif_delete(vl_if); + return (0); + } + + /* Update vlan tag and parent. */ + bzero(vlr_parent, IFNAMSIZ); + if ((vl_tag = vlan_vlif_getparent(ifp->name, vlr_parent)) < 0) + return (-1); + + if (vl_if->vid != vl_tag) + vl_if->vid = vl_tag; + + if (strcmp(vlr_parent, vl_if->vlif_name) != 0) + strncpy(vl_if->vlif_name, vlr_parent, IFNAMSIZ); + + /* XXX: update status */ + return (0); +} + +static void +vlan_update_vltrunk(struct vlan_trunk *vtrunk) +{ +} + +void +vlan_update_all(void *arg __unused) +{ + struct vlan_if *vl_if; + struct vlan_trunk *vtrunk; + + TAILQ_FOREACH(vl_if, &vlif_list, vlif) + vlan_update_vlif(vl_if); + + TAILQ_FOREACH(vtrunk, &vlan_trunk_list, vltrunk) + vlan_update_vltrunk(vtrunk); +} + +static int +vlan_softpad(enum snmp_op op, uint32_t *val) +{ + char vlan_mib_name[] = "net.link.vlan.soft_pad"; + int32_t k_val, new_val; + size_t new_len, k_len; + + if (op == SNMP_OP_SET) + new_len = sizeof(*val); + else + new_len = 0; + + k_len = sizeof(k_val); + + if (*val == EnabledStatus_enabled) + new_val = k_val = 1; + else + new_val = k_val = 0; + + if (sysctlbyname(vlan_mib_name, &k_val, &k_len, + (op == SNMP_OP_SET ? &new_val : NULL), new_len) == -1) { + syslog(LOG_ERR, "sysctl(%s) failed - %s", vlan_mib_name, + strerror(errno)); + return (-1); + } + + if (k_val == 0) + *val = EnabledStatus_disabled; + else + *val = EnabledStatus_enabled; + + return (0); +} + +int +op_begemot_vlan_config(struct snmp_context *ctx, struct snmp_value *val, + u_int sub __unused, u_int iidx __unused, enum snmp_op op) +{ + switch (op) { + case SNMP_OP_GET: + switch (val->var.subs[sub - 1]) { + case LEAF_begemotVlanMaxId: + val->v.integer = EVL_VLID_MASK; /* XXX: FIXME!!! */ + return (SNMP_ERR_NOERROR); + + case LEAF_begemotVlanNumVlans: + val->v.integer = vlan_num; + return (SNMP_ERR_NOERROR); + + case LEAF_begemotVlanDataPoll: + val->v.integer = vlan_data_poll; + return (SNMP_ERR_NOERROR); + + case LEAF_begemotVlanSoftPad: + if (vlan_softpad(op, &(val->v.uint32)) < 0) + return (SNMP_ERR_GENERR); + return (SNMP_ERR_NOERROR); + } + abort(); + + case SNMP_OP_GETNEXT: + abort(); + + case SNMP_OP_SET: + switch (val->var.subs[sub - 1]) { + case LEAF_begemotVlanMaxId: + case LEAF_begemotVlanNumVlans: + return (SNMP_ERR_NOT_WRITEABLE); + + case LEAF_begemotVlanDataPoll: + if (val->v.integer < 1 || val->v.integer > 3600) /* XXX */ + return (SNMP_ERR_WRONG_VALUE); + ctx->scratch->int1 = vlan_data_poll; + vlan_data_poll = val->v.integer; + return (SNMP_ERR_NOERROR); + + case LEAF_begemotVlanSoftPad: + if (val->v.integer != EnabledStatus_enabled && + val->v.integer != EnabledStatus_disabled) + return (SNMP_ERR_WRONG_VALUE); + if (vlan_softpad(SNMP_OP_GET, + &(ctx->scratch->int1)) < 0) + return (SNMP_ERR_GENERR); + if (vlan_softpad(op, &(val->v.uint32)) < 0) + return (SNMP_ERR_GENERR); + return (SNMP_ERR_NOERROR); + } + abort(); + + case SNMP_OP_ROLLBACK: + switch (val->var.subs[sub - 1]) { + case LEAF_begemotVlanDataPoll: + vlan_data_poll = ctx->scratch->int1; + break; + + case LEAF_begemotVlanSoftPad: + vlan_softpad(SNMP_OP_SET, &(ctx->scratch->int1)); + break; + } + return (SNMP_ERR_NOERROR); + + case SNMP_OP_COMMIT: + return (SNMP_ERR_NOERROR); + } + + abort(); +} + +static int +vlan_trunk_parentif_set(struct vlan_trunk *vltr, int hw_opt, int value) +{ + if (value != EnabledStatus_enabled && value != EnabledStatus_disabled) + return (SNMP_ERR_BADVALUE); + + return (SNMP_ERR_NOERROR); +} + +int +op_begemot_vlan_trunk(struct snmp_context *ctx, struct snmp_value *val, + u_int sub, u_int iidx __unused, enum snmp_op op) +{ + struct vlan_trunk *vltr; + + /* XXX: update info */ + + if (val->var.len - sub < 0 || val->var.len - sub > 1) + return (SNMP_ERR_NOSUCHNAME); + + if (val->var.len - sub == 0) { + if (op != SNMP_OP_GETNEXT) + return (SNMP_ERR_NOSUCHNAME); + else + vltr = vlan_trunk_first(); + } else { + vltr = vlan_trunk_find_ifindex(val->var.subs[sub]); + if (op == SNMP_OP_GETNEXT) + vltr = vlan_trunk_next(vltr); + } + + if (vltr == NULL) + return (SNMP_ERR_NOSUCHNAME); + + switch (op) { + case SNMP_OP_GET: + case SNMP_OP_GETNEXT: + switch (val->var.subs[sub - 1]) { + case LEAF_begemotVlanParentIfName: + return (string_get(val, vltr->parent_ifname, -1)); + + case LEAF_begemotVlanParentIfHwTagSupported: + val->v.integer = vltr->hwtag_supported; + return (SNMP_ERR_NOERROR); + + case LEAF_begemotVlanParentIfHwTagEnabled: + val->v.integer = vltr->hwtag_enabled; + return (SNMP_ERR_NOERROR); + + case LEAF_begemotVlanParentIfHwMtuSupported: + val->v.integer = vltr->hwmtu_supported; + return (SNMP_ERR_NOERROR); + + case LEAF_begemotVlanParentIfHwMtuEnabled: + val->v.integer = vltr->hwmtu_enabled; + return (SNMP_ERR_NOERROR); + + case LEAF_begemotVlanParentIfHwCSumSupported: + val->v.integer = vltr->hwcsum_supported; + return (SNMP_ERR_NOERROR); + + case LEAF_begemotVlanParentIfHwCSumEnabled: + val->v.integer = vltr->hwcsum_endbaled; + return (SNMP_ERR_NOERROR); + + case LEAF_begemotVlanTrunkMembers: + val->v.integer = vltr->members; + return (SNMP_ERR_NOERROR); + + case LEAF_begemotVlanTrunkMemberVids: + return (string_get(val, vltr->member_vids, + VLAN_BITMAP_SZ)); + } + abort(); + + case SNMP_OP_SET: + switch (val->var.subs[sub - 1]) { + case LEAF_begemotVlanParentIfName: + case LEAF_begemotVlanParentIfHwTagSupported: + case LEAF_begemotVlanParentIfHwMtuSupported: + case LEAF_begemotVlanParentIfHwCSumSupported: + case LEAF_begemotVlanTrunkMembers: + case LEAF_begemotVlanTrunkMemberVids: + return (SNMP_ERR_NOT_WRITEABLE); + + case LEAF_begemotVlanParentIfHwTagEnabled: + if (vltr->hwtag_supported == TruthValue_false) + return (SNMP_ERR_INCONS_VALUE); + ctx->scratch->int1 = vltr->hwtag_enabled; + return (vlan_trunk_parentif_set(vltr, + val->var.subs[sub - 1], val->v.integer)); + + case LEAF_begemotVlanParentIfHwMtuEnabled: + if (vltr->hwmtu_supported == TruthValue_false) + return (SNMP_ERR_INCONS_VALUE); + ctx->scratch->int1 = vltr->hwmtu_enabled; + return (vlan_trunk_parentif_set(vltr, + val->var.subs[sub - 1], val->v.integer)); + + case LEAF_begemotVlanParentIfHwCSumEnabled: + if (vltr->hwcsum_supported == TruthValue_false) + return (SNMP_ERR_INCONS_VALUE); + ctx->scratch->int1 = vltr->hwcsum_endbaled; + return (vlan_trunk_parentif_set(vltr, + val->var.subs[sub - 1], val->v.integer)); + } + abort(); + + case SNMP_OP_ROLLBACK: + vlan_trunk_parentif_set(vltr, val->var.subs[sub - 1], + ctx->scratch->int1); + return (SNMP_ERR_NOERROR); + + case SNMP_OP_COMMIT: + return (SNMP_ERR_NOERROR); + } + + return (SNMP_ERR_NOSUCHNAME); +} + +/* + * Get the vlan interface entry from an index. + */ +static struct vlan_if * +vlan_iface_index_get(const struct asn_oid *oid, uint sub, int8_t status) +{ + uint i; + char vl_name[IFNAMSIZ]; + struct vlan_if *vlanif; + struct vlan_trunk *vltr; + + /* + * Make sure the OID contains at least a 2 additional suboids + * - one for the parent ifIndex, one for a non-zero-length octetstring, + * and at least one octet from the string. + */ + if (oid->len - sub < 3) + return (NULL); + + if ((vltr = vlan_trunk_find_ifindex(oid->subs[sub])) == NULL) + return (NULL); + + if (oid->len - sub != oid->subs[sub + 1] + 2 || + oid->subs[sub + 1] >= IFNAMSIZ) + return (NULL); + + for (i = 0; i < oid->subs[sub + 1]; i++) + vl_name[i] = oid->subs[sub + i + 2]; + vl_name[i] = '\0'; + + vlanif = vlan_trunk_vlif_find_ifname(vltr, vl_name); + + /* XXX: consider RowStatus - that is new if creation. */ + return (vlanif); +} + +/* + * Get the next vlan interface entry from an index. + */ +static struct vlan_if * +vlan_iface_index_getnext(const struct asn_oid *oid, uint sub, int8_t status) +{ + uint i; + char vl_name[IFNAMSIZ]; + struct vlan_if *vlanif; + struct vlan_trunk *vltrunk; + + if (oid->len - sub == 0) { + if ((vltrunk = vlan_trunk_first()) == NULL) + return (NULL); + + return (vlan_trunk_vlif_first(vltrunk)); + } + + if (oid->len - sub < 3) + return (NULL); + + if ((vltrunk = vlan_trunk_find_ifindex(oid->subs[sub])) == NULL) + return (NULL); + + if (oid->len - sub != oid->subs[sub + 1] + 2 || + oid->subs[sub + 1] >= IFNAMSIZ) + return (NULL); + + for (i = 0; i < oid->subs[sub + 1]; i++) + vl_name[i] = oid->subs[sub + i + 2]; + vl_name[i] = '\0'; + + vlanif = vlan_trunk_vlif_find_ifname(vltrunk, vl_name); + + /* XXX: consider RowStatus - that is new if creation. */ + return (vlan_vlif_next(vlanif)); +} + +static int +vlan_vlif_set_vid(struct vlan_if *vl, uint16_t vid) +{ + return (0); +} + +static int +vlan_vlif_set_proto(struct vlan_if *vl, uint16_t proto) +{ + return (0); +} + +static int +vlan_vlif_set_status(struct vlan_if *vl, uint16_t status) +{ + return (0); +} + +static int +vlan_vlif_set_encap(struct vlan_if *vl, uint16_t encap) +{ + return (0); +} + +static int +vlan_vlif_set_mfudge(struct vlan_if *vl, uint16_t mfudge) +{ + return (0); +} + +static int +vlan_vlif_set_mintu(struct vlan_if *vl, uint16_t mintu) +{ + return (0); +} + +static int +vlan_vlif_rollback_status(struct vlan_if *vl, uint16_t oldstatus, + uint16_t newstatus) +{ + return (0); +} + +int +op_begemot_vlan_iface(struct snmp_context *ctx, struct snmp_value *val, + u_int sub, u_int iidx __unused, enum snmp_op op) +{ + int8_t status, which; + struct vlan_if *vl = NULL; + + /* XXX: update stats */ + which = val->var.subs[sub - 1]; + + switch (op) { + case SNMP_OP_GET: + if (which == LEAF_begemotVlanIfStatus) + status = 1; + else + status = 0; + if ((vl = vlan_iface_index_get(&val->var, sub, status)) + == NULL) + return (SNMP_ERR_NOSUCHNAME); + goto get; + + case SNMP_OP_GETNEXT: + if (which == LEAF_begemotVlanIfStatus) + status = 1; + else + status = 0; + if ((vl = vlan_iface_index_getnext(&val->var, sub, status)) + == NULL) + return (SNMP_ERR_NOSUCHNAME); + goto get; + + case SNMP_OP_SET: + if ((vl = vlan_iface_index_get(&val->var, sub, 0)) == NULL + && which != LEAF_begemotVlanIfStatus) + return (SNMP_ERR_NOSUCHNAME); + + switch (which) { + case LEAF_begemotVlanIfVid: + ctx->scratch->int1 = vl->vid; + return (vlan_vlif_set_vid(vl, val->v.integer)); + + case LEAF_begemotVlanIfProto: + ctx->scratch->int1 = vl->vlif_proto; + return (vlan_vlif_set_proto(vl, val->v.integer)); + + case LEAF_begemotVlanIfStatus: + if (vl == NULL) + ctx->scratch->int1 = RowStatus_destroy; + else + ctx->scratch->int1 = vl->vlif_status; + return (vlan_vlif_set_status(vl, val->v.integer)); + + case LEAF_begemotVlanIfEncaplen: + ctx->scratch->int1 = vl->encaplen; + return (vlan_vlif_set_encap(vl, val->v.integer)); + + case LEAF_begemotVlanIfMtuFudge: + ctx->scratch->int1 = vl->mtu_fudge; + return (vlan_vlif_set_mfudge(vl, val->v.integer)); + + case LEAF_begemotVlanIfMinTU: + ctx->scratch->int1 = vl->min_tu; + return (vlan_vlif_set_mintu(vl, val->v.integer)); + } + abort(); + + case SNMP_OP_COMMIT: + return (SNMP_ERR_NOERROR); + + case SNMP_OP_ROLLBACK: + if ((vl = vlan_iface_index_get(&val->var, sub, 0)) == NULL) + return (SNMP_ERR_NOSUCHNAME); + + switch (which) { + case LEAF_begemotVlanIfVid: + vl->vid = ctx->scratch->int1; + return (vlan_vlif_set_vid(vl, vl->vid)); + + case LEAF_begemotVlanIfProto: + vl->vlif_proto = ctx->scratch->int1; + return (vlan_vlif_set_proto(vl, vl->vlif_proto)); + + case LEAF_begemotVlanIfStatus: + return (vlan_vlif_rollback_status(vl, + ctx->scratch->int1, vl->vlif_status)); + + case LEAF_begemotVlanIfEncaplen: + vl->encaplen = ctx->scratch->int1; + return (vlan_vlif_set_encap(vl, vl->encaplen)); + + case LEAF_begemotVlanIfMtuFudge: + vl->mtu_fudge = ctx->scratch->int1; + return (vlan_vlif_set_mfudge(vl, vl->mtu_fudge)); + + case LEAF_begemotVlanIfMinTU: + vl->min_tu = ctx->scratch->int1; + return (vlan_vlif_set_mintu(vl, vl->min_tu)); + } + abort(); + } + +get: + + switch (which) { + case LEAF_begemotVlanIfName: + return (string_get(val, vl->vlif_name, -1)); + case LEAF_begemotVlanIfVid: + val->v.integer = vl->vid; + break; + case LEAF_begemotVlanIfProto: + val->v.integer = vl->vlif_proto; + break; + case LEAF_begemotVlanIfStatus: + val->v.integer = vl->vlif_status; + break; + case LEAF_begemotVlanIfEncaplen: + val->v.integer = vl->encaplen; + break; + case LEAF_begemotVlanIfMtuFudge: + val->v.integer = vl->mtu_fudge; + break; + case LEAF_begemotVlanIfMinTU: + val->v.integer = vl->min_tu; + break; + } + + return (SNMP_ERR_NOERROR); +} + +int +op_begemot_vlan_if_stats(struct snmp_context *ctx __unused, + struct snmp_value *val, u_int sub, u_int iidx __unused, enum snmp_op op) +{ + struct vlan_if *vl; + + /* XXX: update the info */ + + switch (op) { + case SNMP_OP_SET: + return (SNMP_ERR_NOT_WRITEABLE); + + case SNMP_OP_GET: + if ((vl = vlan_iface_index_get(&val->var, sub, 0)) + == NULL) + return (SNMP_ERR_NOSUCHNAME); + goto get; + + case SNMP_OP_GETNEXT: + if ((vl = vlan_iface_index_getnext(&val->var, sub, 0)) + == NULL) + return (SNMP_ERR_NOSUCHNAME); + goto get; + + case SNMP_OP_COMMIT: + case SNMP_OP_ROLLBACK: + abort(); + } + + return (SNMP_ERR_NOSUCHNAME); + +get: + switch (val->var.subs[sub - 1]) { + case LEAF_begemotVlanIfInFrames: + val->v.uint32 = vl->in_frames; + break; + case LEAF_begemotVlanIfOutFrames: + val->v.uint32 = vl->out_frames; + break; + case LEAF_begemotVlanIfInDiscards: + val->v.uint32 = vl->in_discards; + break; + case LEAF_begemotVlanIfInOverflowFrames: + val->v.uint32 = vl->in_overflows; + break; + case LEAF_begemotVlanIfOutOverflowFrames: + val->v.uint32 = vl->out_overflows; + break; + case LEAF_begemotVlanIfInOverflowDiscards: + val->v.uint32 = vl->overflow_discards; + break; + case LEAF_begemotVlanIfDiscontinuityTime: + val->v.uint32 = vl->disc_time; + break; + default: + return (SNMP_ERR_NOSUCHNAME); + } + + return (SNMP_ERR_NOERROR); +} + +/* + * Load the if_vlan.ko module in kernel if not already there. + */ +static int +vlan_kmod_load(void) +{ + int fileid, modid; + const char mod_name[] = "if_vlan"; + struct module_stat mstat; + + /* Scan files in kernel. */ + mstat.version = sizeof(struct module_stat); + for (fileid = kldnext(0); fileid > 0; fileid = kldnext(fileid)) { + /* Scan modules in file. */ + for (modid = kldfirstmod(fileid); modid > 0; + modid = modfnext(modid)) { + + if (modstat(modid, &mstat) < 0) + continue; + + if (strcmp(mod_name, mstat.name) == 0) + return (0); + } + } + + /* Not present - load it. */ + if (kldload(mod_name) < 0) { + syslog(LOG_ERR, "failed to load %s kernel module", mod_name); + return (-1); + } + + return (1); +} + +static int +vlan_ioctl_init(void) +{ + if ((vl_sock = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { + syslog(LOG_ERR, "cannot open socket : %s", strerror(errno)); + return (-1); + } + + return (0); +} + +/* + * Vlan mib module initialization hook. + * Returns 0 on success, < 0 on error. + */ +static int +vlan_init(struct lmodule * mod, int argc __unused, char *argv[] __unused) +{ + vlan_module = mod; + + if (vlan_kmod_load() < 0) + return (-1); + + if (vlan_ioctl_init() < 0) + return (-1); + + /* Register the module's new interface creation hook. */ + if (mib_register_newif(vlan_attach_newif, vlan_module)) { + syslog(LOG_ERR, "Cannot register newif function: %s", + strerror(errno)); + return (-1); + } + + return (0); +} + +/* + * Vlan mib module finalization hook. + */ +static int +vlan_fini(void) +{ + mib_unregister_newif(vlan_module); + or_unregister(reg_vlan); + + if (vlan_data_timer != NULL) { + timer_stop(vlan_data_timer); + vlan_data_timer = NULL; + } + + vlan_trunks_free(&vlan_trunk_list); + vlan_vlifs_free(&vlif_list); + + return (0); +} + +/* + * Vlan mib module start operation. + */ +static void +vlan_start(void) +{ + struct mibif *ifp; + + reg_vlan = or_register(&oid_begemotVlan, + "The BEGEMOT MIB for Vlan interfaces.", vlan_module); + + /* Add the existing vlan interfaces. */ + for (ifp = mib_first_if(); ifp != NULL; ifp = mib_next_if(ifp)) + vlan_attach_newif(ifp); + + vlan_data_timer = timer_start_repeat(vlan_data_poll * 100, + vlan_data_poll * 100, vlan_update_all, NULL, vlan_module); +} + +static void +vlan_dump(void) +{ + struct vlan_trunk *vtrunk; + struct vlan_if *vif; + + TAILQ_FOREACH(vtrunk, &vlan_trunk_list, vltrunk) + syslog(LOG_ERR, "Vlan trunk %s, index - %d", + vtrunk->parent_ifname, vtrunk->trunk_idx); + + TAILQ_FOREACH(vif, &vlif_list, vlif) + syslog(LOG_ERR, "Vlan if %s, tag - %d, parent index - %d", + vif->vlif_name, vif->vid, vif->trunk_idx); +} + +const struct snmp_module config = { + .comment = "This module implements the BEGEMOT VLAN MIB.", + .init = vlan_init, + .fini = vlan_fini, + .start = vlan_start, + .tree = vlan_ctree, + .dump = vlan_dump, + .tree_size = vlan_CTREE_SIZE, +}; Index: usr.sbin/bsnmpd/modules/snmp_vlan/snmp_vlan.3 =================================================================== --- usr.sbin/bsnmpd/modules/snmp_vlan/snmp_vlan.3 (revision 0) +++ usr.sbin/bsnmpd/modules/snmp_vlan/snmp_vlan.3 (working copy) @@ -0,0 +1,54 @@ +.\"- +.\" Copyright (C) 2007 Shteryana Shopova +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd February 4, 2007 +.Dt snmp_vlan 3 +.Os +.Sh NAME +.Nm snmp_vlan +.Nd "vlan module for snmpd. +.Sh LIBRARY +.Pq begemotSnmpdModulePath."vlan" = "/usr/lib/snmp_vlan.so" +.Sh DESCRIPTION +The +.Nm snmp_vlan ... +.Sh FILES +.Bl -tag -width "XXXXXXXXX" +.It Pa /usr/share/snmp/defs/vlan_tree.def +The description of the MIB tree implemented by +.Nm . +.It Pa /usr/share/snmp/mibs/BEGEMOT-VLAN-MIB.txt +This is the private BEGEMOT-VLAN-MIB that is implemented by this module. +.El +.Sh SEE ALSO +.Xr bsnmpd 1 , +.Xr gensnmptree 1 , +.Xr if_vlan 4 , +.Xr ifconfig 8 , +.Xr snmpmod 3 +.Sh AUTHORS +.An Shteryana Shopova Aq syrinx@FreeBSD.org