kernel tree reorganization stage 1: Major cvs repository work (not logged as
[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  *      @(#) $DragonFly: src/sys/netproto/atm/ipatm/ipatm_input.c,v 1.4 2003/08/07 21:54:33 dillon Exp $
28  */
29
30 /*
31  * IP Over ATM Support
32  * -------------------
33  *
34  * Process stack and data input
35  *
36  */
37
38 #include <netproto/atm/kern_include.h>
39
40 #include "ipatm_var.h"
41
42 /*
43  * Process VCC Input Data
44  * 
45  * Arguments:
46  *      tok     ipatm connection token (pointer to ipvcc)
47  *      m       pointer to input packet buffer chain
48  *
49  * Returns:
50  *      none
51  *
52  */
53 void
54 ipatm_cpcs_data(tok, m)
55         void            *tok;
56         KBuffer         *m;
57 {
58         struct ipvcc    *ivp = tok;
59
60 #ifdef DIAGNOSTIC
61         if (ipatm_print) {
62                 atm_pdu_print(m, "ipatm_input");
63         }
64 #endif
65
66         /*
67          * Handle input packet
68          */
69         if (ivp->iv_state != IPVCC_ACTIVE) {
70                 KB_FREEALL(m);
71                 ipatm_stat.ias_rcvstate++;
72                 return;
73         }
74
75         /*
76          * IP packet - reset idle timer
77          */
78         ivp->iv_idle = 0;
79
80         /*
81          * Pass packet to IP
82          */
83         (void) ipatm_ipinput(ivp->iv_ipnif, m);
84 }
85
86
87 /*
88  * IP Input Packet Handler
89  * 
90  * All IP packets received from various ATM sources will be sent here
91  * for final queuing to the IP layer.
92  *
93  * Arguments:
94  *      inp     pointer to packet's receiving IP network interface
95  *      m       pointer to packet buffer chain
96  *
97  * Returns:
98  *      0       packet successfully queued to IP layer
99  *      else    error queuing packet, buffer chain freed
100  *
101  */
102 int
103 ipatm_ipinput(inp, m)
104         struct ip_nif   *inp;
105         KBuffer         *m;
106 {
107         int             s;
108 #if     BSD < 199103
109         int             space;
110 #endif
111
112 #ifdef DIAGNOSTIC
113         if (ipatm_print) {
114                 atm_pdu_print(m, "ipatm_ipinput");
115         }
116 #endif
117
118 #if defined(BSD)
119 #if BSD >= 199103
120
121 #ifdef DIAGNOSTIC
122         if (!KB_ISPKT(m)) {
123                 panic("ipatm_ipinput: no packet header");
124         }
125         {
126                 int     cnt = 0;
127                 KBuffer *m0 = m;
128
129                 while (m0) {
130                         cnt += KB_LEN(m0);
131                         m0 = KB_NEXT(m0);
132                 }
133                 if (m->m_pkthdr.len != cnt) {
134                         panic("ipatm_ipinput: packet length incorrect");
135                 }
136         }
137 #endif
138         /*
139          * Save the input ifnet pointer in the packet header
140          */
141         m->m_pkthdr.rcvif = (struct ifnet *)inp->inf_nif;
142
143 #else   /* ! BSD >= 199103 */
144         /*
145          * Stick ifnet pointer onto front of packet - hopefully 
146          * there'll be room in the first buffer.
147          */
148         KB_HEADROOM(m, space);
149         if (space < sizeof(struct ifnet *)) {
150                 KBuffer         *n;
151
152                 /*
153                  * We have to allocate another buffer and tack it
154                  * onto the front of the packet
155                  */
156                 KB_ALLOCPKT(n, sizeof(struct ifnet *),
157                         KB_F_NOWAIT, KB_T_HEADER);
158                 if (n == 0) {
159                         KB_FREEALL(m);
160                         ipatm_stat.ias_rcvnobuf++;
161                         return (1);
162                 }
163                 KB_LEN(n) = sizeof(struct ifnet *);
164                 KB_LINKHEAD(n, m);
165                 m = n;
166         } else {
167                 /*
168                  * Header fits, just adjust buffer controls
169                  */
170                 KB_HEADADJ(m, sizeof(struct ifnet *));
171         }
172         {
173                 struct ifnet    **p;
174
175                 KB_DATASTART(m, p, struct ifnet **);
176                 *p = (struct ifnet *)inp->inf_nif;
177         }
178 #endif  /* ! BSD >= 199103 */
179
180         /*
181          * Finally, hand packet off to IP.
182          *
183          * NB: Since we're already in the softint kernel state, we
184          * just call IP directly to avoid the extra unnecessary 
185          * kernel scheduling.
186          */
187         s = splimp();
188         if (IF_QFULL(&ipintrq)) {
189                 IF_DROP(&ipintrq);
190                 (void) splx(s);
191                 KB_FREEALL(m);
192                 return (1);
193         }
194
195         IF_ENQUEUE(&ipintrq, m);
196         (void) splx(s);
197 #if     BSD < 199506
198         ipintr();
199 #else
200         schednetisr ( NETISR_IP );
201 #endif  /* BSD >= 199506 */
202 #endif  /* defined(BSD) */
203
204         return (0);
205 }
206