diff options
Diffstat (limited to 'sys/netatm/ipatm/ipatm_input.c')
-rw-r--r-- | sys/netatm/ipatm/ipatm_input.c | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/sys/netatm/ipatm/ipatm_input.c b/sys/netatm/ipatm/ipatm_input.c new file mode 100644 index 000000000000..ca3e3e75a34a --- /dev/null +++ b/sys/netatm/ipatm/ipatm_input.c @@ -0,0 +1,210 @@ +/* + * + * =================================== + * HARP | Host ATM Research Platform + * =================================== + * + * + * This Host ATM Research Platform ("HARP") file (the "Software") is + * made available by Network Computing Services, Inc. ("NetworkCS") + * "AS IS". NetworkCS does not provide maintenance, improvements or + * support of any kind. + * + * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED, + * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE + * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE. + * In no event shall NetworkCS be responsible for any damages, including + * but not limited to consequential damages, arising from or relating to + * any use of the Software or related support. + * + * Copyright 1994-1998 Network Computing Services, Inc. + * + * Copies of this Software may be made, however, the above copyright + * notice must be reproduced on all copies. + * + * @(#) $Id: ipatm_input.c,v 1.9 1998/04/07 23:03:52 mks Exp $ + * + */ + +/* + * IP Over ATM Support + * ------------------- + * + * Process stack and data input + * + */ + +#ifndef lint +static char *RCSid = "@(#) $Id: ipatm_input.c,v 1.9 1998/04/07 23:03:52 mks Exp $"; +#endif + +#include <netatm/kern_include.h> + +#include <netatm/ipatm/ipatm.h> +#include <netatm/ipatm/ipatm_var.h> +#include <netatm/ipatm/ipatm_serv.h> + + +/* + * Process VCC Input Data + * + * Arguments: + * tok ipatm connection token (pointer to ipvcc) + * m pointer to input packet buffer chain + * + * Returns: + * none + * + */ +void +ipatm_cpcs_data(tok, m) + void *tok; + KBuffer *m; +{ + struct ipvcc *ivp = tok; + +#ifdef DIAGNOSTIC + if (ipatm_print) { + atm_pdu_print(m, "ipatm_input"); + } +#endif + + /* + * Handle input packet + */ + if (ivp->iv_state != IPVCC_ACTIVE) { + KB_FREEALL(m); + ipatm_stat.ias_rcvstate++; + return; + } + + /* + * IP packet - reset idle timer + */ + ivp->iv_idle = 0; + + /* + * Pass packet to IP + */ + (void) ipatm_ipinput(ivp->iv_ipnif, m); +} + + +/* + * IP Input Packet Handler + * + * All IP packets received from various ATM sources will be sent here + * for final queuing to the IP layer. + * + * Arguments: + * inp pointer to packet's receiving IP network interface + * m pointer to packet buffer chain + * + * Returns: + * 0 packet successfully queued to IP layer + * else error queuing packet, buffer chain freed + * + */ +int +ipatm_ipinput(inp, m) + struct ip_nif *inp; + KBuffer *m; +{ + int s, space; + +#ifdef DIAGNOSTIC + if (ipatm_print) { + atm_pdu_print(m, "ipatm_ipinput"); + } +#endif + +#if defined(BSD) +#if BSD >= 199103 + +#ifdef DIAGNOSTIC + if (!KB_ISPKT(m)) { + panic("ipatm_ipinput: no packet header"); + } + { + int cnt = 0; + KBuffer *m0 = m; + + while (m0) { + cnt += KB_LEN(m0); + m0 = KB_NEXT(m0); + } + if (m->m_pkthdr.len != cnt) { + panic("ipatm_ipinput: packet length incorrect"); + } + } +#endif + /* + * Save the input ifnet pointer in the packet header + */ + m->m_pkthdr.rcvif = (struct ifnet *)inp->inf_nif; + +#else /* ! BSD >= 199103 */ + /* + * Stick ifnet pointer onto front of packet - hopefully + * there'll be room in the first buffer. + */ + KB_HEADROOM(m, space); + if (space < sizeof(struct ifnet *)) { + KBuffer *n; + + /* + * We have to allocate another buffer and tack it + * onto the front of the packet + */ + KB_ALLOCPKT(n, sizeof(struct ifnet *), + KB_F_NOWAIT, KB_T_HEADER); + if (n == 0) { + KB_FREEALL(m); + ipatm_stat.ias_rcvnobuf++; + return (1); + } + KB_LEN(n) = sizeof(struct ifnet *); + KB_LINKHEAD(n, m); + m = n; + } else { + /* + * Header fits, just adjust buffer controls + */ + KB_HEADADJ(m, sizeof(struct ifnet *)); + } + { + struct ifnet **p; + + KB_DATASTART(m, p, struct ifnet **); + *p = (struct ifnet *)inp->inf_nif; + } +#endif /* ! BSD >= 199103 */ + + /* + * Finally, hand packet off to IP. + * + * NB: Since we're already in the softint kernel state, we + * just call IP directly to avoid the extra unnecessary + * kernel scheduling. + */ + s = splimp(); + if (IF_QFULL(&ipintrq)) { + IF_DROP(&ipintrq); + (void) splx(s); + KB_FREEALL(m); + return (1); + } + + IF_ENQUEUE(&ipintrq, m); + (void) splx(s); +#if BSD < 199506 + ipintr(); +#else + schednetisr ( NETISR_IP ); +#endif /* BSD >= 199506 */ +#endif /* defined(BSD) */ + + return (0); +} + |