summaryrefslogtreecommitdiffstats
path: root/sys/net
diff options
context:
space:
mode:
authorthompsa <thompsa@FreeBSD.org>2006-07-31 20:24:46 +0000
committerthompsa <thompsa@FreeBSD.org>2006-07-31 20:24:46 +0000
commit643801c6b91cc768837423ab9d777aa07eb18690 (patch)
tree3ee13b17b6b37925375b1efba7a58656806c19ff /sys/net
parent73ebfe88f61c7a436472f5c6b29ba96f06ba7d59 (diff)
downloadFreeBSD-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.c10
-rw-r--r--sys/net/bridgestp.h2
-rw-r--r--sys/net/if_bridge.c107
-rw-r--r--sys/net/if_bridgevar.h43
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
OpenPOWER on IntegriCloud