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