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