38#include <sys/module.h>
39#include <sys/kernel.h>
40#include <sys/malloc.h>
45#include <machine/stdarg.h>
46#include <netnatm/unimsg.h>
49#define NGATMBASE_VERSION 1
96 lead = uni_msg_leading(m);
98 s += lead + len +
EXTRA;
99 if ((b = malloc(s, M_UNIMSG, M_NOWAIT)) == NULL) {
104 bcopy(m->b_rptr, b + lead, len);
105 free(m->b_buf, M_UNIMSG);
108 m->b_rptr = m->b_buf + lead;
109 m->b_wptr = m->b_rptr + len;
110 m->b_lim = m->b_buf + s;
124 if ((error = uni_msg_ensure(m, size)))
126 bcopy(buf, m->b_wptr, size);
140 struct mbuf *m, *m0, *
last;
143 MGETHDR(m0, M_NOWAIT, MT_DATA);
147 KASSERT(hdrlen <= MHLEN, (
"uni_msg_pack_mbuf: hdrlen > MHLEN"));
150 bcopy(hdr, m0->m_data, hdrlen);
152 m0->m_pkthdr.len = hdrlen;
155 if ((n = uni_msg_len(msg)) > MHLEN) {
156 if (!(MCLGET(m0, M_NOWAIT)))
162 bcopy(msg->b_rptr, m0->m_data, n);
165 m0->m_pkthdr.len = n;
169 while (msg != NULL && (n = uni_msg_len(msg)) != 0) {
170 MGET(m, M_NOWAIT, MT_DATA);
177 if (!(MCLGET(m, M_NOWAIT)))
183 bcopy(msg->b_rptr, m->m_data, n);
186 m0->m_pkthdr.len += n;
212 LIST_HEAD_INITIALIZER(ngatm_freeuni);
214 LIST_HEAD_INITIALIZER(ngatm_useduni);
225 while ((h = LIST_FIRST(&ngatm_freeuni)) != NULL) {
226 LIST_REMOVE(h, link);
227 free(h, M_UNIMSGHDR);
231 LIST_FOREACH(h, &ngatm_useduni, link)
232 printf(
"unimsg header in use: %p (%s, %d)\n",
233 &h->msg, h->file, h->line);
242_uni_msg_alloc(
size_t s,
const char *file,
int line)
247 if ((m = LIST_FIRST(&ngatm_freeuni)) != NULL)
248 LIST_REMOVE(m, link);
252 (m = malloc(
sizeof(*m), M_UNIMSGHDR, M_NOWAIT)) == NULL)
256 if((m->msg.b_buf = malloc(s, M_UNIMSG, M_NOWAIT | M_ZERO)) == NULL) {
258 LIST_INSERT_HEAD(&ngatm_freeuni, m, link);
262 m->msg.b_rptr = m->msg.b_wptr = m->msg.b_buf;
263 m->msg.b_lim = m->msg.b_buf + s;
268 LIST_INSERT_HEAD(&ngatm_useduni, m, link);
278_uni_msg_destroy(
struct uni_msg *m,
const char *file,
int line)
285 LIST_FOREACH(h, &ngatm_useduni, link)
293 LIST_FOREACH(h, &ngatm_freeuni, link)
298 printf(
"uni_msg %p was never allocated; found "
299 "in %s:%u\n", m, file, line);
301 printf(
"uni_msg %p was already destroyed in %s,%d; "
302 "found in %s:%u\n", m, h->file, h->line,
305 free(m->b_buf, M_UNIMSG);
307 LIST_REMOVE(d, link);
308 LIST_INSERT_HEAD(&ngatm_freeuni, d, link);
329 LIST_HEAD_INITIALIZER(ngatm_freeuni);
340 while ((h = LIST_FIRST(&ngatm_freeuni)) != NULL) {
341 LIST_REMOVE(h, link);
342 free(h, M_UNIMSGHDR);
358 if ((a = LIST_FIRST(&ngatm_freeuni)) != NULL)
359 LIST_REMOVE(a, link);
363 if ((m = malloc(
sizeof(*m), M_UNIMSGHDR, M_NOWAIT)) == NULL)
367 m = (
struct uni_msg *)a;
370 if((m->b_buf = malloc(s, M_UNIMSG, M_NOWAIT | M_ZERO)) == NULL) {
372 LIST_INSERT_HEAD(&ngatm_freeuni, a, link);
376 m->b_rptr = m->b_wptr = m->b_buf;
377 m->b_lim = m->b_buf + s;
393 free(m->b_buf, M_UNIMSG);
396 LIST_INSERT_HEAD(&ngatm_freeuni, a, link);
408_uni_msg_build(
const char *file,
int line,
void *ptr, ...)
423 n = va_arg(ap,
size_t);
425 p1 = va_arg(ap,
void *);
430 if ((m = _uni_msg_alloc(len, file, line)) == NULL)
439 n = va_arg(ap,
size_t);
440 bcopy(p1, m->b_wptr, n);
442 p1 = va_arg(ap,
void *);
454_uni_msg_unpack_mbuf(
struct mbuf *m,
struct uni_msg **pmsg,
const char *file,
461 if (!(m->m_flags & M_PKTHDR)) {
462 printf(
"%s: bogus packet %p\n", __func__, m);
466 if ((*pmsg = _uni_msg_alloc(m->m_pkthdr.len, file, line)) == NULL)
472 m_copydata(m, 0, m->m_pkthdr.len, (*pmsg)->b_wptr);
473 (*pmsg)->b_wptr += m->m_pkthdr.len;
DECLARE_MODULE(ngatmbase, ngatm_data, SI_SUB_EXEC, SI_ORDER_ANY)
int uni_msg_unpack_mbuf(struct mbuf *m, struct uni_msg **pmsg)
struct uni_msg * uni_msg_build(void *ptr,...)
static LIST_HEAD(ngatm_msg)
int uni_msg_extend(struct uni_msg *m, size_t s)
static int ngatm_handler(module_t, int, void *)
static MALLOC_DEFINE(M_UNIMSG, "unimsg", "uni message buffers")
struct uni_msg * uni_msg_alloc(size_t s)
MODULE_VERSION(ngatmbase, NGATMBASE_VERSION)
static struct mtx ngatm_unilist_mtx
#define NGATMBASE_VERSION
struct mbuf * uni_msg_pack_mbuf(struct uni_msg *msg, void *hdr, size_t hdrlen)
static void uni_msg_init(void)
static moduledata_t ngatm_data
int uni_msg_append(struct uni_msg *m, void *buf, size_t size)
void uni_msg_destroy(struct uni_msg *m)