Path: blob/main/usr.sbin/bsnmpd/modules/snmp_bridge/bridge_port.c
107769 views
/*-1* SPDX-License-Identifier: BSD-2-Clause2*3* Copyright (c) 2006 Shteryana Shopova <[email protected]>4* All rights reserved.5*6* Redistribution and use in source and binary forms, with or without7* modification, are permitted provided that the following conditions8* are met:9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11* 2. Redistributions in binary form must reproduce the above copyright12* notice, this list of conditions and the following disclaimer in the13* documentation and/or other materials provided with the distribution.14*15* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND16* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE17* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE18* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE19* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL20* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS21* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)22* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT23* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY24* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF25* SUCH DAMAGE.26*27* Bridge MIB implementation for SNMPd.28* Bridge ports.29*/3031#include <sys/queue.h>32#include <sys/socket.h>33#include <sys/types.h>3435#include <net/ethernet.h>36#include <net/if.h>37#include <net/if_mib.h>3839#include <assert.h>40#include <errno.h>41#include <stdarg.h>42#include <string.h>43#include <stdlib.h>44#include <syslog.h>4546#include <bsnmp/snmpmod.h>47#include <bsnmp/snmp_mibII.h>4849#define SNMPTREE_TYPES50#include "bridge_tree.h"51#include "bridge_snmp.h"5253TAILQ_HEAD(bridge_ports, bridge_port);5455/*56* Free the bridge base ports list.57*/58static void59bridge_ports_free(struct bridge_ports *headp)60{61struct bridge_port *bp;6263while ((bp = TAILQ_FIRST(headp)) != NULL) {64TAILQ_REMOVE(headp, bp, b_p);65free(bp);66}67}6869/*70* Free the bridge base ports from the base ports list,71* members of a specified bridge interface only.72*/73static void74bridge_port_memif_free(struct bridge_ports *headp,75struct bridge_if *bif)76{77struct bridge_port *bp;7879while (bif->f_bp != NULL && bif->sysindex == bif->f_bp->sysindex) {80bp = TAILQ_NEXT(bif->f_bp, b_p);81TAILQ_REMOVE(headp, bif->f_bp, b_p);82free(bif->f_bp);83bif->f_bp = bp;84}85}8687/*88* Insert a port entry in the base port TAILQ starting to search89* for its place from the position of the first bridge port for the bridge90* interface. Update the first bridge port if necessary.91*/92static void93bridge_port_insert_at(struct bridge_ports *headp,94struct bridge_port *bp, struct bridge_port **f_bp)95{96struct bridge_port *t1;9798assert(f_bp != NULL);99100for (t1 = *f_bp;101t1 != NULL && bp->sysindex == t1->sysindex;102t1 = TAILQ_NEXT(t1, b_p)) {103if (bp->if_idx < t1->if_idx) {104TAILQ_INSERT_BEFORE(t1, bp, b_p);105if (*f_bp == t1)106*f_bp = bp;107return;108}109}110111/*112* Handle the case when our first port was actually the113* last element of the TAILQ.114*/115if (t1 == NULL)116TAILQ_INSERT_TAIL(headp, bp, b_p);117else118TAILQ_INSERT_BEFORE(t1, bp, b_p);119}120121/*122* Find a port entry's position in the ports list according123* to it's parent bridge interface name. Returns a NULL if124* we should be at the TAILQ head, otherwise the entry after125* which we should be inserted.126*/127static struct bridge_port *128bridge_port_find_pos(struct bridge_ports *headp, uint32_t b_idx)129{130uint32_t t_idx;131struct bridge_port *t1;132133if ((t1 = TAILQ_FIRST(headp)) == NULL ||134bridge_compare_sysidx(b_idx, t1->sysindex) < 0)135return (NULL);136137t_idx = t1->sysindex;138139for (t1 = TAILQ_NEXT(t1, b_p); t1 != NULL; t1 = TAILQ_NEXT(t1, b_p)) {140if (t1->sysindex != t_idx) {141if (bridge_compare_sysidx(b_idx, t1->sysindex) < 0)142return (TAILQ_PREV(t1, bridge_ports, b_p));143else144t_idx = t1->sysindex;145}146}147148if (t1 == NULL)149t1 = TAILQ_LAST(headp, bridge_ports);150151return (t1);152}153154/*155* Insert a bridge member interface in the ports TAILQ.156*/157static void158bridge_port_memif_insert(struct bridge_ports *headp,159struct bridge_port *bp, struct bridge_port **f_bp)160{161struct bridge_port *temp;162163if (*f_bp != NULL)164bridge_port_insert_at(headp, bp, f_bp);165else {166temp = bridge_port_find_pos(headp, bp->sysindex);167168if (temp == NULL)169TAILQ_INSERT_HEAD(headp, bp, b_p);170else171TAILQ_INSERT_AFTER(headp, temp, bp, b_p);172*f_bp = bp;173}174}175176/* The global ports list. */177static struct bridge_ports bridge_ports = TAILQ_HEAD_INITIALIZER(bridge_ports);178static time_t ports_list_age;179180void181bridge_ports_update_listage(void)182{183ports_list_age = time(NULL);184}185186void187bridge_ports_fini(void)188{189bridge_ports_free(&bridge_ports);190}191192void193bridge_members_free(struct bridge_if *bif)194{195bridge_port_memif_free(&bridge_ports, bif);196}197198/*199* Find the first port in the ports list.200*/201static struct bridge_port *202bridge_port_first(void)203{204return (TAILQ_FIRST(&bridge_ports));205}206207/*208* Find the next port in the ports list.209*/210static struct bridge_port *211bridge_port_next(struct bridge_port *bp)212{213return (TAILQ_NEXT(bp, b_p));214}215216/*217* Find the first member of the specified bridge interface.218*/219struct bridge_port *220bridge_port_bif_first(struct bridge_if *bif)221{222return (bif->f_bp);223}224225/*226* Find the next member of the specified bridge interface.227*/228struct bridge_port *229bridge_port_bif_next(struct bridge_port *bp)230{231struct bridge_port *bp_next;232233if ((bp_next = TAILQ_NEXT(bp, b_p)) == NULL ||234bp_next->sysindex != bp->sysindex)235return (NULL);236237return (bp_next);238}239240/*241* Remove a bridge port from the ports list.242*/243void244bridge_port_remove(struct bridge_port *bp, struct bridge_if *bif)245{246if (bif->f_bp == bp)247bif->f_bp = bridge_port_bif_next(bp);248249TAILQ_REMOVE(&bridge_ports, bp, b_p);250free(bp);251}252253/*254* Allocate memory for a new bridge port and insert it255* in the base ports list. Return a pointer to the port's256* structure in case we want to do anything else with it.257*/258struct bridge_port *259bridge_new_port(struct mibif *mif, struct bridge_if *bif)260{261struct bridge_port *bp;262263if ((bp = (struct bridge_port *) malloc(sizeof(*bp))) == NULL) {264syslog(LOG_ERR, "bridge new member: failed: %s",265strerror(errno));266return (NULL);267}268269bzero(bp, sizeof(*bp));270271bp->sysindex = bif->sysindex;272bp->if_idx = mif->index;273bp->port_no = mif->sysindex;274strlcpy(bp->p_name, mif->name, IFNAMSIZ);275bp->circuit = oid_zeroDotZero;276277/*278* Initialize all rstpMib specific values to false/default.279* These will be set to their true values later if the bridge280* supports RSTP.281*/282bp->proto_migr = TruthValue_false;283bp->admin_edge = TruthValue_false;284bp->oper_edge = TruthValue_false;285bp->oper_ptp = TruthValue_false;286bp->admin_ptp = StpPortAdminPointToPointType_auto;287288bridge_port_memif_insert(&bridge_ports, bp, &(bif->f_bp));289290return (bp);291}292293/*294* Update our info from the corresponding mibII interface info.295*/296void297bridge_port_getinfo_mibif(struct mibif *m_if, struct bridge_port *bp)298{299bp->max_info = m_if->mib.ifmd_data.ifi_mtu;300bp->in_frames = m_if->mib.ifmd_data.ifi_ipackets;301bp->out_frames = m_if->mib.ifmd_data.ifi_opackets;302bp->in_drops = m_if->mib.ifmd_data.ifi_iqdrops;303}304305/*306* Find a port, whose SNMP's mibII ifIndex matches one of the ports,307* members of the specified bridge interface.308*/309struct bridge_port *310bridge_port_find(int32_t if_idx, struct bridge_if *bif)311{312struct bridge_port *bp;313314for (bp = bif->f_bp; bp != NULL; bp = TAILQ_NEXT(bp, b_p)) {315if (bp->sysindex != bif->sysindex) {316bp = NULL;317break;318}319320if (bp->if_idx == if_idx)321break;322}323324return (bp);325}326327void328bridge_ports_dump(struct bridge_if *bif)329{330struct bridge_port *bp;331332for (bp = bridge_port_bif_first(bif); bp != NULL;333bp = bridge_port_bif_next(bp)) {334syslog(LOG_ERR, "memif - %s, index - %d",335bp->p_name, bp->port_no);336}337}338339/*340* RFC4188 specifics.341*/342int343op_dot1d_base_port(struct snmp_context *c __unused, struct snmp_value *val,344uint sub, uint iidx __unused, enum snmp_op op)345{346struct bridge_if *bif;347struct bridge_port *bp;348349if ((bif = bridge_get_default()) == NULL)350return (SNMP_ERR_NOSUCHNAME);351352if (time(NULL) - bif->ports_age > bridge_get_data_maxage() &&353bridge_update_memif(bif) <= 0)354return (SNMP_ERR_NOSUCHNAME);355356switch (op) {357case SNMP_OP_GET:358if (val->var.len - sub != 1)359return (SNMP_ERR_NOSUCHNAME);360if ((bp = bridge_port_find(val->var.subs[sub],361bif)) == NULL)362return (SNMP_ERR_NOSUCHNAME);363goto get;364365case SNMP_OP_GETNEXT:366if (val->var.len - sub == 0) {367if ((bp = bridge_port_bif_first(bif)) == NULL)368return (SNMP_ERR_NOSUCHNAME);369} else {370if ((bp = bridge_port_find(val->var.subs[sub],371bif)) == NULL ||372(bp = bridge_port_bif_next(bp)) == NULL)373return (SNMP_ERR_NOSUCHNAME);374}375val->var.len = sub + 1;376val->var.subs[sub] = bp->port_no;377goto get;378379case SNMP_OP_SET:380return (SNMP_ERR_NOT_WRITEABLE);381382case SNMP_OP_ROLLBACK:383case SNMP_OP_COMMIT:384break;385}386abort();387388get:389switch (val->var.subs[sub - 1]) {390case LEAF_dot1dBasePort:391val->v.integer = bp->port_no;392return (SNMP_ERR_NOERROR);393394case LEAF_dot1dBasePortIfIndex:395val->v.integer = bp->if_idx;396return (SNMP_ERR_NOERROR);397398case LEAF_dot1dBasePortCircuit:399val->v.oid = bp->circuit;400return (SNMP_ERR_NOERROR);401402case LEAF_dot1dBasePortDelayExceededDiscards:403val->v.uint32 = bp->dly_ex_drops;404return (SNMP_ERR_NOERROR);405406case LEAF_dot1dBasePortMtuExceededDiscards:407val->v.uint32 = bp->dly_mtu_drops;408return (SNMP_ERR_NOERROR);409}410411abort();412}413414int415op_dot1d_stp_port(struct snmp_context *ctx, struct snmp_value *val,416uint sub, uint iidx __unused, enum snmp_op op)417{418struct bridge_if *bif;419struct bridge_port *bp;420421if ((bif = bridge_get_default()) == NULL)422return (SNMP_ERR_NOSUCHNAME);423424if (time(NULL) - bif->ports_age > bridge_get_data_maxage() &&425bridge_update_memif(bif) <= 0)426return (SNMP_ERR_NOSUCHNAME);427428switch (op) {429case SNMP_OP_GET:430if (val->var.len - sub != 1)431return (SNMP_ERR_NOSUCHNAME);432if ((bp = bridge_port_find(val->var.subs[sub],433bif)) == NULL)434return (SNMP_ERR_NOSUCHNAME);435goto get;436437case SNMP_OP_GETNEXT:438if (val->var.len - sub == 0) {439if ((bp = bridge_port_bif_first(bif)) == NULL)440return (SNMP_ERR_NOSUCHNAME);441} else {442if ((bp = bridge_port_find(val->var.subs[sub],443bif)) == NULL ||444(bp = bridge_port_bif_next(bp)) == NULL)445return (SNMP_ERR_NOSUCHNAME);446}447val->var.len = sub + 1;448val->var.subs[sub] = bp->port_no;449goto get;450451case SNMP_OP_SET:452if (val->var.len - sub != 1)453return (SNMP_ERR_NOSUCHNAME);454if ((bp = bridge_port_find(val->var.subs[sub],455bif)) == NULL)456return (SNMP_ERR_NOSUCHNAME);457458switch (val->var.subs[sub - 1]) {459case LEAF_dot1dStpPortPriority:460if (val->v.integer < 0 || val->v.integer > 255)461return (SNMP_ERR_WRONG_VALUE);462463ctx->scratch->int1 = bp->priority;464if (bridge_port_set_priority(bif->bif_name, bp,465val->v.integer) < 0)466return (SNMP_ERR_GENERR);467return (SNMP_ERR_NOERROR);468469case LEAF_dot1dStpPortEnable:470if (val->v.integer != dot1dStpPortEnable_enabled &&471val->v.integer != dot1dStpPortEnable_disabled)472return (SNMP_ERR_WRONG_VALUE);473474ctx->scratch->int1 = bp->enable;475if (bridge_port_set_stp_enable(bif->bif_name,476bp, val->v.integer) < 0)477return (SNMP_ERR_GENERR);478return (SNMP_ERR_NOERROR);479480case LEAF_dot1dStpPortPathCost:481if (val->v.integer < SNMP_PORT_MIN_PATHCOST ||482val->v.integer > SNMP_PORT_MAX_PATHCOST)483return (SNMP_ERR_WRONG_VALUE);484485ctx->scratch->int1 = bp->path_cost;486if (bridge_port_set_path_cost(bif->bif_name, bp,487val->v.integer) < 0)488return (SNMP_ERR_GENERR);489return (SNMP_ERR_NOERROR);490491case LEAF_dot1dStpPort:492case LEAF_dot1dStpPortState:493case LEAF_dot1dStpPortDesignatedRoot:494case LEAF_dot1dStpPortDesignatedCost:495case LEAF_dot1dStpPortDesignatedBridge:496case LEAF_dot1dStpPortDesignatedPort:497case LEAF_dot1dStpPortForwardTransitions:498return (SNMP_ERR_NOT_WRITEABLE);499}500abort();501502case SNMP_OP_ROLLBACK:503if ((bp = bridge_port_find(val->var.subs[sub],504bif)) == NULL)505return (SNMP_ERR_GENERR);506switch (val->var.subs[sub - 1]) {507case LEAF_dot1dStpPortPriority:508bridge_port_set_priority(bif->bif_name, bp,509ctx->scratch->int1);510break;511case LEAF_dot1dStpPortEnable:512bridge_port_set_stp_enable(bif->bif_name, bp,513ctx->scratch->int1);514break;515case LEAF_dot1dStpPortPathCost:516bridge_port_set_path_cost(bif->bif_name, bp,517ctx->scratch->int1);518break;519}520return (SNMP_ERR_NOERROR);521522case SNMP_OP_COMMIT:523return (SNMP_ERR_NOERROR);524}525abort();526527get:528switch (val->var.subs[sub - 1]) {529case LEAF_dot1dStpPort:530val->v.integer = bp->port_no;531return (SNMP_ERR_NOERROR);532533case LEAF_dot1dStpPortPriority:534val->v.integer = bp->priority;535return (SNMP_ERR_NOERROR);536537case LEAF_dot1dStpPortState:538val->v.integer = bp->state;539return (SNMP_ERR_NOERROR);540541case LEAF_dot1dStpPortEnable:542val->v.integer = bp->enable;543return (SNMP_ERR_NOERROR);544545case LEAF_dot1dStpPortPathCost:546val->v.integer = bp->path_cost;547return (SNMP_ERR_NOERROR);548549case LEAF_dot1dStpPortDesignatedRoot:550return (string_get(val, bp->design_root,551SNMP_BRIDGE_ID_LEN));552553case LEAF_dot1dStpPortDesignatedCost:554val->v.integer = bp->design_cost;555return (SNMP_ERR_NOERROR);556557case LEAF_dot1dStpPortDesignatedBridge:558return (string_get(val, bp->design_bridge,559SNMP_BRIDGE_ID_LEN));560561case LEAF_dot1dStpPortDesignatedPort:562return (string_get(val, bp->design_port, 2));563564case LEAF_dot1dStpPortForwardTransitions:565val->v.uint32 = bp->fwd_trans;566return (SNMP_ERR_NOERROR);567}568569abort();570}571572int573op_dot1d_stp_ext_port(struct snmp_context *ctx, struct snmp_value *val,574uint sub, uint iidx __unused, enum snmp_op op)575{576struct bridge_if *bif;577struct bridge_port *bp;578579if ((bif = bridge_get_default()) == NULL)580return (SNMP_ERR_NOSUCHNAME);581582if (time(NULL) - bif->ports_age > bridge_get_data_maxage() &&583bridge_update_memif(bif) <= 0)584return (SNMP_ERR_NOSUCHNAME);585586switch (op) {587case SNMP_OP_GET:588if (val->var.len - sub != 1)589return (SNMP_ERR_NOSUCHNAME);590if ((bp = bridge_port_find(val->var.subs[sub],591bif)) == NULL)592return (SNMP_ERR_NOSUCHNAME);593goto get;594595case SNMP_OP_GETNEXT:596if (val->var.len - sub == 0) {597if ((bp = bridge_port_bif_first(bif)) == NULL)598return (SNMP_ERR_NOSUCHNAME);599} else {600if ((bp = bridge_port_find(val->var.subs[sub],601bif)) == NULL ||602(bp = bridge_port_bif_next(bp)) == NULL)603return (SNMP_ERR_NOSUCHNAME);604}605val->var.len = sub + 1;606val->var.subs[sub] = bp->port_no;607goto get;608609case SNMP_OP_SET:610if (val->var.len - sub != 1)611return (SNMP_ERR_NOSUCHNAME);612if ((bp = bridge_port_find(val->var.subs[sub],613bif)) == NULL)614return (SNMP_ERR_NOSUCHNAME);615616switch (val->var.subs[sub - 1]) {617case LEAF_dot1dStpPortAdminEdgePort:618if (val->v.integer != TruthValue_true &&619val->v.integer != TruthValue_false)620return (SNMP_ERR_WRONG_VALUE);621622ctx->scratch->int1 = bp->admin_edge;623if (bridge_port_set_admin_edge(bif->bif_name, bp,624val->v.integer) < 0)625return (SNMP_ERR_GENERR);626return (SNMP_ERR_NOERROR);627628case LEAF_dot1dStpPortAdminPointToPoint:629if (val->v.integer < 0 || val->v.integer >630StpPortAdminPointToPointType_auto)631return (SNMP_ERR_WRONG_VALUE);632633ctx->scratch->int1 = bp->admin_ptp;634if (bridge_port_set_admin_ptp(bif->bif_name, bp,635val->v.integer) < 0)636return (SNMP_ERR_GENERR);637return (SNMP_ERR_NOERROR);638639case LEAF_dot1dStpPortAdminPathCost:640if (val->v.integer < SNMP_PORT_MIN_PATHCOST ||641val->v.integer > SNMP_PORT_MAX_PATHCOST)642return (SNMP_ERR_WRONG_VALUE);643644ctx->scratch->int1 = bp->admin_path_cost;645if (bridge_port_set_path_cost(bif->bif_name, bp,646val->v.integer) < 0)647return (SNMP_ERR_GENERR);648return (SNMP_ERR_NOERROR);649650case LEAF_dot1dStpPortProtocolMigration:651case LEAF_dot1dStpPortOperEdgePort:652case LEAF_dot1dStpPortOperPointToPoint:653return (SNMP_ERR_NOT_WRITEABLE);654}655abort();656657case SNMP_OP_ROLLBACK:658if ((bp = bridge_port_find(val->var.subs[sub],659bif)) == NULL)660return (SNMP_ERR_GENERR);661662switch (val->var.subs[sub - 1]) {663case LEAF_dot1dStpPortAdminEdgePort:664bridge_port_set_admin_edge(bif->bif_name, bp,665ctx->scratch->int1);666break;667case LEAF_dot1dStpPortAdminPointToPoint:668bridge_port_set_admin_ptp(bif->bif_name, bp,669ctx->scratch->int1);670break;671case LEAF_dot1dStpPortAdminPathCost:672bridge_port_set_path_cost(bif->bif_name, bp,673ctx->scratch->int1);674break;675}676return (SNMP_ERR_NOERROR);677678case SNMP_OP_COMMIT:679return (SNMP_ERR_NOERROR);680}681abort();682683get:684switch (val->var.subs[sub - 1]) {685case LEAF_dot1dStpPortProtocolMigration:686val->v.integer = bp->proto_migr;687return (SNMP_ERR_NOERROR);688689case LEAF_dot1dStpPortAdminEdgePort:690val->v.integer = bp->admin_edge;691return (SNMP_ERR_NOERROR);692693case LEAF_dot1dStpPortOperEdgePort:694val->v.integer = bp->oper_edge;695return (SNMP_ERR_NOERROR);696697case LEAF_dot1dStpPortAdminPointToPoint:698val->v.integer = bp->admin_ptp;699return (SNMP_ERR_NOERROR);700701case LEAF_dot1dStpPortOperPointToPoint:702val->v.integer = bp->oper_ptp;703return (SNMP_ERR_NOERROR);704705case LEAF_dot1dStpPortAdminPathCost:706val->v.integer = bp->admin_path_cost;707return (SNMP_ERR_NOERROR);708}709710abort();711}712713int714op_dot1d_tp_port(struct snmp_context *c __unused, struct snmp_value *val,715uint sub, uint iidx __unused, enum snmp_op op)716{717struct bridge_if *bif;718struct bridge_port *bp;719720if ((bif = bridge_get_default()) == NULL)721return (SNMP_ERR_NOSUCHNAME);722723if (time(NULL) - bif->ports_age > bridge_get_data_maxage() &&724bridge_update_memif(bif) <= 0)725return (SNMP_ERR_NOSUCHNAME);726727switch (op) {728case SNMP_OP_GET:729if (val->var.len - sub != 1)730return (SNMP_ERR_NOSUCHNAME);731if ((bp = bridge_port_find(val->var.subs[sub],732bif)) == NULL)733return (SNMP_ERR_NOSUCHNAME);734goto get;735736case SNMP_OP_GETNEXT:737if (val->var.len - sub == 0) {738if ((bp = bridge_port_bif_first(bif)) == NULL)739return (SNMP_ERR_NOSUCHNAME);740} else {741if ((bp = bridge_port_find(val->var.subs[sub],742bif)) == NULL ||743(bp = bridge_port_bif_next(bp)) == NULL)744return (SNMP_ERR_NOSUCHNAME);745}746val->var.len = sub + 1;747val->var.subs[sub] = bp->port_no;748goto get;749750case SNMP_OP_SET:751return (SNMP_ERR_NOT_WRITEABLE);752753case SNMP_OP_ROLLBACK:754case SNMP_OP_COMMIT:755break;756}757abort();758759get:760switch (val->var.subs[sub - 1]) {761case LEAF_dot1dTpPort:762val->v.integer = bp->port_no;763return (SNMP_ERR_NOERROR);764765case LEAF_dot1dTpPortMaxInfo:766val->v.integer = bp->max_info;767return (SNMP_ERR_NOERROR);768769case LEAF_dot1dTpPortInFrames:770val->v.uint32 = bp->in_frames;771return (SNMP_ERR_NOERROR);772773case LEAF_dot1dTpPortOutFrames:774val->v.uint32 = bp->out_frames;775return (SNMP_ERR_NOERROR);776777case LEAF_dot1dTpPortInDiscards:778val->v.uint32 = bp->in_drops;779return (SNMP_ERR_NOERROR);780}781782abort();783}784785/*786* Private BEGEMOT-BRIDGE-MIB specifics.787*/788789/*790* Construct a bridge port entry index.791*/792static int793bridge_port_index_append(struct asn_oid *oid, uint sub,794const struct bridge_port *bp)795{796uint i;797const char *b_name;798799if ((b_name = bridge_if_find_name(bp->sysindex)) == NULL)800return (-1);801802oid->len = sub + strlen(b_name) + 1 + 1;803oid->subs[sub] = strlen(b_name);804805for (i = 1; i <= strlen(b_name); i++)806oid->subs[sub + i] = b_name[i - 1];807808oid->subs[sub + i] = bp->port_no;809810return (0);811}812813/*814* Get the port entry from an entry's index.815*/816static struct bridge_port *817bridge_port_index_get(const struct asn_oid *oid, uint sub, int8_t status)818{819uint i;820int32_t port_no;821char bif_name[IFNAMSIZ];822struct bridge_if *bif;823struct bridge_port *bp;824825if (oid->len - sub != oid->subs[sub] + 2 ||826oid->subs[sub] >= IFNAMSIZ)827return (NULL);828829for (i = 0; i < oid->subs[sub]; i++)830bif_name[i] = oid->subs[sub + i + 1];831bif_name[i] = '\0';832833port_no = oid->subs[sub + i + 1];834835if ((bif = bridge_if_find_ifname(bif_name)) == NULL)836return (NULL);837838if ((bp = bridge_port_find(port_no, bif)) == NULL ||839(status == 0 && bp->status != RowStatus_active))840return (NULL);841842return (bp);843}844845/*846* Get the next port entry from an entry's index.847*/848static struct bridge_port *849bridge_port_index_getnext(const struct asn_oid *oid, uint sub, int8_t status)850{851uint i;852int32_t port_no;853char bif_name[IFNAMSIZ];854struct bridge_if *bif;855struct bridge_port *bp;856857if (oid->len - sub == 0)858bp = bridge_port_first();859else {860if (oid->len - sub != oid->subs[sub] + 2 ||861oid->subs[sub] >= IFNAMSIZ)862return (NULL);863864for (i = 0; i < oid->subs[sub]; i++)865bif_name[i] = oid->subs[sub + i + 1];866bif_name[i] = '\0';867868port_no = oid->subs[sub + i + 1];869870if ((bif = bridge_if_find_ifname(bif_name)) == NULL ||871(bp = bridge_port_find(port_no, bif)) == NULL)872return (NULL);873874bp = bridge_port_next(bp);875}876877if (status == 1)878return (bp);879880while (bp != NULL) {881if (bp->status == RowStatus_active)882break;883bp = bridge_port_next(bp);884}885886return (bp);887}888889/*890* Read the bridge name and port index from a ASN OID structure.891*/892static int893bridge_port_index_decode(const struct asn_oid *oid, uint sub,894char *b_name, int32_t *idx)895{896uint i;897898if (oid->len - sub != oid->subs[sub] + 2 ||899oid->subs[sub] >= IFNAMSIZ)900return (-1);901902for (i = 0; i < oid->subs[sub]; i++)903b_name[i] = oid->subs[sub + i + 1];904b_name[i] = '\0';905906*idx = oid->subs[sub + i + 1];907return (0);908}909910static int911bridge_port_set_status(struct snmp_context *ctx,912struct snmp_value *val, uint sub)913{914int32_t if_idx;915char b_name[IFNAMSIZ];916struct bridge_if *bif;917struct bridge_port *bp;918struct mibif *mif;919920if (bridge_port_index_decode(&val->var, sub, b_name, &if_idx) < 0)921return (SNMP_ERR_INCONS_VALUE);922923if ((bif = bridge_if_find_ifname(b_name)) == NULL ||924(mif = mib_find_if(if_idx)) == NULL)925return (SNMP_ERR_INCONS_VALUE);926927bp = bridge_port_find(if_idx, bif);928929switch (val->v.integer) {930case RowStatus_active:931if (bp == NULL)932return (SNMP_ERR_INCONS_VALUE);933934if (bp->span_enable == 0)935return (SNMP_ERR_INCONS_VALUE);936937ctx->scratch->int1 = bp->status;938bp->status = RowStatus_active;939break;940941case RowStatus_notInService:942if (bp == NULL || bp->span_enable == 0 ||943bp->status == RowStatus_active)944return (SNMP_ERR_INCONS_VALUE);945946ctx->scratch->int1 = bp->status;947bp->status = RowStatus_notInService;948949case RowStatus_notReady:950/* FALLTHROUGH */951case RowStatus_createAndGo:952return (SNMP_ERR_INCONS_VALUE);953954case RowStatus_createAndWait:955if (bp != NULL)956return (SNMP_ERR_INCONS_VALUE);957958if ((bp = bridge_new_port(mif, bif)) == NULL)959return (SNMP_ERR_GENERR);960961ctx->scratch->int1 = RowStatus_destroy;962bp->status = RowStatus_notReady;963break;964965case RowStatus_destroy:966if (bp == NULL)967return (SNMP_ERR_INCONS_VALUE);968969ctx->scratch->int1 = bp->status;970bp->status = RowStatus_destroy;971break;972}973974return (SNMP_ERR_NOERROR);975}976977static int978bridge_port_rollback_status(struct snmp_context *ctx,979struct snmp_value *val, uint sub)980{981int32_t if_idx;982char b_name[IFNAMSIZ];983struct bridge_if *bif;984struct bridge_port *bp;985986if (bridge_port_index_decode(&val->var, sub, b_name, &if_idx) < 0)987return (SNMP_ERR_GENERR);988989if ((bif = bridge_if_find_ifname(b_name)) == NULL ||990(bp = bridge_port_find(if_idx, bif)) == NULL)991return (SNMP_ERR_GENERR);992993if (ctx->scratch->int1 == RowStatus_destroy)994bridge_port_remove(bp, bif);995else996bp->status = ctx->scratch->int1;997998return (SNMP_ERR_NOERROR);999}10001001static int1002bridge_port_commit_status(struct snmp_value *val, uint sub)1003{1004int32_t if_idx;1005char b_name[IFNAMSIZ];1006struct bridge_if *bif;1007struct bridge_port *bp;10081009if (bridge_port_index_decode(&val->var, sub, b_name, &if_idx) < 0)1010return (SNMP_ERR_GENERR);10111012if ((bif = bridge_if_find_ifname(b_name)) == NULL ||1013(bp = bridge_port_find(if_idx, bif)) == NULL)1014return (SNMP_ERR_GENERR);10151016switch (bp->status) {1017case RowStatus_active:1018if (bridge_port_addm(bp, b_name) < 0)1019return (SNMP_ERR_COMMIT_FAILED);1020break;10211022case RowStatus_destroy:1023if (bridge_port_delm(bp, b_name) < 0)1024return (SNMP_ERR_COMMIT_FAILED);1025bridge_port_remove(bp, bif);1026break;1027}10281029return (SNMP_ERR_NOERROR);1030}10311032static int1033bridge_port_set_span_enable(struct snmp_context *ctx,1034struct snmp_value *val, uint sub)1035{1036int32_t if_idx;1037char b_name[IFNAMSIZ];1038struct bridge_if *bif;1039struct bridge_port *bp;1040struct mibif *mif;10411042if (val->v.integer != begemotBridgeBaseSpanEnabled_enabled &&1043val->v.integer != begemotBridgeBaseSpanEnabled_disabled)1044return (SNMP_ERR_BADVALUE);10451046if (bridge_port_index_decode(&val->var, sub, b_name, &if_idx) < 0)1047return (SNMP_ERR_INCONS_VALUE);10481049if ((bif = bridge_if_find_ifname(b_name)) == NULL)1050return (SNMP_ERR_INCONS_VALUE);10511052if ((bp = bridge_port_find(if_idx, bif)) == NULL) {1053if ((mif = mib_find_if(if_idx)) == NULL)1054return (SNMP_ERR_INCONS_VALUE);10551056if ((bp = bridge_new_port(mif, bif)) == NULL)1057return (SNMP_ERR_GENERR);10581059ctx->scratch->int1 = RowStatus_destroy;1060} else if (bp->status == RowStatus_active) {1061return (SNMP_ERR_INCONS_VALUE);1062} else {1063ctx->scratch->int1 = bp->status;1064}10651066bp->span_enable = val->v.integer;1067bp->status = RowStatus_notInService;10681069return (SNMP_ERR_NOERROR);1070}10711072int1073op_begemot_base_port(struct snmp_context *ctx, struct snmp_value *val,1074uint sub, uint iidx __unused, enum snmp_op op)1075{1076int8_t status, which;1077const char *bname;1078struct bridge_port *bp;10791080if (time(NULL) - ports_list_age > bridge_get_data_maxage())1081bridge_update_all_ports();10821083which = val->var.subs[sub - 1];1084status = 0;10851086switch (op) {1087case SNMP_OP_GET:1088if (which == LEAF_begemotBridgeBaseSpanEnabled ||1089which == LEAF_begemotBridgeBasePortStatus)1090status = 1;1091if ((bp = bridge_port_index_get(&val->var, sub,1092status)) == NULL)1093return (SNMP_ERR_NOSUCHNAME);1094goto get;10951096case SNMP_OP_GETNEXT:1097if (which == LEAF_begemotBridgeBaseSpanEnabled ||1098which == LEAF_begemotBridgeBasePortStatus)1099status = 1;1100if ((bp = bridge_port_index_getnext(&val->var, sub,1101status)) == NULL ||1102bridge_port_index_append(&val->var, sub, bp) < 0)1103return (SNMP_ERR_NOSUCHNAME);1104goto get;11051106case SNMP_OP_SET:1107switch (which) {1108case LEAF_begemotBridgeBaseSpanEnabled:1109return (bridge_port_set_span_enable(ctx, val, sub));11101111case LEAF_begemotBridgeBasePortStatus:1112return (bridge_port_set_status(ctx, val, sub));11131114case LEAF_begemotBridgeBasePortPrivate:1115if ((bp = bridge_port_index_get(&val->var, sub,1116status)) == NULL)1117return (SNMP_ERR_NOSUCHNAME);1118if ((bname = bridge_if_find_name(bp->sysindex)) == NULL)1119return (SNMP_ERR_GENERR);1120ctx->scratch->int1 = bp->priv_set;1121return (bridge_port_set_private(bname, bp,1122val->v.integer));11231124case LEAF_begemotBridgeBasePort:1125case LEAF_begemotBridgeBasePortIfIndex:1126case LEAF_begemotBridgeBasePortDelayExceededDiscards:1127case LEAF_begemotBridgeBasePortMtuExceededDiscards:1128return (SNMP_ERR_NOT_WRITEABLE);1129}1130abort();11311132case SNMP_OP_ROLLBACK:1133switch (which) {1134case LEAF_begemotBridgeBaseSpanEnabled:1135/* FALLTHROUGH */1136case LEAF_begemotBridgeBasePortStatus:1137return (bridge_port_rollback_status(ctx, val, sub));1138case LEAF_begemotBridgeBasePortPrivate:1139if ((bp = bridge_port_index_get(&val->var, sub,1140status)) == NULL)1141return (SNMP_ERR_GENERR);1142if ((bname = bridge_if_find_name(bp->sysindex)) == NULL)1143return (SNMP_ERR_GENERR);1144return (bridge_port_set_private(bname, bp,1145ctx->scratch->int1));1146}1147return (SNMP_ERR_NOERROR);11481149case SNMP_OP_COMMIT:1150if (which == LEAF_begemotBridgeBasePortStatus)1151return (bridge_port_commit_status(val, sub));11521153return (SNMP_ERR_NOERROR);1154}1155abort();11561157get:1158switch (which) {1159case LEAF_begemotBridgeBasePort:1160val->v.integer = bp->port_no;1161return (SNMP_ERR_NOERROR);11621163case LEAF_begemotBridgeBasePortIfIndex:1164val->v.integer = bp->if_idx;1165return (SNMP_ERR_NOERROR);11661167case LEAF_begemotBridgeBaseSpanEnabled:1168val->v.integer = bp->span_enable;1169return (SNMP_ERR_NOERROR);11701171case LEAF_begemotBridgeBasePortDelayExceededDiscards:1172val->v.uint32 = bp->dly_ex_drops;1173return (SNMP_ERR_NOERROR);11741175case LEAF_begemotBridgeBasePortMtuExceededDiscards:1176val->v.uint32 = bp->dly_mtu_drops;1177return (SNMP_ERR_NOERROR);11781179case LEAF_begemotBridgeBasePortStatus:1180val->v.integer = bp->status;1181return (SNMP_ERR_NOERROR);11821183case LEAF_begemotBridgeBasePortPrivate:1184val->v.integer = bp->priv_set;1185return (SNMP_ERR_NOERROR);1186}11871188abort();1189}11901191int1192op_begemot_stp_port(struct snmp_context *ctx, struct snmp_value *val,1193uint sub, uint iidx __unused, enum snmp_op op)1194{1195struct bridge_port *bp;1196const char *b_name;11971198if (time(NULL) - ports_list_age > bridge_get_data_maxage())1199bridge_update_all_ports();12001201switch (op) {1202case SNMP_OP_GET:1203if ((bp = bridge_port_index_get(&val->var, sub, 0)) == NULL)1204return (SNMP_ERR_NOSUCHNAME);1205goto get;12061207case SNMP_OP_GETNEXT:1208if ((bp = bridge_port_index_getnext(&val->var, sub, 0)) ==1209NULL || bridge_port_index_append(&val->var, sub, bp) < 0)1210return (SNMP_ERR_NOSUCHNAME);1211goto get;12121213case SNMP_OP_SET:1214if ((bp = bridge_port_index_get(&val->var, sub, 0)) == NULL)1215return (SNMP_ERR_NOSUCHNAME);1216if ((b_name = bridge_if_find_name(bp->sysindex)) == NULL)1217return (SNMP_ERR_GENERR);12181219switch (val->var.subs[sub - 1]) {1220case LEAF_begemotBridgeStpPortPriority:1221if (val->v.integer < 0 || val->v.integer > 255)1222return (SNMP_ERR_WRONG_VALUE);12231224ctx->scratch->int1 = bp->priority;1225if (bridge_port_set_priority(b_name, bp,1226val->v.integer) < 0)1227return (SNMP_ERR_GENERR);1228return (SNMP_ERR_NOERROR);12291230case LEAF_begemotBridgeStpPortEnable:1231if (val->v.integer !=1232(int32_t)begemotBridgeStpPortEnable_enabled ||1233val->v.integer !=1234(int32_t)begemotBridgeStpPortEnable_disabled)1235return (SNMP_ERR_WRONG_VALUE);12361237ctx->scratch->int1 = bp->enable;1238if (bridge_port_set_stp_enable(b_name, bp,1239val->v.integer) < 0)1240return (SNMP_ERR_GENERR);1241return (SNMP_ERR_NOERROR);12421243case LEAF_begemotBridgeStpPortPathCost:1244if (val->v.integer < SNMP_PORT_MIN_PATHCOST ||1245val->v.integer > SNMP_PORT_MAX_PATHCOST)1246return (SNMP_ERR_WRONG_VALUE);12471248ctx->scratch->int1 = bp->path_cost;1249if (bridge_port_set_path_cost(b_name, bp,1250val->v.integer) < 0)1251return (SNMP_ERR_GENERR);1252return (SNMP_ERR_NOERROR);12531254case LEAF_begemotBridgeStpPort:1255case LEAF_begemotBridgeStpPortState:1256case LEAF_begemotBridgeStpPortDesignatedRoot:1257case LEAF_begemotBridgeStpPortDesignatedCost:1258case LEAF_begemotBridgeStpPortDesignatedBridge:1259case LEAF_begemotBridgeStpPortDesignatedPort:1260case LEAF_begemotBridgeStpPortForwardTransitions:1261return (SNMP_ERR_NOT_WRITEABLE);1262}1263abort();12641265case SNMP_OP_ROLLBACK:1266if ((bp = bridge_port_index_get(&val->var, sub, 0)) == NULL ||1267(b_name = bridge_if_find_name(bp->sysindex)) == NULL)1268return (SNMP_ERR_GENERR);12691270switch (val->var.subs[sub - 1]) {1271case LEAF_begemotBridgeStpPortPriority:1272bridge_port_set_priority(b_name, bp,1273ctx->scratch->int1);1274break;1275case LEAF_begemotBridgeStpPortEnable:1276bridge_port_set_stp_enable(b_name, bp,1277ctx->scratch->int1);1278break;1279case LEAF_begemotBridgeStpPortPathCost:1280bridge_port_set_path_cost(b_name, bp,1281ctx->scratch->int1);1282break;1283}1284return (SNMP_ERR_NOERROR);12851286case SNMP_OP_COMMIT:1287return (SNMP_ERR_NOERROR);1288}1289abort();12901291get:1292switch (val->var.subs[sub - 1]) {1293case LEAF_begemotBridgeStpPort:1294val->v.integer = bp->port_no;1295return (SNMP_ERR_NOERROR);12961297case LEAF_begemotBridgeStpPortPriority:1298val->v.integer = bp->priority;1299return (SNMP_ERR_NOERROR);13001301case LEAF_begemotBridgeStpPortState:1302val->v.integer = bp->state;1303return (SNMP_ERR_NOERROR);13041305case LEAF_begemotBridgeStpPortEnable:1306val->v.integer = bp->enable;1307return (SNMP_ERR_NOERROR);13081309case LEAF_begemotBridgeStpPortPathCost:1310val->v.integer = bp->path_cost;1311return (SNMP_ERR_NOERROR);13121313case LEAF_begemotBridgeStpPortDesignatedRoot:1314return (string_get(val, bp->design_root, SNMP_BRIDGE_ID_LEN));13151316case LEAF_begemotBridgeStpPortDesignatedCost:1317val->v.integer = bp->design_cost;1318return (SNMP_ERR_NOERROR);13191320case LEAF_begemotBridgeStpPortDesignatedBridge:1321return (string_get(val, bp->design_bridge, SNMP_BRIDGE_ID_LEN));13221323case LEAF_begemotBridgeStpPortDesignatedPort:1324return (string_get(val, bp->design_port, 2));13251326case LEAF_begemotBridgeStpPortForwardTransitions:1327val->v.uint32 = bp->fwd_trans;1328return (SNMP_ERR_NOERROR);1329}13301331abort();1332}13331334int1335op_begemot_stp_ext_port(struct snmp_context *ctx, struct snmp_value *val,1336uint sub, uint iidx __unused, enum snmp_op op)1337{1338struct bridge_port *bp;1339const char *b_name;13401341if (time(NULL) - ports_list_age > bridge_get_data_maxage())1342bridge_update_all_ports();13431344switch (op) {1345case SNMP_OP_GET:1346if ((bp = bridge_port_index_get(&val->var, sub, 0)) == NULL)1347return (SNMP_ERR_NOSUCHNAME);1348goto get;13491350case SNMP_OP_GETNEXT:1351if ((bp = bridge_port_index_getnext(&val->var, sub, 0)) ==1352NULL || bridge_port_index_append(&val->var, sub, bp) < 0)1353return (SNMP_ERR_NOSUCHNAME);1354goto get;13551356case SNMP_OP_SET:1357if ((bp = bridge_port_index_get(&val->var, sub, 0)) == NULL)1358return (SNMP_ERR_NOSUCHNAME);1359if ((b_name = bridge_if_find_name(bp->sysindex)) == NULL)1360return (SNMP_ERR_GENERR);13611362switch (val->var.subs[sub - 1]) {1363case LEAF_begemotBridgeStpPortAdminEdgePort:1364if (val->v.integer != TruthValue_true &&1365val->v.integer != TruthValue_false)1366return (SNMP_ERR_WRONG_VALUE);13671368ctx->scratch->int1 = bp->admin_edge;1369if (bridge_port_set_admin_edge(b_name, bp,1370val->v.integer) < 0)1371return (SNMP_ERR_GENERR);1372return (SNMP_ERR_NOERROR);13731374case LEAF_begemotBridgeStpPortAdminPointToPoint:1375if (val->v.integer < 0 || val->v.integer >1376StpPortAdminPointToPointType_auto)1377return (SNMP_ERR_WRONG_VALUE);13781379ctx->scratch->int1 = bp->admin_ptp;1380if (bridge_port_set_admin_ptp(b_name, bp,1381val->v.integer) < 0)1382return (SNMP_ERR_GENERR);1383return (SNMP_ERR_NOERROR);13841385case LEAF_begemotBridgeStpPortAdminPathCost:1386if (val->v.integer < SNMP_PORT_MIN_PATHCOST ||1387val->v.integer > SNMP_PORT_MAX_PATHCOST)1388return (SNMP_ERR_WRONG_VALUE);13891390ctx->scratch->int1 = bp->admin_path_cost;1391if (bridge_port_set_path_cost(b_name, bp,1392val->v.integer) < 0)1393return (SNMP_ERR_GENERR);1394return (SNMP_ERR_NOERROR);13951396case LEAF_begemotBridgeStpPortProtocolMigration:1397case LEAF_begemotBridgeStpPortOperEdgePort:1398case LEAF_begemotBridgeStpPortOperPointToPoint:1399return (SNMP_ERR_NOT_WRITEABLE);1400}1401abort();14021403case SNMP_OP_ROLLBACK:1404if ((bp = bridge_port_index_get(&val->var, sub, 0)) == NULL ||1405(b_name = bridge_if_find_name(bp->sysindex)) == NULL)1406return (SNMP_ERR_GENERR);14071408switch (val->var.subs[sub - 1]) {1409case LEAF_begemotBridgeStpPortAdminEdgePort:1410bridge_port_set_admin_edge(b_name, bp,1411ctx->scratch->int1);1412break;1413case LEAF_begemotBridgeStpPortAdminPointToPoint:1414bridge_port_set_admin_ptp(b_name, bp,1415ctx->scratch->int1);1416break;1417case LEAF_begemotBridgeStpPortAdminPathCost:1418bridge_port_set_path_cost(b_name, bp,1419ctx->scratch->int1);1420break;1421}1422return (SNMP_ERR_NOERROR);14231424case SNMP_OP_COMMIT:1425return (SNMP_ERR_NOERROR);1426}1427abort();14281429get:1430switch (val->var.subs[sub - 1]) {1431case LEAF_begemotBridgeStpPortProtocolMigration:1432val->v.integer = bp->proto_migr;1433return (SNMP_ERR_NOERROR);14341435case LEAF_begemotBridgeStpPortAdminEdgePort:1436val->v.integer = bp->admin_edge;1437return (SNMP_ERR_NOERROR);14381439case LEAF_begemotBridgeStpPortOperEdgePort:1440val->v.integer = bp->oper_edge;1441return (SNMP_ERR_NOERROR);14421443case LEAF_begemotBridgeStpPortAdminPointToPoint:1444val->v.integer = bp->admin_ptp;1445return (SNMP_ERR_NOERROR);14461447case LEAF_begemotBridgeStpPortOperPointToPoint:1448val->v.integer = bp->oper_ptp;1449return (SNMP_ERR_NOERROR);14501451case LEAF_begemotBridgeStpPortAdminPathCost:1452val->v.integer = bp->admin_path_cost;1453return (SNMP_ERR_NOERROR);1454}14551456abort();1457}14581459int1460op_begemot_tp_port(struct snmp_context *c __unused, struct snmp_value *val,1461uint sub, uint iidx __unused, enum snmp_op op)1462{1463struct bridge_port *bp;14641465if (time(NULL) - ports_list_age > bridge_get_data_maxage())1466bridge_update_all_ports();14671468switch (op) {1469case SNMP_OP_GET:1470if ((bp = bridge_port_index_get(&val->var, sub, 0)) == NULL)1471return (SNMP_ERR_NOSUCHNAME);1472goto get;14731474case SNMP_OP_GETNEXT:1475if ((bp = bridge_port_index_getnext(&val->var, sub, 0)) ==1476NULL || bridge_port_index_append(&val->var, sub, bp) < 0)1477return (SNMP_ERR_NOSUCHNAME);1478goto get;14791480case SNMP_OP_SET:1481return (SNMP_ERR_NOT_WRITEABLE);14821483case SNMP_OP_ROLLBACK:1484case SNMP_OP_COMMIT:1485break;1486}1487abort();14881489get:1490switch (val->var.subs[sub - 1]) {1491case LEAF_begemotBridgeTpPort:1492val->v.integer = bp->port_no;1493return (SNMP_ERR_NOERROR);14941495case LEAF_begemotBridgeTpPortMaxInfo:1496val->v.integer = bp->max_info;1497return (SNMP_ERR_NOERROR);14981499case LEAF_begemotBridgeTpPortInFrames:1500val->v.uint32 = bp->in_frames;1501return (SNMP_ERR_NOERROR);15021503case LEAF_begemotBridgeTpPortOutFrames:1504val->v.uint32 = bp->out_frames;1505return (SNMP_ERR_NOERROR);15061507case LEAF_begemotBridgeTpPortInDiscards:1508val->v.uint32 = bp->in_drops;1509return (SNMP_ERR_NOERROR);1510}15111512abort();1513}151415151516