123168Smckusick /*
234853Sbostic * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
333453Skarels * All rights reserved.
423168Smckusick *
544468Sbostic * %sccs.include.redist.c%
633453Skarels *
7*56528Sbostic * @(#)if_imphost.c 7.11 (Berkeley) 10/11/92
823168Smckusick */
95712Ssam
105712Ssam #include "imp.h"
115712Ssam #if NIMP > 0
125712Ssam /*
135712Ssam * Host table manipulation routines.
145712Ssam * Only needed when shipping stuff through an IMP.
1511231Ssam *
1611231Ssam * Everything in here is called at splimp from
1711231Ssam * from the IMP protocol code (if_imp.c), or
1811231Ssam * interlocks with the code at splimp.
195712Ssam */
20*56528Sbostic #include <sys/param.h>
21*56528Sbostic #include <sys/mbuf.h>
22*56528Sbostic #include <sys/socket.h>
23*56528Sbostic #include <sys/syslog.h>
2411231Ssam
25*56528Sbostic #include <net/if.h>
2633427Skarels
27*56528Sbostic #include <netinet/in.h>
28*56528Sbostic #include <netinet/in_systm.h>
2911231Ssam
30*56528Sbostic #include <netimp/if_imp.h>
31*56528Sbostic #include <netimp/if_imphost.h>
325712Ssam
3333427Skarels extern struct imp_softc imp_softc[];
345712Ssam
355712Ssam /*
365712Ssam * Given an internet address
375712Ssam * return a host structure (if it exists).
385712Ssam */
395712Ssam struct host *
hostlookup(imp,host,unit)4033427Skarels hostlookup(imp, host, unit)
4133427Skarels int imp, host, unit;
425712Ssam {
435712Ssam register struct host *hp;
445712Ssam register struct mbuf *m;
4533427Skarels register int hash = HOSTHASH(imp, host);
465712Ssam
4733453Skarels for (m = imp_softc[unit].imp_hosts; m; m = m->m_next) {
485712Ssam hp = &mtod(m, struct hmbuf *)->hm_hosts[hash];
4933453Skarels if (hp->h_imp == imp && hp->h_host == host) {
5034209Skarels if ((hp->h_flags & HF_INUSE) == 0)
5133453Skarels mtod(dtom(hp), struct hmbuf *)->hm_count++;
526589Ssam hp->h_flags |= HF_INUSE;
5311231Ssam return (hp);
546589Ssam }
555712Ssam }
5611231Ssam return ((struct host *)0);
575712Ssam }
585712Ssam
595712Ssam /*
605712Ssam * Enter a reference to this host's internet
615712Ssam * address. If no host structure exists, create
625712Ssam * one and hook it into the host database.
635712Ssam */
645712Ssam struct host *
hostenter(imp,host,unit)6533427Skarels hostenter(imp, host, unit)
6633427Skarels int imp, host, unit;
675712Ssam {
685860Sroot register struct mbuf *m, **mprev;
695860Sroot register struct host *hp, *hp0 = 0;
7033427Skarels register int hash = HOSTHASH(imp, host);
715712Ssam
7233453Skarels mprev = &imp_softc[unit].imp_hosts;
735860Sroot while (m = *mprev) {
746209Swnj mprev = &m->m_next;
755712Ssam hp = &mtod(m, struct hmbuf *)->hm_hosts[hash];
7633453Skarels if (hp->h_imp == imp && hp->h_host == host) {
7734209Skarels if ((hp->h_flags & HF_INUSE) == 0)
7833453Skarels mtod(dtom(hp), struct hmbuf *)->hm_count++;
7933427Skarels goto foundhost;
8033453Skarels }
816589Ssam if ((hp->h_flags & HF_INUSE) == 0) {
825860Sroot if (hp0 == 0)
835860Sroot hp0 = hp;
845860Sroot continue;
855860Sroot }
865712Ssam }
875712Ssam
885712Ssam /*
895712Ssam * No current host structure, make one.
905712Ssam * If our search ran off the end of the
915712Ssam * chain of mbuf's, allocate another.
925712Ssam */
935860Sroot if (hp0 == 0) {
949646Ssam m = m_getclr(M_DONTWAIT, MT_HTABLE);
9511231Ssam if (m == NULL)
9611231Ssam return ((struct host *)0);
975860Sroot *mprev = m;
985860Sroot hp0 = &mtod(m, struct hmbuf *)->hm_hosts[hash];
995712Ssam }
1005860Sroot hp = hp0;
10134209Skarels mtod(dtom(hp), struct hmbuf *)->hm_count++;
10233427Skarels hp->h_imp = imp;
10333427Skarels hp->h_host = host;
1046589Ssam hp->h_timer = 0;
1056725Ssam hp->h_flags = 0;
1065712Ssam
1075712Ssam foundhost:
1086589Ssam hp->h_flags |= HF_INUSE;
1095712Ssam return (hp);
1105712Ssam }
1115712Ssam
1125712Ssam /*
11333427Skarels * Reset a given imp unit's host entries.
11434693Skarels * Must be called at splimp.
1155712Ssam */
hostreset(unit)11633427Skarels hostreset(unit)
11733427Skarels int unit;
1185712Ssam {
1195712Ssam register struct mbuf *m;
1205712Ssam register struct host *hp, *lp;
1215860Sroot struct hmbuf *hm;
1225712Ssam
12333453Skarels for (m = imp_softc[unit].imp_hosts; m; m = m->m_next) {
1245860Sroot hm = mtod(m, struct hmbuf *);
1255860Sroot hp = hm->hm_hosts;
1265712Ssam lp = hp + HPMBUF;
1276589Ssam while (hm->hm_count > 0 && hp < lp) {
12833453Skarels hostrelease(hp);
1295712Ssam hp++;
1305712Ssam }
1315712Ssam }
13233453Skarels hostcompress(unit);
1335712Ssam }
1345712Ssam
1355712Ssam /*
1365712Ssam * Remove a host structure and release
1375712Ssam * any resources it's accumulated.
1385712Ssam */
hostrelease(hp)1395860Sroot hostrelease(hp)
1405712Ssam register struct host *hp;
1415712Ssam {
1425712Ssam
14334209Skarels if (hp->h_q)
14434209Skarels hostflush(hp);
14534209Skarels hp->h_rfnm = 0;
14634209Skarels if (hp->h_flags & HF_INUSE)
14734209Skarels --mtod(dtom(hp), struct hmbuf *)->hm_count;
14833453Skarels hp->h_flags = 0;
14933453Skarels }
15033453Skarels
15133453Skarels /*
15233453Skarels * Flush the message queue for a host.
15333453Skarels */
hostflush(hp)15433453Skarels hostflush(hp)
15533453Skarels register struct host *hp;
15633453Skarels {
15734459Skarels register struct mbuf *m;
15833453Skarels
1595712Ssam /*
1605712Ssam * Discard any packets left on the waiting q
1615712Ssam */
1625771Swnj if (m = hp->h_q) {
1635868Sroot register struct mbuf *n;
1645868Sroot
1655868Sroot do {
1665868Sroot n = m->m_act;
1675868Sroot m_freem(m);
1685868Sroot m = n;
1695868Sroot } while (m != hp->h_q);
1705771Swnj hp->h_q = 0;
17133453Skarels hp->h_qcnt = 0;
1725712Ssam }
1735712Ssam }
1745924Sroot
17534693Skarels /*
17634693Skarels * Release mbufs in host table that contain no entries
17734693Skarels * currently in use. Must be called at splimp.
17834693Skarels */
hostcompress(unit)17933453Skarels hostcompress(unit)
18033453Skarels int unit;
1815924Sroot {
18233427Skarels register struct mbuf *m, **mprev;
18334693Skarels struct imp_softc *sc = &imp_softc[unit];
1845924Sroot
18534693Skarels mprev = &sc->imp_hosts;
18634693Skarels sc->imp_hostq = 0;
18733427Skarels while (m = *mprev) {
18833427Skarels if (mtod(m, struct hmbuf *)->hm_count == 0)
18933427Skarels *mprev = m_free(m);
19033427Skarels else
19133427Skarels mprev = &m->m_next;
19233427Skarels }
1935924Sroot }
1946589Ssam
1956589Ssam /*
1966589Ssam * Host data base timer routine.
1976589Ssam * Decrement timers on structures which are
1986589Ssam * waiting to be deallocated. On expiration
1996589Ssam * release resources, possibly deallocating
2006589Ssam * mbuf associated with structure.
2016589Ssam */
hostslowtimo()2026589Ssam hostslowtimo()
2036589Ssam {
2046589Ssam register struct mbuf *m;
2056589Ssam register struct host *hp, *lp;
20633454Skarels struct imp_softc *sc;
2076589Ssam struct hmbuf *hm;
20833453Skarels int s = splimp(), unit, any;
2096589Ssam
21033453Skarels for (unit = 0; unit < NIMP; unit++) {
21133453Skarels any = 0;
21233454Skarels sc = &imp_softc[unit];
21333454Skarels for (m = sc->imp_hosts; m; m = m->m_next) {
2146589Ssam hm = mtod(m, struct hmbuf *);
2156589Ssam hp = hm->hm_hosts;
2166589Ssam lp = hp + HPMBUF;
2176779Ssam for (; hm->hm_count > 0 && hp < lp; hp++) {
21833427Skarels if (hp->h_timer && --hp->h_timer == 0) {
21933427Skarels if (hp->h_rfnm) {
22034260Skarels log(LOG_INFO, /* XXX */
22133453Skarels "imp%d: host %d/imp %d, lost rfnm\n",
22233453Skarels unit, hp->h_host, ntohs(hp->h_imp));
22334209Skarels sc->imp_lostrfnm++;
22434209Skarels imprestarthost(sc, hp);
22534209Skarels } else {
22633453Skarels any = 1;
22733453Skarels hostrelease(hp);
22833454Skarels if (sc->imp_hostq == m)
22933454Skarels sc->imp_hostq = 0;
23033453Skarels }
23133427Skarels }
2326589Ssam }
23333453Skarels }
23434209Skarels if (any)
23533453Skarels hostcompress(unit);
2366589Ssam }
23711241Ssam splx(s);
2386589Ssam }
23913081Ssam #endif
240