diff options
author | thompsa <thompsa@FreeBSD.org> | 2006-07-31 20:24:46 +0000 |
---|---|---|
committer | thompsa <thompsa@FreeBSD.org> | 2006-07-31 20:24:46 +0000 |
commit | 643801c6b91cc768837423ab9d777aa07eb18690 (patch) | |
tree | 3ee13b17b6b37925375b1efba7a58656806c19ff /sys/net | |
parent | 73ebfe88f61c7a436472f5c6b29ba96f06ba7d59 (diff) | |
download | FreeBSD-src-643801c6b91cc768837423ab9d777aa07eb18690.zip FreeBSD-src-643801c6b91cc768837423ab9d777aa07eb18690.tar.gz |
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)
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/bridgestp.c | 10 | ||||
-rw-r--r-- | sys/net/bridgestp.h | 2 | ||||
-rw-r--r-- | sys/net/if_bridge.c | 107 | ||||
-rw-r--r-- | sys/net/if_bridgevar.h | 43 |
4 files changed, 161 insertions, 1 deletions
diff --git a/sys/net/bridgestp.c b/sys/net/bridgestp.c index d57b173..d58cbc0 100644 --- a/sys/net/bridgestp.c +++ b/sys/net/bridgestp.c @@ -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 *, @@ -531,6 +532,12 @@ bstp_set_port_state(struct bstp_port *bp, uint8_t 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) { BSTP_LOCK_ASSERT(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); diff --git a/sys/net/bridgestp.h b/sys/net/bridgestp.h index 61f2317..0905653 100644 --- a/sys/net/bridgestp.h +++ b/sys/net/bridgestp.h @@ -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; }; 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 diff --git a/sys/net/if_bridgevar.h b/sys/net/if_bridgevar.h index 0e07825..35d5537 100644 --- a/sys/net/if_bridgevar.h +++ b/sys/net/if_bridgevar.h @@ -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 |