Date: Tue, 12 Apr 2005 10:50:31 +0300 From: "Donatas" <donatas@lrtc.net> To: <freebsd-net@freebsd.org> Subject: unable to load atm_aal.ko (Corrected) Message-ID: <010e01c53f34$4d006d10$9f90a8c0@DONATAS>
next in thread | raw e-mail | index | archive | help
[-- Attachment #1 --] sorry for an error(wrote atm_llc.ko) so once again, atm_aal.c and atm_aal.h files cannot be compiled under FreeBSD5.3 and on 5.2 machine compiled atm_aal.ko cannot be loaded: kldload atm_aal.ko link_elf: symbol m_gethdr undefined can someone help to solve this problem? thank you Donatas Gendvilas SC Lithuanian Radio And Television Center Data Transfers Department - N.O.C. Phone: +370 5 2040444, +370 652 37580 Sausio 13-osios st. 10, 04347 Vilnius, Lithuania [-- Attachment #2 --] # -nostdinc -D_KERNEL -DKLD_MODULE -I- -I. -I@ -I@/dev -I@/../include -I/usr/include atm_aal.c atm_aal5.c atm_aal.o: atm_aal.c @/sys/param.h @/sys/types.h @/sys/cdefs.h \ machine/endian.h @/sys/_types.h machine/_types.h @/sys/select.h \ @/sys/_sigset.h @/sys/_timeval.h @/sys/timespec.h @/sys/syslimits.h \ @/sys/errno.h @/sys/time.h @/sys/priority.h machine/param.h \ @/sys/systm.h machine/atomic.h machine/cpufunc.h machine/psl.h \ @/sys/callout.h @/sys/queue.h @/sys/stdint.h machine/_stdint.h \ @/sys/libkern.h @/sys/mbuf.h @/sys/malloc.h @/sys/_lock.h \ @/sys/_mutex.h @/sys/kernel.h @/sys/linker_set.h @/sys/module.h \ @/sys/lock.h @/sys/mutex.h @/sys/pcpu.h @/sys/vmmeter.h machine/pcpu.h \ machine/segments.h machine/tss.h machine/mutex.h @/sys/socket.h \ @/sys/_iovec.h @/net/if.h @/net/if_var.h @/sys/_label.h @/sys/event.h \ @/net/if_media.h @/net/if_atm.h atm_aal.h atm_aal5.o: atm_aal5.c @/sys/param.h @/sys/types.h @/sys/cdefs.h \ machine/endian.h @/sys/_types.h machine/_types.h @/sys/select.h \ @/sys/_sigset.h @/sys/_timeval.h @/sys/timespec.h @/sys/syslimits.h \ @/sys/errno.h @/sys/time.h @/sys/priority.h machine/param.h \ @/sys/systm.h machine/atomic.h machine/cpufunc.h machine/psl.h \ @/sys/callout.h @/sys/queue.h @/sys/stdint.h machine/_stdint.h \ @/sys/libkern.h @/sys/mbuf.h @/sys/malloc.h @/sys/_lock.h \ @/sys/_mutex.h @/sys/kernel.h @/sys/linker_set.h @/sys/module.h \ @/sys/lock.h @/sys/mutex.h @/sys/pcpu.h @/sys/vmmeter.h machine/pcpu.h \ machine/segments.h machine/tss.h machine/mutex.h @/sys/socket.h \ @/sys/_iovec.h @/net/if.h @/net/if_var.h @/sys/_label.h @/sys/event.h \ @/net/if_media.h @/net/if_atm.h atm_aal.h [-- Attachment #3 --] /* * Copyright (c) 2003, Benno Rice <benno@eloquent.com.au> * All Rights Reserved. * * Development sponsored by Traverse Technologies, http://www.traverse.com.au/ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $Eloquent: projects/atm_aal/atm_aal5.c,v 1.9 2003/12/01 23:56:18 benno Exp $ */ #include <sys/param.h> #include <sys/systm.h> #include <sys/mbuf.h> #include <sys/malloc.h> #include <sys/kernel.h> #include <sys/lock.h> #include <sys/mutex.h> #include <sys/socket.h> #include <net/if.h> #include <net/if_media.h> #include <net/if_atm.h> #include "atm_aal.h" #define ATM_AAL5_EOM(cell) (cell[3] & 0x2) struct atm_aal5_trailer { uint8_t cpcs_uu; uint8_t cpi; uint16_t length; uint32_t crc; }; static uint32_t crc32table[] = { 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4, }; static uint32_t atm_aal5_crc(struct mbuf *, int); struct mbuf * atm_aal5_decode(struct atm_aal *aal, struct atm_aal_vcc *vcc, uint8_t *cell) { uint8_t *data; u_int pdu_length; struct atm_aal5_trailer trailer; struct mbuf *m; if (vcc->vcc_m == NULL) { MGETHDR(vcc->vcc_m, M_DONTWAIT, MT_DATA); if (vcc->vcc_m == NULL) { printf("atm_aal5_decode: MGETHDR failed\n"); return (NULL); } vcc->vcc_m->m_len = 0; vcc->vcc_m->m_pkthdr.len = 0; } data = cell + (aal->aal_flags & ATM_AAL_HEADER_4BYTE ? 4 : 5); m_copyback(vcc->vcc_m, vcc->vcc_length, 48, data); vcc->vcc_length += 48; if (ATM_AAL5_EOM(cell)) { trailer.cpcs_uu = data[40]; trailer.cpi = data[41]; trailer.length = ((data[42] & 0xff) << 8) + (data[43] & 0xff); trailer.crc = (data[44] << 24) + (data[45] << 16) + (data[46] << 8) + data[47]; if (vcc->vcc_length < trailer.length) { /* We've lost some data. */ printf("atm_aal5_decode: PDU too small\n"); m_freem(vcc->vcc_m); m = NULL; goto reset; } pdu_length = ((trailer.length + 8 + 47) / 48) * 48; if (vcc->vcc_length > pdu_length) { /* * We've got too much data. * Try trimming out the start on the assumption that * there's been a lost EOM cell. */ printf("atm_aal5_decode: PDU too large\n"); m_adj(vcc->vcc_m, vcc->vcc_length - pdu_length); vcc->vcc_length = pdu_length; } /* Calculate and check CRC. */ if (atm_aal5_crc(vcc->vcc_m, pdu_length - 4) != trailer.crc) { printf("atm_aal5_decode: CRC mismatch\n"); m_freem(vcc->vcc_m); m = NULL; goto reset; } /* Discard the trailer and the padding. */ m_adj(vcc->vcc_m, trailer.length - vcc->vcc_length); m = vcc->vcc_m; m->m_pkthdr.len = trailer.length; reset: MGETHDR(vcc->vcc_m, M_DONTWAIT, MT_DATA); if (vcc->vcc_m == NULL) { printf("atm_aal5_decode: MGETHDR failed\n"); } else { vcc->vcc_m->m_len = 0; vcc->vcc_m->m_pkthdr.len = 0; } vcc->vcc_length = 0; return (m); } return (NULL); } struct mbuf * atm_aal5_encode(struct atm_aal *aal, struct atm_aal_vcc *vcc, struct mbuf *m0) { uint16_t payload_length; int pdu_length, pad_length; uint32_t crc; uint8_t buffer[53], *trailer; if (m0->m_pkthdr.len > 65535) { return (NULL); } payload_length = m0->m_pkthdr.len & 0xffff; pdu_length = ((payload_length + 8 + 47) / 48) * 48; pad_length = pdu_length - payload_length - 8; bzero(buffer, pad_length + 8); /* We leave the CPCS-UU and CPI bits as zero for now. */ trailer = &buffer[pad_length]; trailer[2] = (payload_length >> 8) & 0xff; trailer[3] = payload_length & 0xff; m_copyback(m0, payload_length, pad_length + 4, buffer); crc = atm_aal5_crc(m0, pdu_length - 4); buffer[0] = (crc >> 24) & 0xff; buffer[1] = (crc >> 16) & 0xff; buffer[2] = (crc >> 8) & 0xff; buffer[3] = crc & 0xff; m_copyback(m0, pdu_length - 4, 4, buffer); return (atm_aal_segment(vcc, m0)); } static uint32_t atm_aal5_crc(struct mbuf *m0, int length) { uint32_t crc; struct mbuf *m; uint8_t *data; int len, total; crc = 0xffffffff; total = 0; for (m = m0; m != NULL; m = m->m_next) { for (len = m->m_len, data = m->m_data; len > 0; len--, data++) { crc = crc32table[((crc >> 24) ^ *data) & 0xff] ^ (crc << 8); total++; if (total >= length) break; } if (total >= length) break; } return (~crc); } [-- Attachment #4 --] /* * Copyright (c) 2003, Benno Rice <benno@eloquent.com.au> * All Rights Reserved. * * Development sponsored by Traverse Technologies, http://www.traverse.com.au/ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $Eloquent: projects/atm_aal/atm_aal.c,v 1.20 2003/12/01 23:56:18 benno Exp $ */ #include <sys/param.h> #include <sys/systm.h> #include <sys/mbuf.h> #include <sys/malloc.h> #include <sys/kernel.h> #include <sys/lock.h> #include <sys/mutex.h> #include <sys/socket.h> #include <sys/queue.h> #include <net/if.h> #include <net/if_media.h> #include <net/if_atm.h> #include "atm_aal.h" MALLOC_DEFINE(M_ATM_AAL, "atm_aal", "Data for ATM AAL operations"); #define ATM_AAL_GET_VPI(cell) \ (((cell[0] & 0xf) << 4) + (cell[1] >> 4)) #define ATM_AAL_GET_VCI(cell) \ (((cell[1] & 0xf) << 12) + (cell[2] << 4) + (cell[3] >> 4)) static void atm_aal_vcc_free(struct atm_aal_vcc *); static int atm_aal_modevent(module_t, int, void *); struct atm_aal * atm_aal_create(struct ifnet *ifnet, u_int flags, atm_aal_callback_t callback, void *arg) { struct atm_aal *aal; MALLOC(aal, struct atm_aal *, sizeof(struct atm_aal), M_ATM_AAL, M_WAITOK | M_ZERO); if (aal == NULL) { printf("atm_aal_create: malloc failed\n"); return (NULL); } SLIST_INIT(&aal->aal_vccs); aal->aal_nvccs = 0; mtx_init(&aal->aal_mtx, "ATM AAL", NULL, MTX_DEF); aal->aal_flags = flags; aal->aal_callback = callback; aal->aal_arg = arg; return (aal); } void atm_aal_destroy(struct atm_aal *aal) { atm_aal_vcc_closeall(aal); mtx_lock(&aal->aal_mtx); mtx_destroy(&aal->aal_mtx); FREE(aal, M_ATM_AAL); } int atm_aal_vcc_open(struct atm_aal *aal, u_int vpi, u_int vci, u_int aaltype, u_int flags, void *arg) { struct atm_aal_vcc *vcc, *vcc1; if ((flags & ATMIO_FLAG_NOTX) && (flags & ATMIO_FLAG_NORX)) { return (EINVAL); } switch (aaltype) { case ATMIO_AAL_RAW: case ATMIO_AAL_5: break; default: return (EINVAL); } MALLOC(vcc, struct atm_aal_vcc *, sizeof(struct atm_aal_vcc), M_ATM_AAL, M_WAITOK | M_ZERO); if (vcc == NULL) { printf("atm_aal_vcc_open: malloc failed\n"); return (ENOMEM); } MGETHDR(vcc->vcc_m, M_TRYWAIT, MT_DATA); if (vcc->vcc_m == NULL) { printf("atm_aal_vcc_open: MGETHDR failed\n"); FREE(vcc, M_ATM_AAL); return (ENOMEM); } vcc->vcc_m->m_len = 0; vcc->vcc_m->m_pkthdr.len = 0; vcc->vcc_vpi = vpi; vcc->vcc_vci = vci; vcc->vcc_aal = aaltype; vcc->vcc_flags = flags; vcc->vcc_length = 0; vcc->vcc_arg = arg; mtx_lock(&aal->aal_mtx); SLIST_FOREACH(vcc1, &aal->aal_vccs, vcc_next) { if (vcc1->vcc_vpi == vpi && vcc1->vcc_vci == vci) { m_freem(vcc->vcc_m); free(vcc, M_ATM_AAL); return (EBUSY); } } SLIST_INSERT_HEAD(&aal->aal_vccs, vcc, vcc_next); aal->aal_nvccs++; mtx_unlock(&aal->aal_mtx); return (0); } void atm_aal_vcc_close(struct atm_aal *aal, u_int vpi, u_int vci) { struct atm_aal_vcc *vcc; mtx_lock(&aal->aal_mtx); SLIST_FOREACH(vcc, &aal->aal_vccs, vcc_next) { if (vcc->vcc_vpi == vpi && vcc->vcc_vci == vci) { SLIST_REMOVE(&aal->aal_vccs, vcc, atm_aal_vcc, vcc_next); atm_aal_vcc_free(vcc); aal->aal_nvccs--; mtx_unlock(&aal->aal_mtx); return; } } mtx_unlock(&aal->aal_mtx); } void atm_aal_vcc_closeall(struct atm_aal *aal) { struct atm_aal_vcc *vcc; mtx_lock(&aal->aal_mtx); while (!SLIST_EMPTY(&aal->aal_vccs)) { vcc = SLIST_FIRST(&aal->aal_vccs); SLIST_REMOVE_HEAD(&aal->aal_vccs, vcc_next); atm_aal_vcc_free(vcc); } aal->aal_nvccs = 0; mtx_unlock(&aal->aal_mtx); } void atm_aal_process_in(struct atm_aal *aal, uint8_t *cells, u_int ncells) { struct atm_aal_vcc *vcc; u_int vpi, vci; uint8_t *cell; int i; struct mbuf *m; vcc = NULL; mtx_lock(&aal->aal_mtx); for (i = 0; i < ncells; i++) { if (aal->aal_flags & ATM_AAL_HEADER_4BYTE) { cell = &cells[i * 52]; } else { cell = &cells[i * 53]; } vpi = ATM_AAL_GET_VPI(cell); vci = ATM_AAL_GET_VCI(cell); if (vcc == NULL || vcc->vcc_vpi != vpi || vcc->vcc_vci != vci) { SLIST_FOREACH(vcc, &aal->aal_vccs, vcc_next) { if (vcc->vcc_vpi == vpi && vcc->vcc_vci == vci) { break; } } if (vcc == NULL) continue; } if (vcc->vcc_flags & ATMIO_FLAG_NORX) { continue; } m = NULL; switch (vcc->vcc_aal) { case ATMIO_AAL_0: case ATMIO_AAL_34: break; /* UNSUPPORTED */ case ATMIO_AAL_5: m = atm_aal5_decode(aal, vcc, cell); break; case ATMIO_AAL_RAW: m = atm_aalraw_decode(aal, vcc, cell); break; } if (m != NULL) { mtx_unlock(&aal->aal_mtx); aal->aal_callback(aal, vcc, m); vcc = NULL; mtx_lock(&aal->aal_mtx); } } mtx_unlock(&aal->aal_mtx); } struct mbuf * atm_aal_process_out(struct atm_aal *aal, struct mbuf *m) { struct atm_pseudohdr *aph; u_int vpi, vci; struct atm_aal_vcc *vcc; if (m->m_pkthdr.len < sizeof(struct atm_pseudohdr)) { printf("atm_aal_process_out: chain too small (%d)\n", m->m_pkthdr.len); m_freem(m); return (NULL); } if (m->m_len < sizeof(struct atm_pseudohdr) && (m = m_pullup(m, sizeof(struct atm_pseudohdr))) == NULL) { printf("atm_aal_process_out: m_pullup failed\n"); return (NULL); } aph = mtod(m, struct atm_pseudohdr *); vpi = ATM_PH_VPI(aph); vci = ATM_PH_VCI(aph); m_adj(m, sizeof(struct atm_pseudohdr)); if (m->m_pkthdr.len == 0) { printf("atm_aal_process_out: no data\n"); m_freem(m); return (NULL); } mtx_lock(&aal->aal_mtx); SLIST_FOREACH(vcc, &aal->aal_vccs, vcc_next) { if (vcc->vcc_vpi == vpi && vcc->vcc_vci == vci) { break; } } if (vcc == NULL) { printf("atm_aal_process_out: no vcc for %d/%d\n", vpi, vci); mtx_unlock(&aal->aal_mtx); m_freem(m); return (NULL); } switch (vcc->vcc_aal) { case ATMIO_AAL_0: m = atm_aal_segment(vcc, m); break; case ATMIO_AAL_34: break; /* UNSUPPORTED */ case ATMIO_AAL_5: m = atm_aal5_encode(aal, vcc, m); break; } mtx_unlock(&aal->aal_mtx); return (m); } /* * Allocate an mbuf chain that holds the given amount of data filled * with what junk we got from the allocation routines. */ static struct mbuf * atm_aal_mgetm(struct mbuf *m0, u_int len) { struct mbuf *m, *tmp; if (len <= MHLEN) { MGETHDR(m, M_DONTWAIT, MT_DATA); if (m == NULL) { printf("atm_aal_segment: MGETHDR failed\n"); return (NULL); } if (m_dup_pkthdr(m, m0, M_DONTWAIT) == 0) { printf("atm_aal_segment: m_dup_pkthdr failed?\n"); m_freem(m); return (NULL); } m->m_len = m->m_pkthdr.len = len; return (m); } m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); if (m == NULL) { printf("atm_aal_segment: MGETHDR failed\n"); return (NULL); } if (m_dup_pkthdr(m, m0, M_DONTWAIT) == 0) { printf("atm_aal_segment: m_dup_pkthdr failed?\n"); m_freem(m); return (NULL); } if (len <= MCLBYTES) { m->m_len = m->m_pkthdr.len = len; return (m); } m->m_len = MCLBYTES; m->m_pkthdr.len = len; len -= MCLBYTES; tmp = m_getm(m, len, M_DONTWAIT, MT_DATA); if (tmp == NULL) { printf("atm_aal_segment: allocating chain failed\n"); m_freem(m); return (NULL); } /* fixup lengths */ while (len > 0) { if (tmp->m_flags & M_EXT) tmp->m_len = min(len, MCLBYTES); else tmp->m_len = min(len, MLEN); len -= tmp->m_len; tmp = tmp->m_next; } return (m); } struct mbuf * atm_aal_segment(struct atm_aal_vcc *vcc, struct mbuf *m0) { int pdu_cells, pdu_length, i; uint8_t buffer[53]; struct mbuf *m; pdu_length = m0->m_pkthdr.len; pdu_cells = pdu_length / 48; m = atm_aal_mgetm(m0, pdu_cells * 52); if (m == NULL) return (NULL); buffer[0] = (vcc->vcc_vpi >> 4) & 0xf; buffer[1] = ((vcc->vcc_vpi << 4) & 0xf0) + ((vcc->vcc_vci >> 12) & 0xf); buffer[2] = (vcc->vcc_vci >> 4) & 0xff; buffer[3] = (vcc->vcc_vci << 4) & 0xf0; /* XXX: HEC */ for (i = 0; i < pdu_cells; i++) { #ifdef DEBUG printf("atm_aal_segment: before: m0 = %d m = %d\n", m_length(m0, NULL), m_length(m, NULL)); #endif m_copydata(m0, i * 48, 48, &buffer[4]); if (i == pdu_cells - 1) { /* XXX: All the world is AAL5? */ buffer[3] |= 0x2; /* XXX: HEC */ } /* XXX should optimize and not use m_copyback */ m_copyback(m, i * 52, 52, buffer); #ifdef DEBUG printf("atm_aal_segment: after: m0 = %d m = %d\n", m_length(m0, NULL), m_length(m, NULL)); #endif } m_freem(m0); return (m); } void atm_aal_input(struct atm_aal *aal, struct atm_aal_vcc *vcc, struct mbuf *m) { struct ifnet *ifp; struct atm_pseudohdr aph; ifp = (struct ifnet *)aal->aal_arg; m->m_pkthdr.rcvif = ifp; ATM_PH_FLAGS(&aph) = vcc->vcc_flags; ATM_PH_VPI(&aph) = vcc->vcc_vpi; ATM_PH_SETVCI(&aph, vcc->vcc_vci); ifp->if_ipackets++; atm_input(ifp, &aph, m, vcc->vcc_arg); } static void atm_aal_vcc_free(struct atm_aal_vcc *vcc) { m_freem(vcc->vcc_m); FREE(vcc, M_ATM_AAL); } static int atm_aal_modevent(module_t mod, int type, void *unused) { switch (type) { case MOD_LOAD: if (bootverbose) printf("atm_aal: <Software ATM Adaptation Layer>\n"); return (0); break; case MOD_UNLOAD: return (0); break; } return (EINVAL); } static moduledata_t atm_aal_mod = { "atm_aal", atm_aal_modevent, 0 }; DECLARE_MODULE(atm_aal, atm_aal_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST); MODULE_VERSION(atm_aal, 1); MODULE_DEPEND(atm_aal, atm, 1, 1, 1); /* * RAW AAL - just produce one mbuf per cell */ struct mbuf * atm_aalraw_decode(struct atm_aal *aal, struct atm_aal_vcc *vcc, uint8_t *cell) { struct mbuf *m; if (vcc->vcc_m == NULL) { MGETHDR(vcc->vcc_m, M_DONTWAIT, MT_DATA); if (vcc->vcc_m == NULL) { printf("atm_aal5_decode: MGETHDR failed\n"); return (NULL); } vcc->vcc_m->m_len = 0; vcc->vcc_m->m_pkthdr.len = 0; } vcc->vcc_m->m_len = 52; vcc->vcc_m->m_pkthdr.len = 52; if (aal->aal_flags & ATM_AAL_HEADER_4BYTE) bcopy(cell, vcc->vcc_m->m_data, 52); else { bcopy(cell, vcc->vcc_m->m_data, 4); bcopy(cell + 5, vcc->vcc_m->m_data + 4, 48); } m = vcc->vcc_m; vcc->vcc_m = NULL; return (m); } /* * Return just a copy but be sure to truncate to a multiple of 52 byte */ struct mbuf * atm_aalraw_encode(struct atm_aal *aal, struct atm_aal_vcc *vcc, struct mbuf *m0) { struct mbuf *m; u_int pdu_cells; pdu_cells = m0->m_pkthdr.len / 52; if (m0->m_pkthdr.len % 52 == 0) m = m_copypacket(m0, M_DONTWAIT); else { m = m_dup(m0, M_DONTWAIT); if (m != NULL) m_adj(m, -(m0->m_pkthdr.len % 52)); } return (m); } [-- Attachment #5 --] /* * Copyright (c) 2003, Benno Rice <benno@eloquent.com.au> * All Rights Reserved. * * Development sponsored by Traverse Technologies, http://www.traverse.com.au/ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $Eloquent: projects/atm_aal/atm_aal.h,v 1.11 2003/12/01 23:56:18 benno Exp $ */ #ifndef _ATM_AAL_H_ #define _ATM_AAL_H_ #include <sys/queue.h> MALLOC_DECLARE(M_ATM_AAL); SLIST_HEAD(atm_aal_vcc_list, atm_aal_vcc); struct atm_aal; struct atm_aal_vcc; typedef void atm_aal_callback_t(struct atm_aal *, struct atm_aal_vcc *, struct mbuf *); struct atm_aal { int aal_nvccs; /* How many VCCs we have. */ struct atm_aal_vcc_list aal_vccs; /* List of VCCs. */ struct mtx aal_mtx; /* Mutex. */ u_int aal_flags; /* Flags. */ atm_aal_callback_t *aal_callback; /* Callback for when we have data. */ void *aal_arg; /* Callback argument. */ }; struct atm_aal_vcc { u_int vcc_vpi; /* Virtual Path Identifier */ u_int vcc_vci; /* Virtual Channel Identifier */ u_int vcc_aal; /* ATM Adaptation Layer */ u_int vcc_flags; /* Flags */ struct mbuf *vcc_m; /* Our current mbuf. */ u_int vcc_length; /* How much data we're holding. */ void *vcc_arg; /* Callback argument. */ SLIST_ENTRY(atm_aal_vcc) vcc_next; }; /* Flag definitions. */ #define ATM_AAL_HEADER_4BYTE 0x00000001 /* HEC is done elsewhere. */ /* AAL context management. */ struct atm_aal * atm_aal_create(struct ifnet *, u_int, atm_aal_callback_t, void *); void atm_aal_destroy(struct atm_aal *); /* AAL VCC management. */ int atm_aal_vcc_open(struct atm_aal *, u_int, u_int, u_int, u_int, void *); void atm_aal_vcc_close(struct atm_aal *, u_int, u_int); void atm_aal_vcc_closeall(struct atm_aal *); /* Entry points for in- and outbound processing. */ void atm_aal_process_in(struct atm_aal *, uint8_t *, u_int); struct mbuf * atm_aal_process_out(struct atm_aal *, struct mbuf *); /* Convenience function for AALs. Handles segmentation and header addition. */ struct mbuf * atm_aal_segment(struct atm_aal_vcc *, struct mbuf *); /* Convenience function to act as a callback to hand mbufs to the ATM layer. */ void atm_aal_input(struct atm_aal *, struct atm_aal_vcc *, struct mbuf *); /* Function for returning the vcc table. */ struct atmio_vcctable * atm_aal_getvccs(struct atm_aal *, int); /* AAL5 routines. */ struct mbuf * atm_aal5_decode(struct atm_aal *, struct atm_aal_vcc *, uint8_t *); struct mbuf * atm_aal5_encode(struct atm_aal *, struct atm_aal_vcc *, struct mbuf *); /* RAW AAL routines. */ struct mbuf * atm_aalraw_decode(struct atm_aal *, struct atm_aal_vcc *, uint8_t *); struct mbuf * atm_aalraw_encode(struct atm_aal *, struct atm_aal_vcc *, struct mbuf *); #endif [-- Attachment #6 --] # $Eloquent: projects/atm_aal/Makefile,v 1.1 2003/09/20 12:00:50 benno Exp $ KMOD= atm_aal SRCS= atm_aal.c atm_aal5.c .include <bsd.kmod.mk>
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?010e01c53f34$4d006d10$9f90a8c0>
