Add some statistics that are needed to support RFC4188 as part of the SoC2006

work on a bridge monitoring module for BSNMP.

Submitted by:	shteryana (SoC 2006)
This commit is contained in:
Andrew Thompson 2006-07-31 20:24:46 +00:00
parent af73d4e69e
commit 51383c37cd
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=160867
4 changed files with 161 additions and 1 deletions

View File

@ -112,6 +112,7 @@ static void bstp_make_forwarding(struct bstp_state *,
static void bstp_make_blocking(struct bstp_state *,
struct bstp_port *);
static void bstp_set_port_state(struct bstp_port *, uint8_t);
static void bstp_update_forward_transitions(struct bstp_port *);
#ifdef notused
static void bstp_set_bridge_priority(struct bstp_state *, uint64_t);
static void bstp_set_port_priority(struct bstp_state *,
@ -530,6 +531,12 @@ bstp_set_port_state(struct bstp_port *bp, uint8_t state)
bp->bp_state = state;
}
static void
bstp_update_forward_transitions(struct bstp_port *bp)
{
bp->bp_forward_transitions++;
}
static void
bstp_topology_change_detection(struct bstp_state *bs)
{
@ -543,6 +550,7 @@ bstp_topology_change_detection(struct bstp_state *bs)
bstp_timer_start(&bs->bs_tcn_timer, 0);
}
bs->bs_topology_change_detected = 1;
getmicrotime(&bs->bs_last_tc_time);
}
static void
@ -749,6 +757,7 @@ bstp_forward_delay_timer_expiry(struct bstp_state *bs,
bstp_timer_start(&bp->bp_forward_delay_timer, 0);
} else if (bp->bp_state == BSTP_IFSTATE_LEARNING) {
bstp_set_port_state(bp, BSTP_IFSTATE_FORWARDING);
bstp_update_forward_transitions(bp);
if (bstp_designated_for_some_port(bs) &&
bp->bp_change_detection_enabled)
bstp_topology_change_detection(bs);
@ -865,6 +874,7 @@ bstp_reinit(struct bstp_state *bs)
LIST_FOREACH(bp, &bs->bs_bplist, bp_next)
bstp_ifupdstatus(bs, bp);
getmicrotime(&bs->bs_last_tc_time);
bstp_port_state_selection(bs);
bstp_config_bpdu_generation(bs);
bstp_timer_start(&bs->bs_hello_timer, 0);

View File

@ -201,6 +201,7 @@ struct bstp_port {
uint8_t bp_config_pending;
uint8_t bp_change_detection_enabled;
uint8_t bp_priority;
uint32_t bp_forward_transitions;
};
/*
@ -229,6 +230,7 @@ struct bstp_state {
struct bstp_timer bs_tcn_timer;
struct callout bs_bstpcallout; /* STP callout */
struct bstp_timer bs_link_timer;
struct timeval bs_last_tc_time;
LIST_HEAD(, bstp_port) bs_bplist;
};

View File

@ -212,6 +212,7 @@ struct bridge_softc {
uint32_t sc_rthash_key; /* key for hash */
LIST_HEAD(, bridge_iflist) sc_spanlist; /* span ports list */
struct bstp_state sc_stp; /* STP state */
uint32_t sc_brtexceeded; /* # of cache drops */
};
static struct mtx bridge_list_mtx;
@ -299,6 +300,9 @@ static int bridge_ioctl_sifprio(struct bridge_softc *, void *);
static int bridge_ioctl_sifcost(struct bridge_softc *, void *);
static int bridge_ioctl_addspan(struct bridge_softc *, void *);
static int bridge_ioctl_delspan(struct bridge_softc *, void *);
static int bridge_ioctl_gbparam(struct bridge_softc *, void *);
static int bridge_ioctl_grte(struct bridge_softc *, void *);
static int bridge_ioctl_gifsstp(struct bridge_softc *, void *);
static int bridge_pfil(struct mbuf **, struct ifnet *, struct ifnet *,
int);
static int bridge_ip_checkbasic(struct mbuf **mp);
@ -397,6 +401,15 @@ const struct bridge_control bridge_control_table[] = {
BC_F_COPYIN|BC_F_SUSER },
{ bridge_ioctl_delspan, sizeof(struct ifbreq),
BC_F_COPYIN|BC_F_SUSER },
{ bridge_ioctl_gbparam, sizeof(struct ifbropreq),
BC_F_COPYOUT },
{ bridge_ioctl_grte, sizeof(struct ifbrparam),
BC_F_COPYOUT },
{ bridge_ioctl_gifsstp, sizeof(struct ifbpstpconf),
BC_F_COPYOUT },
};
const int bridge_control_table_size =
sizeof(bridge_control_table) / sizeof(bridge_control_table[0]);
@ -510,6 +523,7 @@ bridge_clone_create(struct if_clone *ifc, int unit, caddr_t params)
sc->sc_brtmax = BRIDGE_RTABLE_MAX;
sc->sc_brttimeout = BRIDGE_RTABLE_TIMEOUT;
getmicrotime(&(sc->sc_stp.bs_last_tc_time));
/* Initialize our routing table. */
bridge_rtable_init(sc);
@ -1425,6 +1439,95 @@ bridge_ioctl_delspan(struct bridge_softc *sc, void *arg)
return (0);
}
static int
bridge_ioctl_gbparam(struct bridge_softc *sc, void *arg)
{
struct ifbropreq *req = arg;
struct bstp_port *root_port;
BRIDGE_LOCK_ASSERT(sc);
req->ifbop_maxage = sc->sc_stp.bs_max_age;
req->ifbop_hellotime = sc->sc_stp.bs_hello_time;
req->ifbop_fwddelay = sc->sc_stp.bs_forward_delay;
root_port = sc->sc_stp.bs_root_port;
if (root_port == NULL)
req->ifbop_root_port = 0;
else
req->ifbop_root_port = root_port->bp_ifp->if_index;
req->ifbop_root_path_cost = sc->sc_stp.bs_root_path_cost;
req->ifbop_designated_root = sc->sc_stp.bs_designated_root;
req->ifbop_last_tc_time.tv_sec = sc->sc_stp.bs_last_tc_time.tv_sec;
req->ifbop_last_tc_time.tv_usec = sc->sc_stp.bs_last_tc_time.tv_usec;
return (0);
}
static int
bridge_ioctl_grte(struct bridge_softc *sc, void *arg)
{
struct ifbrparam *param = arg;
BRIDGE_LOCK_ASSERT(sc);
param->ifbrp_cexceeded = sc->sc_brtexceeded;
return (0);
}
static int
bridge_ioctl_gifsstp(struct bridge_softc *sc, void *arg)
{
struct ifbpstpconf *bifstp = arg;
struct bridge_iflist *bif;
struct ifbpstpreq bpreq;
int count, len, error = 0;
BRIDGE_LOCK_ASSERT(sc);
count = 0;
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
if ((bif->bif_flags & IFBIF_STP) != 0)
count++;
}
if (bifstp->ifbpstp_len == 0) {
bifstp->ifbpstp_len = sizeof(bpreq) * count;
return (0);
}
count = 0;
len = bifstp->ifbpstp_len;
bzero(&bpreq, sizeof(bpreq));
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
if (len < sizeof(bpreq))
break;
if ((bif->bif_flags & IFBIF_STP) == 0)
continue;
bpreq.ifbp_portno = bif->bif_ifp->if_index & 0xff;
bpreq.ifbp_fwd_trans = bif->bif_stp.bp_forward_transitions;
bpreq.ifbp_design_cost = bif->bif_stp.bp_designated_cost;
bpreq.ifbp_design_port = bif->bif_stp.bp_designated_port;
bpreq.ifbp_design_bridge = bif->bif_stp.bp_designated_bridge;
bpreq.ifbp_design_root = bif->bif_stp.bp_designated_root;
error = copyout(&bpreq, bifstp->ifbpstp_req + count,
sizeof(bpreq));
if (error != 0)
break;
count++;
len -= sizeof(bpreq);
}
bifstp->ifbpstp_len = sizeof(bpreq) * count;
return (error);
}
/*
* bridge_ifdetach:
*
@ -2249,8 +2352,10 @@ bridge_rtupdate(struct bridge_softc *sc, const uint8_t *dst,
* update it, otherwise create a new one.
*/
if ((brt = bridge_rtnode_lookup(sc, dst)) == NULL) {
if (sc->sc_brtcnt >= sc->sc_brtmax)
if (sc->sc_brtcnt >= sc->sc_brtmax) {
sc->sc_brtexceeded++;
return (ENOSPC);
}
/*
* Allocate a new bridge forwarding node, and

View File

@ -108,6 +108,10 @@
#define BRDGSIFCOST 22 /* set if path cost (ifbreq) */
#define BRDGADDS 23 /* add bridge span member (ifbreq) */
#define BRDGDELS 24 /* delete bridge span member (ifbreq) */
#define BRDGPARAM 25 /* get bridge STP params (ifbropreq) */
#define BRDGGRTE 26 /* get cache drops (ifbrparam) */
#define BRDGGIFSSTP 27 /* get member STP params list
* (ifbpstpconf) */
/*
* Generic bridge control request.
@ -191,6 +195,45 @@ struct ifbrparam {
#define ifbrp_hellotime ifbrp_ifbrpu.ifbrpu_int8 /* hello time (sec) */
#define ifbrp_fwddelay ifbrp_ifbrpu.ifbrpu_int8 /* fwd time (sec) */
#define ifbrp_maxage ifbrp_ifbrpu.ifbrpu_int8 /* max age (sec) */
#define ifbrp_cexceeded ifbrp_ifbrpu.ifbrpu_int32 /* # of cache dropped
* adresses */
/*
* Bridge current operational parameters structure.
*/
struct ifbropreq {
uint8_t ifbop_maxage;
uint8_t ifbop_hellotime;
uint8_t ifbop_fwddelay;
uint16_t ifbop_root_port;
uint32_t ifbop_root_path_cost;
uint64_t ifbop_designated_root;
struct timeval ifbop_last_tc_time;
};
/*
* Bridge member operational STP params structure.
*/
struct ifbpstpreq {
uint8_t ifbp_portno; /* bp STP port number */
uint32_t ifbp_fwd_trans; /* bp STP fwd transitions */
uint32_t ifbp_design_cost; /* bp STP designated cost */
uint32_t ifbp_design_port; /* bp STP designated port */
uint64_t ifbp_design_bridge; /* bp STP designated bridge */
uint64_t ifbp_design_root; /* bp STP designated root */
};
/*
* Bridge STP ports list structure.
*/
struct ifbpstpconf {
uint32_t ifbpstp_len; /* buffer size */
union {
caddr_t ifbpstpu_buf;
struct ifbpstpreq *ifbpstpu_req;
} ifbpstp_ifbpstpu;
#define ifbpstp_buf ifbpstp_ifbpstpu.ifbpstpu_buf
#define ifbpstp_req ifbpstp_ifbpstpu.ifbpstpu_req
};
#ifdef _KERNEL