Initial import from FreeBSD RELENG_4:
[dragonfly.git] / sys / netproto / atm / ipatm / ipatm_input.c
1 /*
2  *
3  * ===================================
4  * HARP  |  Host ATM Research Platform
5  * ===================================
6  *
7  *
8  * This Host ATM Research Platform ("HARP") file (the "Software") is
9  * made available by Network Computing Services, Inc. ("NetworkCS")
10  * "AS IS".  NetworkCS does not provide maintenance, improvements or
11  * support of any kind.
12  *
13  * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
14  * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
15  * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
16  * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
17  * In no event shall NetworkCS be responsible for any damages, including
18  * but not limited to consequential damages, arising from or relating to
19  * any use of the Software or related support.
20  *
21  * Copyright 1994-1998 Network Computing Services, Inc.
22  *
23  * Copies of this Software may be made, however, the above copyright
24  * notice must be reproduced on all copies.
25  *
26  *      @(#) $FreeBSD: src/sys/netatm/ipatm/ipatm_input.c,v 1.4 2000/01/17 20:49:43 mks Exp $
27  *
28  */
29
30 /*
31  * IP Over ATM Support
32  * -------------------
33  *
34  * Process stack and data input
35  *
36  */
37
38 #include <netatm/kern_include.h>
39
40 #include <netatm/ipatm/ipatm_var.h>
41
42 #ifndef lint
43 __RCSID("@(#) $FreeBSD: src/sys/netatm/ipatm/ipatm_input.c,v 1.4 2000/01/17 20:49:43 mks Exp $");
44 #endif
45
46
47 /*
48  * Process VCC Input Data
49  * 
50  * Arguments:
51  *      tok     ipatm connection token (pointer to ipvcc)
52  *      m       pointer to input packet buffer chain
53  *
54  * Returns:
55  *      none
56  *
57  */
58 void
59 ipatm_cpcs_data(tok, m)
60         void            *tok;
61         KBuffer         *m;
62 {
63         struct ipvcc    *ivp = tok;
64
65 #ifdef DIAGNOSTIC
66         if (ipatm_print) {
67                 atm_pdu_print(m, "ipatm_input");
68         }
69 #endif
70
71         /*
72          * Handle input packet
73          */
74         if (ivp->iv_state != IPVCC_ACTIVE) {
75                 KB_FREEALL(m);
76                 ipatm_stat.ias_rcvstate++;
77                 return;
78         }
79
80         /*
81          * IP packet - reset idle timer
82          */
83         ivp->iv_idle = 0;
84
85         /*
86          * Pass packet to IP
87          */
88         (void) ipatm_ipinput(ivp->iv_ipnif, m);
89 }
90
91
92 /*
93  * IP Input Packet Handler
94  * 
95  * All IP packets received from various ATM sources will be sent here
96  * for final queuing to the IP layer.
97  *
98  * Arguments:
99  *      inp     pointer to packet's receiving IP network interface
100  *      m       pointer to packet buffer chain
101  *
102  * Returns:
103  *      0       packet successfully queued to IP layer
104  *      else    error queuing packet, buffer chain freed
105  *
106  */
107 int
108 ipatm_ipinput(inp, m)
109         struct ip_nif   *inp;
110         KBuffer         *m;
111 {
112         int             s;
113 #if     BSD < 199103
114         int             space;
115 #endif
116
117 #ifdef DIAGNOSTIC
118         if (ipatm_print) {
119                 atm_pdu_print(m, "ipatm_ipinput");
120         }
121 #endif
122
123 #if defined(BSD)
124 #if BSD >= 199103
125
126 #ifdef DIAGNOSTIC
127         if (!KB_ISPKT(m)) {
128                 panic("ipatm_ipinput: no packet header");
129         }
130         {
131                 int     cnt = 0;
132                 KBuffer *m0 = m;
133
134                 while (m0) {
135                         cnt += KB_LEN(m0);
136                         m0 = KB_NEXT(m0);
137                 }
138                 if (m->m_pkthdr.len != cnt) {
139                         panic("ipatm_ipinput: packet length incorrect");
140                 }
141         }
142 #endif
143         /*
144          * Save the input ifnet pointer in the packet header
145          */
146         m->m_pkthdr.rcvif = (struct ifnet *)inp->inf_nif;
147
148 #else   /* ! BSD >= 199103 */
149         /*
150          * Stick ifnet pointer onto front of packet - hopefully 
151          * there'll be room in the first buffer.
152          */
153         KB_HEADROOM(m, space);
154         if (space < sizeof(struct ifnet *)) {
155                 KBuffer         *n;
156
157                 /*
158                  * We have to allocate another buffer and tack it
159                  * onto the front of the packet
160                  */
161                 KB_ALLOCPKT(n, sizeof(struct ifnet *),
162                         KB_F_NOWAIT, KB_T_HEADER);
163                 if (n == 0) {
164                         KB_FREEALL(m);
165                         ipatm_stat.ias_rcvnobuf++;
166                         return (1);
167                 }
168                 KB_LEN(n) = sizeof(struct ifnet *);
169                 KB_LINKHEAD(n, m);
170                 m = n;
171         } else {
172                 /*
173                  * Header fits, just adjust buffer controls
174                  */
175                 KB_HEADADJ(m, sizeof(struct ifnet *));
176         }
177         {
178                 struct ifnet    **p;
179
180                 KB_DATASTART(m, p, struct ifnet **);
181                 *p = (struct ifnet *)inp->inf_nif;
182         }
183 #endif  /* ! BSD >= 199103 */
184
185         /*
186          * Finally, hand packet off to IP.
187          *
188          * NB: Since we're already in the softint kernel state, we
189          * just call IP directly to avoid the extra unnecessary 
190          * kernel scheduling.
191          */
192         s = splimp();
193         if (IF_QFULL(&ipintrq)) {
194                 IF_DROP(&ipintrq);
195                 (void) splx(s);
196                 KB_FREEALL(m);
197                 return (1);
198         }
199
200         IF_ENQUEUE(&ipintrq, m);
201         (void) splx(s);
202 #if     BSD < 199506
203         ipintr();
204 #else
205         schednetisr ( NETISR_IP );
206 #endif  /* BSD >= 199506 */
207 #endif  /* defined(BSD) */
208
209         return (0);
210 }
211