225045b4c7b5d9c30b5898ff15f07eb0013db983
[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.5 2003/09/15 23:38:15 hsu 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 #if     BSD < 199103
108         int             space;
109 #endif
110
111 #ifdef DIAGNOSTIC
112         if (ipatm_print) {
113                 atm_pdu_print(m, "ipatm_ipinput");
114         }
115 #endif
116
117 #if defined(BSD)
118 #if BSD >= 199103
119
120 #ifdef DIAGNOSTIC
121         if (!KB_ISPKT(m)) {
122                 panic("ipatm_ipinput: no packet header");
123         }
124         {
125                 int     cnt = 0;
126                 KBuffer *m0 = m;
127
128                 while (m0) {
129                         cnt += KB_LEN(m0);
130                         m0 = KB_NEXT(m0);
131                 }
132                 if (m->m_pkthdr.len != cnt) {
133                         panic("ipatm_ipinput: packet length incorrect");
134                 }
135         }
136 #endif
137         /*
138          * Save the input ifnet pointer in the packet header
139          */
140         m->m_pkthdr.rcvif = (struct ifnet *)inp->inf_nif;
141
142 #else   /* ! BSD >= 199103 */
143         /*
144          * Stick ifnet pointer onto front of packet - hopefully 
145          * there'll be room in the first buffer.
146          */
147         KB_HEADROOM(m, space);
148         if (space < sizeof(struct ifnet *)) {
149                 KBuffer         *n;
150
151                 /*
152                  * We have to allocate another buffer and tack it
153                  * onto the front of the packet
154                  */
155                 KB_ALLOCPKT(n, sizeof(struct ifnet *),
156                         KB_F_NOWAIT, KB_T_HEADER);
157                 if (n == 0) {
158                         KB_FREEALL(m);
159                         ipatm_stat.ias_rcvnobuf++;
160                         return (1);
161                 }
162                 KB_LEN(n) = sizeof(struct ifnet *);
163                 KB_LINKHEAD(n, m);
164                 m = n;
165         } else {
166                 /*
167                  * Header fits, just adjust buffer controls
168                  */
169                 KB_HEADADJ(m, sizeof(struct ifnet *));
170         }
171         {
172                 struct ifnet    **p;
173
174                 KB_DATASTART(m, p, struct ifnet **);
175                 *p = (struct ifnet *)inp->inf_nif;
176         }
177 #endif  /* ! BSD >= 199103 */
178
179         /*
180          * Finally, hand packet off to IP.
181          *
182          * NB: Since we're already in the softint kernel state, we
183          * just call IP directly to avoid the extra unnecessary 
184          * kernel scheduling.
185          */
186         netisr_dispatch(NETISR_IP, m);
187 #endif  /* defined(BSD) */
188         return (0);
189 }