From 643801c6b91cc768837423ab9d777aa07eb18690 Mon Sep 17 00:00:00 2001 From: thompsa Date: Mon, 31 Jul 2006 20:24:46 +0000 Subject: 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) --- sys/net/if_bridge.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 106 insertions(+), 1 deletion(-) (limited to 'sys/net/if_bridge.c') diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index bd61bb2..4e2aa80 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -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 -- cgit v1.1