summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCamiel Dobbelaar <camield@cvs.openbsd.org>2004-12-23 09:32:56 +0000
committerCamiel Dobbelaar <camield@cvs.openbsd.org>2004-12-23 09:32:56 +0000
commit2896717df4d4b76a94048648d000937c3e6450aa (patch)
tree21b31025750f9204336ac8ccdde5f6d9163a4623
parent365dc55cb3a4182fbea73f1848be769c5eeb4066 (diff)
Simplify hashtable (de)allocation by moving it into the clone functions.
ok mickey@ henning@, "looks good" markus@ jason@
-rw-r--r--sys/net/if_bridge.c90
-rw-r--r--sys/net/if_bridge.h9
2 files changed, 16 insertions, 83 deletions
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 14c9e41766e..8f2d24d901d 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bridge.c,v 1.140 2004/12/19 03:25:36 mcbride Exp $ */
+/* $OpenBSD: if_bridge.c,v 1.141 2004/12/23 09:32:55 camield Exp $ */
/*
* Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
@@ -97,11 +97,6 @@
#include <net/if_bridge.h>
-#ifndef BRIDGE_RTABLE_SIZE
-#define BRIDGE_RTABLE_SIZE 1024
-#endif
-#define BRIDGE_RTABLE_MASK (BRIDGE_RTABLE_SIZE - 1)
-
/*
* Maximum number of addresses to cache
*/
@@ -198,7 +193,7 @@ bridge_clone_create(struct if_clone *ifc, int unit)
{
struct bridge_softc *sc;
struct ifnet *ifp;
- int s;
+ int i, s;
sc = malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT);
if (!sc)
@@ -215,6 +210,9 @@ bridge_clone_create(struct if_clone *ifc, int unit)
timeout_set(&sc->sc_brtimeout, bridge_timer, sc);
LIST_INIT(&sc->sc_iflist);
LIST_INIT(&sc->sc_spanlist);
+ for (i = 0; i < BRIDGE_RTABLE_SIZE; i++)
+ LIST_INIT(&sc->sc_rts[i]);
+ sc->sc_hashkey = arc4random();
ifp = &sc->sc_if;
snprintf(ifp->if_xname, sizeof ifp->if_xname, "%s%d", ifc->ifc_name,
unit);
@@ -247,11 +245,11 @@ bridge_clone_destroy(struct ifnet *ifp)
int s;
bridge_stop(sc);
+ bridge_rtflush(sc, IFBF_FLUSHALL);
while ((bif = LIST_FIRST(&sc->sc_iflist)) != NULL) {
/* XXX shared with ioctl and detach */
/* XXX promisc disable? */
LIST_REMOVE(bif, next);
- bridge_rtdelete(sc, bif->ifp, 0);
bridge_flushrule(bif);
bif->ifp->if_bridge = NULL;
free(bif, M_DEVBUF);
@@ -866,22 +864,10 @@ void
bridge_init(struct bridge_softc *sc)
{
struct ifnet *ifp = &sc->sc_if;
- int i;
if ((ifp->if_flags & IFF_RUNNING) == IFF_RUNNING)
return;
- if (sc->sc_rts == NULL) {
- sc->sc_rts = (struct bridge_rthead *)malloc(
- BRIDGE_RTABLE_SIZE * (sizeof(struct bridge_rthead)),
- M_DEVBUF, M_NOWAIT);
- if (sc->sc_rts == NULL)
- return;
- for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) {
- LIST_INIT(&sc->sc_rts[i]);
- }
- sc->sc_hashkey = arc4random();
- }
ifp->if_flags |= IFF_RUNNING;
bstp_initialization(sc);
@@ -1604,22 +1590,6 @@ bridge_rtupdate(struct bridge_softc *sc, struct ether_addr *ea,
u_int32_t h;
int dir;
- if (sc->sc_rts == NULL) {
- if (setflags && flags == IFBAF_STATIC) {
- sc->sc_rts = (struct bridge_rthead *)malloc(
- BRIDGE_RTABLE_SIZE *
- (sizeof(struct bridge_rthead)),M_DEVBUF,M_NOWAIT);
- if (sc->sc_rts == NULL)
- goto done;
-
- for (h = 0; h < BRIDGE_RTABLE_SIZE; h++) {
- LIST_INIT(&sc->sc_rts[h]);
- }
- sc->sc_hashkey = arc4random();
- } else
- goto done;
- }
-
h = bridge_hash(sc, ea);
p = LIST_FIRST(&sc->sc_rts[h]);
if (p == LIST_END(&sc->sc_rts[h])) {
@@ -1718,9 +1688,6 @@ bridge_rtlookup(struct bridge_softc *sc, struct ether_addr *ea)
u_int32_t h;
int dir;
- if (sc->sc_rts == NULL)
- goto fail;
-
h = bridge_hash(sc, ea);
LIST_FOREACH(p, &sc->sc_rts[h], brt_next) {
dir = memcmp(ea, &p->brt_addr, sizeof(p->brt_addr));
@@ -1778,14 +1745,11 @@ bridge_rttrim(struct bridge_softc *sc)
struct bridge_rtnode *n, *p;
int i;
- if (sc->sc_rts == NULL)
- goto done;
-
/*
* Make sure we have to trim the address table
*/
if (sc->sc_brtcnt <= sc->sc_brtmax)
- goto done;
+ return;
/*
* Force an aging cycle, this might trim enough addresses.
@@ -1793,7 +1757,7 @@ bridge_rttrim(struct bridge_softc *sc)
bridge_rtage(sc);
if (sc->sc_brtcnt <= sc->sc_brtmax)
- goto done;
+ return;
for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) {
n = LIST_FIRST(&sc->sc_rts[i]);
@@ -1805,17 +1769,10 @@ bridge_rttrim(struct bridge_softc *sc)
free(n, M_DEVBUF);
n = p;
if (sc->sc_brtcnt <= sc->sc_brtmax)
- goto done;
+ return;
}
}
}
-
-done:
- if (sc->sc_rts != NULL && sc->sc_brtcnt == 0 &&
- (sc->sc_if.if_flags & IFF_UP) == 0) {
- free(sc->sc_rts, M_DEVBUF);
- sc->sc_rts = NULL;
- }
}
void
@@ -1838,9 +1795,6 @@ bridge_rtage(struct bridge_softc *sc)
struct bridge_rtnode *n, *p;
int i;
- if (sc->sc_rts == NULL)
- return;
-
for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) {
n = LIST_FIRST(&sc->sc_rts[i]);
while (n != LIST_END(&sc->sc_rts[i])) {
@@ -1875,9 +1829,6 @@ bridge_rtflush(struct bridge_softc *sc, int full)
int i;
struct bridge_rtnode *p, *n;
- if (sc->sc_rts == NULL)
- return (0);
-
for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) {
n = LIST_FIRST(&sc->sc_rts[i]);
while (n != LIST_END(&sc->sc_rts[i])) {
@@ -1893,11 +1844,6 @@ bridge_rtflush(struct bridge_softc *sc, int full)
}
}
- if (sc->sc_brtcnt == 0 && (sc->sc_if.if_flags & IFF_UP) == 0) {
- free(sc->sc_rts, M_DEVBUF);
- sc->sc_rts = NULL;
- }
-
return (0);
}
@@ -1910,20 +1856,12 @@ bridge_rtdaddr(struct bridge_softc *sc, struct ether_addr *ea)
int h;
struct bridge_rtnode *p;
- if (sc->sc_rts == NULL)
- return (ENOENT);
-
h = bridge_hash(sc, ea);
LIST_FOREACH(p, &sc->sc_rts[h], brt_next) {
if (bcmp(ea, &p->brt_addr, sizeof(p->brt_addr)) == 0) {
LIST_REMOVE(p, brt_next);
sc->sc_brtcnt--;
free(p, M_DEVBUF);
- if (sc->sc_brtcnt == 0 &&
- (sc->sc_if.if_flags & IFF_UP) == 0) {
- free(sc->sc_rts, M_DEVBUF);
- sc->sc_rts = NULL;
- }
return (0);
}
}
@@ -1939,9 +1877,6 @@ bridge_rtdelete(struct bridge_softc *sc, struct ifnet *ifp, int dynonly)
int i;
struct bridge_rtnode *n, *p;
- if (sc->sc_rts == NULL)
- return;
-
/*
* Loop through all of the hash buckets and traverse each
* chain looking for routes to this interface.
@@ -1967,10 +1902,6 @@ bridge_rtdelete(struct bridge_softc *sc, struct ifnet *ifp, int dynonly)
n = p;
}
}
- if (sc->sc_brtcnt == 0 && (sc->sc_if.if_flags & IFF_UP) == 0) {
- free(sc->sc_rts, M_DEVBUF);
- sc->sc_rts = NULL;
- }
}
/*
@@ -1984,9 +1915,6 @@ bridge_rtfind(struct bridge_softc *sc, struct ifbaconf *baconf)
struct bridge_rtnode *n;
struct ifbareq bareq;
- if (sc->sc_rts == NULL)
- goto done;
-
if (baconf->ifbac_len == 0)
onlycnt = 1;
diff --git a/sys/net/if_bridge.h b/sys/net/if_bridge.h
index 1bbde37f079..686d8ef60bf 100644
--- a/sys/net/if_bridge.h
+++ b/sys/net/if_bridge.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bridge.h,v 1.26 2003/12/03 14:55:58 markus Exp $ */
+/* $OpenBSD: if_bridge.h,v 1.27 2004/12/23 09:32:55 camield Exp $ */
/*
* Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
@@ -230,6 +230,11 @@ struct bridge_rtnode {
struct ether_addr brt_addr; /* dst addr */
};
+#ifndef BRIDGE_RTABLE_SIZE
+#define BRIDGE_RTABLE_SIZE 1024
+#endif
+#define BRIDGE_RTABLE_MASK (BRIDGE_RTABLE_SIZE - 1)
+
/*
* Software state for each bridge
*/
@@ -261,7 +266,7 @@ struct bridge_softc {
struct timeout sc_brtimeout; /* timeout state */
struct timeout sc_bstptimeout; /* stp timeout */
LIST_HEAD(, bridge_iflist) sc_iflist; /* interface list */
- LIST_HEAD(bridge_rthead, bridge_rtnode) *sc_rts;/* hash table */
+ LIST_HEAD(, bridge_rtnode) sc_rts[BRIDGE_RTABLE_SIZE]; /* hash table */
LIST_HEAD(, bridge_iflist) sc_spanlist; /* span ports */
};