-/* if_imphost.c 4.4 82/02/16 */
+/*
+ * Copyright (c) 1982 Regents of the University of California.
+ * All rights reserved. The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ *
+ * @(#)if_imphost.c 6.7 (Berkeley) %G%
+ */
#include "imp.h"
#if NIMP > 0
/*
* Host table manipulation routines.
* Only needed when shipping stuff through an IMP.
+ *
+ * Everything in here is called at splimp from
+ * from the IMP protocol code (if_imp.c), or
+ * interlocks with the code at splimp.
*/
+#include "param.h"
+#include "mbuf.h"
+#include "syslog.h"
+
+#include "../netinet/in.h"
+#include "../netinet/in_systm.h"
-#include "../h/param.h"
-#include "../h/mbuf.h"
-#include "../net/in.h"
-#include "../net/in_systm.h"
-#include "../net/if_imp.h"
-#include "../net/if_imphost.h"
+#include "if_imp.h"
+#include "if_imphost.h"
/*
* Head of host table hash chains.
register struct mbuf *m;
register int hash = HOSTHASH(addr);
-COUNT(HOSTLOOKUP);
for (m = hosts; m; m = m->m_next) {
hp = &mtod(m, struct hmbuf *)->hm_hosts[hash];
- if (hp->h_refcnt == 0)
- continue;
- if (hp->h_addr.s_addr == addr.s_addr)
+ if (hp->h_addr.s_addr == addr.s_addr) {
+ hp->h_flags |= HF_INUSE;
return (hp);
+ }
}
- return (0);
+ return ((struct host *)0);
}
/*
register struct host *hp, *hp0 = 0;
register int hash = HOSTHASH(addr);
-COUNT(HOSTENTER);
mprev = &hosts;
while (m = *mprev) {
+ mprev = &m->m_next;
hp = &mtod(m, struct hmbuf *)->hm_hosts[hash];
- if (hp->h_refcnt == 0) {
+ if ((hp->h_flags & HF_INUSE) == 0) {
+ if (hp->h_addr.s_addr == addr.s_addr)
+ goto foundhost;
if (hp0 == 0)
hp0 = hp;
continue;
}
if (hp->h_addr.s_addr == addr.s_addr)
goto foundhost;
- mprev = &m->m_next;
}
/*
* chain of mbuf's, allocate another.
*/
if (hp0 == 0) {
- m = m_getclr(M_DONTWAIT);
- if (m == 0)
- return (0);
+ m = m_getclr(M_DONTWAIT, MT_HTABLE);
+ if (m == NULL)
+ return ((struct host *)0);
*mprev = m;
- m->m_off = MMINOFF;
hp0 = &mtod(m, struct hmbuf *)->hm_hosts[hash];
}
mtod(dtom(hp0), struct hmbuf *)->hm_count++;
hp = hp0;
hp->h_addr = addr;
- hp->h_status = HOSTS_UP;
+ hp->h_timer = 0;
+ hp->h_flags = 0;
foundhost:
- hp->h_refcnt++; /* know new structures have 0 val */
+ hp->h_flags |= HF_INUSE;
return (hp);
}
/*
- * Free a reference to a host. If this causes the
- * host structure to be released do so.
+ * Mark a host structure free and set it's
+ * timer going.
*/
hostfree(hp)
register struct host *hp;
{
- register struct mbuf *m;
-COUNT(HOSTFREE);
- if (--hp->h_refcnt)
- return;
- hostrelease(hp);
+ hp->h_flags &= ~HF_INUSE;
+ hp->h_timer = HOSTTIMER;
+ hp->h_rfnm = 0;
}
/*
* Reset a given network's host entries.
- * This involves clearing all packet queue's
- * and releasing host structures.
*/
hostreset(net)
- int net;
+ u_long net;
{
register struct mbuf *m;
register struct host *hp, *lp;
struct hmbuf *hm;
- int x;
+ struct mbuf *mnext;
-COUNT(HOSTRESET);
- x = splimp();
- for (m = hosts; m; m = m->m_next) {
+ for (m = hosts; m; m = mnext) {
+ mnext = m->m_next;
hm = mtod(m, struct hmbuf *);
hp = hm->hm_hosts;
lp = hp + HPMBUF;
- while (hm->hm_count != 0 && hp < lp) {
- if (hp->h_addr.s_net == net)
- hostrelease(mtod(m, struct hmbuf *), hp);
+ while (hm->hm_count > 0 && hp < lp) {
+ if (in_netof(hp->h_addr) == net) {
+ hp->h_flags &= ~HF_INUSE;
+ hostrelease(hp);
+ }
hp++;
}
}
- splx(x);
}
/*
{
register struct mbuf *m, **mprev, *mh = dtom(hp);
-COUNT(HOSTRELEASE);
/*
* Discard any packets left on the waiting q
*/
} while (m != hp->h_q);
hp->h_q = 0;
}
+ hp->h_flags = 0;
+ hp->h_rfnm = 0;
if (--mtod(mh, struct hmbuf *)->hm_count)
return;
mprev = &hosts;
while ((m = *mprev) != mh)
mprev = &m->m_next;
- *mprev = mh->m_next;
- (void) m_free(mh);
+ *mprev = m_free(mh);
+}
+
+/*
+ * Remove a packet from the holding q.
+ * The RFNM counter is also bumped.
+ */
+struct mbuf *
+hostdeque(hp)
+ register struct host *hp;
+{
+ register struct mbuf *m;
+
+ hp->h_rfnm--;
+ HOST_DEQUE(hp, m);
+ if (m)
+ return (m);
+ if (hp->h_rfnm == 0)
+ hostfree(hp);
+ return (0);
+}
+
+/*
+ * Host data base timer routine.
+ * Decrement timers on structures which are
+ * waiting to be deallocated. On expiration
+ * release resources, possibly deallocating
+ * mbuf associated with structure.
+ */
+hostslowtimo()
+{
+ register struct mbuf *m;
+ register struct host *hp, *lp;
+ struct hmbuf *hm;
+ struct mbuf *mnext;
+ int s = splimp();
+
+ for (m = hosts; m; m = mnext) {
+ mnext = m->m_next;
+ hm = mtod(m, struct hmbuf *);
+ hp = hm->hm_hosts;
+ lp = hp + HPMBUF;
+ for (; hm->hm_count > 0 && hp < lp; hp++) {
+ if (hp->h_timer && --hp->h_timer == 0) {
+ if (hp->h_rfnm)
+ log(LOG_WARNING,
+ "imp?: host %x, lost %d rfnms\n",
+ ntohl(hp->h_addr.s_addr), hp->h_rfnm);
+ hostrelease(hp);
+ }
+ }
+ }
+ splx(s);
}
+#endif