diff options
author | 2000-11-07 05:38:53 +0000 | |
---|---|---|
committer | 2000-11-07 05:38:53 +0000 | |
commit | caf87018172e03f6cc295ec669c243503ab58ba4 (patch) | |
tree | 85bcb4fed1e755c20ab557633d180af175938539 | |
parent | Add __P(). ok deraadt@ (diff) | |
download | wireguard-openbsd-caf87018172e03f6cc295ec669c243503ab58ba4.tar.xz wireguard-openbsd-caf87018172e03f6cc295ec669c243503ab58ba4.zip |
- Since the actual frame processing takes place from softnet(), splhigh
is not needed (the only other two places that modify the state of the
bridge are bridge_ioctl() and bridge_rtage(), both of which can easily
be wrapped in splsoftnet).
- compute a random hashkey each time the bridge is brought up
-rw-r--r-- | sys/net/if_bridge.c | 109 |
1 files changed, 44 insertions, 65 deletions
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index 0626876c03a..74810198d69 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_bridge.c,v 1.40 2000/11/06 01:40:28 jason Exp $ */ +/* $OpenBSD: if_bridge.c,v 1.41 2000/11/07 05:38:53 jason Exp $ */ /* * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net) @@ -139,6 +139,7 @@ struct bridge_softc { u_int32_t sc_brtmax; /* max # addresses */ u_int32_t sc_brtcnt; /* current # addrs */ u_int32_t sc_brttimeout; /* timeout ticks */ + u_int32_t sc_hashkey; /* hash key */ struct timeout sc_brtimeout; /* timeout state */ LIST_HEAD(, bridge_iflist) sc_iflist; /* interface list */ LIST_HEAD(bridge_rthead, bridge_rtnode) *sc_rts;/* hash table */ @@ -156,8 +157,9 @@ void bridge_stop __P((struct bridge_softc *)); void bridge_init __P((struct bridge_softc *)); int bridge_bifconf __P((struct bridge_softc *, struct ifbifconf *)); +void bridge_timer __P((void *)); int bridge_rtfind __P((struct bridge_softc *, struct ifbaconf *)); -void bridge_rtage __P((void *)); +void bridge_rtage __P((struct bridge_softc *)); void bridge_rttrim __P((struct bridge_softc *)); void bridge_rtdelete __P((struct bridge_softc *, struct ifnet *)); int bridge_rtdaddr __P((struct bridge_softc *, struct ether_addr *)); @@ -166,7 +168,7 @@ struct ifnet * bridge_rtupdate __P((struct bridge_softc *, struct ether_addr *, struct ifnet *ifp, int, u_int8_t)); struct ifnet * bridge_rtlookup __P((struct bridge_softc *, struct ether_addr *)); -u_int32_t bridge_hash __P((struct ether_addr *)); +u_int32_t bridge_hash __P((struct bridge_softc *, struct ether_addr *)); int bridge_blocknonip __P((struct ether_header *, struct mbuf *)); int bridge_addrule __P((struct bridge_iflist *, struct ifbrlreq *, int out)); @@ -203,7 +205,7 @@ bridgeattach(unused) sc->sc_brtmax = BRIDGE_RTABLE_MAX; sc->sc_brttimeout = BRIDGE_RTABLE_TIMEOUT; - timeout_set(&sc->sc_brtimeout, bridge_rtage, sc); + timeout_set(&sc->sc_brtimeout, bridge_timer, sc); LIST_INIT(&sc->sc_iflist); ifp = &sc->sc_if; sprintf(ifp->if_xname, "bridge%d", i); @@ -244,7 +246,7 @@ bridge_ioctl(ifp, cmd, data) int error = 0, s; struct bridge_iflist *p; - s = splimp(); + s = splsoftnet(); switch (cmd) { case SIOCBRDGADD: if ((error = suser(prc->p_ucred, &prc->p_acflag)) != 0) @@ -681,26 +683,23 @@ bridge_init(sc) struct bridge_softc *sc; { struct ifnet *ifp = &sc->sc_if; - int i, s; + int i; if ((ifp->if_flags & IFF_RUNNING) == IFF_RUNNING) return; - s = splhigh(); 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) { - splx(s); + if (sc->sc_rts == NULL) return; - } for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) { LIST_INIT(&sc->sc_rts[i]); } + get_random_bytes(&sc->sc_hashkey, sizeof(sc->sc_hashkey)); } ifp->if_flags |= IFF_RUNNING; - splx(s); if (sc->sc_brttimeout != 0) timeout_add(&sc->sc_brtimeout, sc->sc_brttimeout * hz); @@ -1216,25 +1215,25 @@ bridge_rtupdate(sc, ea, ifp, setflags, flags) { struct bridge_rtnode *p, *q; u_int32_t h; - int s, dir; + int dir; - s = splhigh(); 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++) + for (h = 0; h < BRIDGE_RTABLE_SIZE; h++) { LIST_INIT(&sc->sc_rts[h]); + } + get_random_bytes(&sc->sc_hashkey, sizeof(sc->sc_hashkey)); } else goto done; } - h = bridge_hash(ea); + h = bridge_hash(sc, ea); p = LIST_FIRST(&sc->sc_rts[h]); if (p == LIST_END(&sc->sc_rts[h])) { if (sc->sc_brtcnt >= sc->sc_brtmax) @@ -1322,7 +1321,6 @@ bridge_rtupdate(sc, ea, ifp, setflags, flags) done: ifp = NULL; want: - splx(s); return (ifp); } @@ -1333,28 +1331,20 @@ bridge_rtlookup(sc, ea) { struct bridge_rtnode *p; u_int32_t h; - int s, dir; - - /* - * Lock out everything else - */ - s = splhigh(); + int dir; if (sc->sc_rts == NULL) goto fail; - h = bridge_hash(ea); + h = bridge_hash(sc, ea); LIST_FOREACH(p, &sc->sc_rts[h], brt_next) { dir = memcmp(ea, &p->brt_addr, sizeof(p->brt_addr)); - if (dir == 0) { - splx(s); + if (dir == 0) return (p->brt_if); - } if (dir > 0) goto fail; } fail: - splx(s); return (NULL); } @@ -1378,10 +1368,11 @@ fail: } while(0) u_int32_t -bridge_hash(addr) +bridge_hash(sc, addr) + struct bridge_softc *sc; struct ether_addr *addr; { - u_int32_t a = 0x9e3779b9, b = 0x9e3779b9, c = 0xdeadbeef; + u_int32_t a = 0x9e3779b9, b = 0x9e3779b9, c = sc->sc_hashkey; b += addr->ether_addr_octet[5] << 8; b += addr->ether_addr_octet[4]; @@ -1403,9 +1394,8 @@ bridge_rttrim(sc) struct bridge_softc *sc; { struct bridge_rtnode *n, *p; - int s, i; + int i; - s = splhigh(); if (sc->sc_rts == NULL) goto done; @@ -1418,9 +1408,7 @@ bridge_rttrim(sc) /* * Force an aging cycle, this might trim enough addresses. */ - splx(s); bridge_rtage(sc); - s = splhigh(); if (sc->sc_brtcnt <= sc->sc_brtmax) goto done; @@ -1446,7 +1434,17 @@ done: free(sc->sc_rts, M_DEVBUF); sc->sc_rts = NULL; } +} +void +bridge_timer(vsc) + void *vsc; +{ + struct bridge_softc *sc = vsc; + int s; + + s = splsoftnet(); + bridge_rtage(sc); splx(s); } @@ -1454,18 +1452,14 @@ done: * Perform an aging cycle */ void -bridge_rtage(vsc) - void *vsc; +bridge_rtage(sc) + struct bridge_softc *sc; { - struct bridge_softc *sc = (struct bridge_softc *)vsc; struct bridge_rtnode *n, *p; - int s, i; + int i; - s = splhigh(); - if (sc->sc_rts == NULL) { - splx(s); + if (sc->sc_rts == NULL) return; - } for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) { n = LIST_FIRST(&sc->sc_rts[i]); @@ -1487,7 +1481,6 @@ bridge_rtage(vsc) } } } - splx(s); if (sc->sc_brttimeout != 0) timeout_add(&sc->sc_brtimeout, sc->sc_brttimeout * hz); @@ -1501,12 +1494,11 @@ bridge_rtflush(sc, full) struct bridge_softc *sc; int full; { - int s, i; + int i; struct bridge_rtnode *p, *n; - s = splhigh(); if (sc->sc_rts == NULL) - goto done; + return (0); for (i = 0; i < BRIDGE_RTABLE_SIZE; i++) { n = LIST_FIRST(&sc->sc_rts[i]); @@ -1528,8 +1520,6 @@ bridge_rtflush(sc, full) sc->sc_rts = NULL; } -done: - splx(s); return (0); } @@ -1541,14 +1531,13 @@ bridge_rtdaddr(sc, ea) struct bridge_softc *sc; struct ether_addr *ea; { - int h, s; + int h; struct bridge_rtnode *p; - s = splhigh(); if (sc->sc_rts == NULL) - goto done; + return (ENOENT); - h = bridge_hash(ea); + 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); @@ -1559,13 +1548,10 @@ bridge_rtdaddr(sc, ea) free(sc->sc_rts, M_DEVBUF); sc->sc_rts = NULL; } - splx(s); return (0); } } -done: - splx(s); return (ENOENT); } /* @@ -1576,12 +1562,11 @@ bridge_rtdelete(sc, ifp) struct bridge_softc *sc; struct ifnet *ifp; { - int i, s; + int i; struct bridge_rtnode *n, *p; - s = splhigh(); if (sc->sc_rts == NULL) - goto done; + return; /* * Loop through all of the hash buckets and traverse each @@ -1604,9 +1589,6 @@ bridge_rtdelete(sc, ifp) free(sc->sc_rts, M_DEVBUF); sc->sc_rts = NULL; } - -done: - splx(s); } /* @@ -1617,13 +1599,11 @@ bridge_rtfind(sc, baconf) struct bridge_softc *sc; struct ifbaconf *baconf; { - int i, s, error = 0; + int i, error = 0; u_int32_t cnt = 0; struct bridge_rtnode *n; struct ifbareq bareq; - s = splhigh(); - if (sc->sc_rts == NULL || baconf->ifbac_len == 0) goto done; @@ -1649,7 +1629,6 @@ bridge_rtfind(sc, baconf) } done: baconf->ifbac_len = cnt * sizeof(struct ifbareq); - splx(s); return (error); } |