1 /*
2  * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  *	@(#)if_imphost.h	7.7 (Berkeley) 06/28/90
8  */
9 
10 /*
11  * Host structure used with IMP's.
12  * Used to hold outgoing packets which
13  * would exceed allowed RFNM count.
14  *
15  * These structures are packed into
16  * mbuf's and kept as small as possible.
17  */
18 struct host {
19 	struct	mbuf *h_q;		/* holding queue */
20 	u_short	h_timer;		/* used to stay off deletion */
21 	u_short	h_imp;			/* host's imp number */
22 	u_char	h_host;			/* host's number on imp */
23 	u_char	h_qcnt;          	/* size of holding q */
24 	u_char	h_rfnm;			/* # outstanding rfnm's */
25 	u_char	h_flags;		/* see below */
26 };
27 
28 /*
29  * A host structure is kept around (even when there are no
30  * references to it) for a spell to avoid constant reallocation
31  * and also to reflect IMP status back to sites which aren't
32  * directly connected to the IMP.  When structures are marked
33  * idle, a timer is started; when the timer expires the structure
34  * is deallocated.  A structure may be reused before the timer expires.
35  * A structure holds a reference on the containing mbuf when it is marked
36  * HF_INUSE.
37  */
38 #define	HF_INUSE	0x1
39 #define	HF_DEAD		(1<<IMPTYPE_HOSTDEAD)
40 #define	HF_UNREACH	(1<<IMPTYPE_HOSTUNREACH)
41 
42 #define	HOSTTIMER	128		/* keep structure around awhile */
43 
44 /*
45  * Mark a host structure free; used if host entry returned by hostlookup
46  * isn't needed.  h_rfnm must be zero.
47  */
48 #define	hostfree(hp) { \
49 	if ((hp)->h_timer == 0 && (hp)->h_qcnt == 0 && \
50 	    (hp)->h_flags & HF_INUSE) \
51 		hostrelease(hp); \
52 }
53 
54 /*
55  * Release a host entry when last rfnm is received.
56  */
57 #define	hostidle(hp)	{ (hp)->h_timer = HOSTTIMER; }
58 
59 /*
60  * Host structures, as seen inside an mbuf.
61  * Hashing on the host and imp is used to
62  * select an index into the first mbuf.  Collisions
63  * are then resolved by searching successive
64  * mbuf's at the same index.  Reclamation is done
65  * automatically at the time a structure is freed.
66  */
67 #define	HPMBUF	((MLEN - sizeof(int)) / sizeof(struct host))
68 /* don't need to swab as long as HPMBUF is odd */
69 #if defined(notdef) && BYTE_ORDER == BIG_ENDIAN
70 #define	HOSTHASH(imp, host)	((unsigned)(ntohs(imp)+(host)) % HPMBUF)
71 #else
72 #define	HOSTHASH(imp, host)	((unsigned)((imp)+(host)) % HPMBUF)
73 #endif
74 
75 /*
76  * In-line expansions for queuing operations on
77  * host message holding queue.  Queue is maintained
78  * as circular list with the head pointing to the
79  * last message in the queue.
80  */
81 #define	HOST_ENQUE(hp, m) { \
82 	register struct mbuf *n; \
83 	(hp)->h_qcnt++; \
84 	if ((n = (hp)->h_q) == 0) \
85 		(hp)->h_q = (m)->m_act = (m); \
86 	else { \
87 		(m)->m_act = n->m_act; \
88 		(hp)->h_q = n->m_act = (m); \
89 	} \
90 }
91 #define	HOST_DEQUE(hp, m) { \
92 	if ((m) = (hp)->h_q) { \
93 		if ((m)->m_act == (m)) \
94 			(hp)->h_q = 0; \
95 		else { \
96 			(m) = (m)->m_act; \
97 			(hp)->h_q->m_act = (m)->m_act; \
98 		} \
99 		(hp)->h_qcnt--; \
100 		(m)->m_act = 0; \
101 	} \
102 }
103 
104 struct hmbuf {
105 	int	hm_count;		/* # of struct's in use */
106 	struct	host hm_hosts[HPMBUF];	/* data structures proper */
107 };
108 
109 #ifdef KERNEL
110 struct host *hostlookup();
111 struct host *hostenter();
112 #endif
113