summaryrefslogtreecommitdiffstats
path: root/sys/net/if_bridge.c
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/if_bridge.c
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/if_bridge.c')
-rw-r--r--sys/net/if_bridge.c107
1 files changed, 106 insertions, 1 deletions
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
OpenPOWER on IntegriCloud