if.c revision a635f37f89f35fb85d5ec2236c5e25c5997b6c89
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle/*
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle * Copyright (c) 1995 Danny Gasparovski.
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle *
097bfeed7df838b1ecab3f9b0e464d32b22b3633Chad Kienle * Please read the file COPYRIGHT for the
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle * terms and conditions of the copyright.
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle */
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle#include <slirp.h>
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle#define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm))
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienlestatic void ifs_insque(struct mbuf *ifm, struct mbuf *ifmhead)
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle{
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle ifm->ifs_next = ifmhead->ifs_next;
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle ifmhead->ifs_next = ifm;
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle ifm->ifs_prev = ifmhead;
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle ifm->ifs_next->ifs_prev = ifm;
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle}
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienlestatic void ifs_remque(struct mbuf *ifm)
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle{
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle ifm->ifs_prev->ifs_next = ifm->ifs_next;
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle ifm->ifs_next->ifs_prev = ifm->ifs_prev;
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle}
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle
960fec0475ebdfe553ee373492c5ca9aeb6568b5Chad Kienlevoid
960fec0475ebdfe553ee373492c5ca9aeb6568b5Chad Kienleif_init(PNATState pData)
960fec0475ebdfe553ee373492c5ca9aeb6568b5Chad Kienle{
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle /* 2 for alignment, 14 for ethernet, 40 for TCP/IP */
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle if_maxlinkhdr = 2 + 14 + 40;
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle if_queued = 0;
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle if_thresh = 10;
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle if_mtu = 1500;
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle if_mru = 1500;
960fec0475ebdfe553ee373492c5ca9aeb6568b5Chad Kienle if_comp = IF_AUTOCOMP;
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle if_fastq.ifq_next = if_fastq.ifq_prev = &if_fastq;
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle if_batchq.ifq_next = if_batchq.ifq_prev = &if_batchq;
bbd145f9a8eae7f1e801398d0c6ff10e360cc853Chad Kienle/* sl_compress_init(&comp_s); */
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle next_m = &if_batchq;
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle}
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle/*
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle * if_output: Queue packet into an output queue.
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle * There are 2 output queue's, if_fastq and if_batchq.
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle * Each output queue is a doubly linked list of double linked lists
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle * of mbufs, each list belonging to one "session" (socket). This
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle * way, we can output packets fairly by sending one packet from each
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle * session, instead of all the packets from one session, then all packets
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle * from the next session, etc. Packets on the if_fastq get absolute
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle * priority, but if one session hogs the link, it gets "downgraded"
13bd86ef28dc99779ef14d9b30fb2d88dfdaca87Chad Kienle * to the batchq until it runs out of packets, then it'll return
13bd86ef28dc99779ef14d9b30fb2d88dfdaca87Chad Kienle * to the fastq (eg. if the user does an ls -alR in a telnet session,
2457dfd453eb97df58c0a9392ffd8c3d50e2497dChad Kienle * it'll temporarily get downgraded to the batchq)
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle */
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienlevoid
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienleif_output(PNATState pData, struct socket *so, struct mbuf *ifm)
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle{
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle struct mbuf *ifq;
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle int on_fastq = 1;
2457dfd453eb97df58c0a9392ffd8c3d50e2497dChad Kienle
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle DEBUG_CALL("if_output");
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle DEBUG_ARG("so = %lx", (long)so);
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle DEBUG_ARG("ifm = %lx", (long)ifm);
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle /*
8896e80cf352ac72c24eb9c08463f27866aeb68aJason Lemay * First remove the mbuf from m_usedlist,
8896e80cf352ac72c24eb9c08463f27866aeb68aJason Lemay * since we're gonna use m_next and m_prev ourselves
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle * XXX Shouldn't need this, gotta change dtom() etc.
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle */
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle if (ifm->m_flags & M_USEDLIST)
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle {
8896e80cf352ac72c24eb9c08463f27866aeb68aJason Lemay remque(pData, ifm);
dd291c383b4490ed77e47d65b4c52595d915f802Chad Kienle ifm->m_flags &= ~M_USEDLIST;
960fec0475ebdfe553ee373492c5ca9aeb6568b5Chad Kienle }
960fec0475ebdfe553ee373492c5ca9aeb6568b5Chad Kienle
960fec0475ebdfe553ee373492c5ca9aeb6568b5Chad Kienle /*
960fec0475ebdfe553ee373492c5ca9aeb6568b5Chad Kienle * See if there's already a batchq list for this session.
960fec0475ebdfe553ee373492c5ca9aeb6568b5Chad Kienle * This can include an interactive session, which should go on fastq,
a485b9752cb65285d7164dfc69a97c0e69011d0bChad Kienle * but gets too greedy... hence it'll be downgraded from fastq to batchq.
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle * We mustn't put this packet back on the fastq (or we'll send it out of order)
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle * XXX add cache here?
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle */
960fec0475ebdfe553ee373492c5ca9aeb6568b5Chad Kienle for (ifq = if_batchq.ifq_prev; ifq != &if_batchq; ifq = ifq->ifq_prev)
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle {
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle if (so == ifq->ifq_so)
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle {
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle /* A match! */
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle ifm->ifq_so = so;
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle ifs_insque(ifm, ifq->ifs_prev);
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle goto diddit;
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle }
a1d206a2a22b5cde9b00633ea4472ae0b144d695Brendan Mmiller }
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle /* No match, check which queue to put it on */
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle if (so && (so->so_iptos & IPTOS_LOWDELAY))
a1d206a2a22b5cde9b00633ea4472ae0b144d695Brendan Mmiller {
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle ifq = if_fastq.ifq_prev;
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle on_fastq = 1;
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle /*
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle * Check if this packet is a part of the last
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle * packet's session
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle */
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle if (ifq->ifq_so == so)
960fec0475ebdfe553ee373492c5ca9aeb6568b5Chad Kienle {
960fec0475ebdfe553ee373492c5ca9aeb6568b5Chad Kienle ifm->ifq_so = so;
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle ifs_insque(ifm, ifq->ifs_prev);
a1d206a2a22b5cde9b00633ea4472ae0b144d695Brendan Mmiller goto diddit;
a1d206a2a22b5cde9b00633ea4472ae0b144d695Brendan Mmiller }
a1d206a2a22b5cde9b00633ea4472ae0b144d695Brendan Mmiller }
a1d206a2a22b5cde9b00633ea4472ae0b144d695Brendan Mmiller else
a1d206a2a22b5cde9b00633ea4472ae0b144d695Brendan Mmiller ifq = if_batchq.ifq_prev;
a1d206a2a22b5cde9b00633ea4472ae0b144d695Brendan Mmiller
a1d206a2a22b5cde9b00633ea4472ae0b144d695Brendan Mmiller /* Create a new doubly linked list for this session */
a1d206a2a22b5cde9b00633ea4472ae0b144d695Brendan Mmiller ifm->ifq_so = so;
a485b9752cb65285d7164dfc69a97c0e69011d0bChad Kienle ifs_init(ifm);
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle insque(pData, ifm, ifq);
ad0b283113c3f11ac1877df97d5d0fae899b56caBrendan Mmiller
a485b9752cb65285d7164dfc69a97c0e69011d0bChad Kienlediddit:
ad0b283113c3f11ac1877df97d5d0fae899b56caBrendan Mmiller ++if_queued;
a485b9752cb65285d7164dfc69a97c0e69011d0bChad Kienle
ad0b283113c3f11ac1877df97d5d0fae899b56caBrendan Mmiller if (so)
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle {
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle /* Update *_queued */
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle so->so_queued++;
a1d206a2a22b5cde9b00633ea4472ae0b144d695Brendan Mmiller so->so_nqueued++;
960fec0475ebdfe553ee373492c5ca9aeb6568b5Chad Kienle /*
960fec0475ebdfe553ee373492c5ca9aeb6568b5Chad Kienle * Check if the interactive session should be downgraded to
960fec0475ebdfe553ee373492c5ca9aeb6568b5Chad Kienle * the batchq. A session is downgraded if it has queued 6
960fec0475ebdfe553ee373492c5ca9aeb6568b5Chad Kienle * packets without pausing, and at least 3 of those packets
960fec0475ebdfe553ee373492c5ca9aeb6568b5Chad Kienle * have been sent over the link
960fec0475ebdfe553ee373492c5ca9aeb6568b5Chad Kienle * (XXX These are arbitrary numbers, probably not optimal..)
960fec0475ebdfe553ee373492c5ca9aeb6568b5Chad Kienle */
960fec0475ebdfe553ee373492c5ca9aeb6568b5Chad Kienle if (on_fastq
960fec0475ebdfe553ee373492c5ca9aeb6568b5Chad Kienle && so->so_nqueued >= 6
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle && (so->so_nqueued - so->so_queued) >= 3)
8896e80cf352ac72c24eb9c08463f27866aeb68aJason Lemay {
8896e80cf352ac72c24eb9c08463f27866aeb68aJason Lemay /* Remove from current queue... */
ad0b283113c3f11ac1877df97d5d0fae899b56caBrendan Mmiller remque(pData, ifm->ifs_next);
ad0b283113c3f11ac1877df97d5d0fae899b56caBrendan Mmiller
ad0b283113c3f11ac1877df97d5d0fae899b56caBrendan Mmiller /* ...And insert in the new. That'll teach ya! */
a485b9752cb65285d7164dfc69a97c0e69011d0bChad Kienle insque(pData, ifm->ifs_next, &if_batchq);
960fec0475ebdfe553ee373492c5ca9aeb6568b5Chad Kienle }
960fec0475ebdfe553ee373492c5ca9aeb6568b5Chad Kienle }
8896e80cf352ac72c24eb9c08463f27866aeb68aJason Lemay
8896e80cf352ac72c24eb9c08463f27866aeb68aJason Lemay#ifndef FULL_BOLT
ad0b283113c3f11ac1877df97d5d0fae899b56caBrendan Mmiller /*
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle * This prevents us from malloc()ing too many mbufs
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle */
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle if (link_up)
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle {
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle /* if_start will check towrite */
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle if_start(pData);
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle }
a1d206a2a22b5cde9b00633ea4472ae0b144d695Brendan Mmiller#endif
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle}
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle/*
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle * Send a packet
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle * We choose a packet based on it's position in the output queues;
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle * If there are packets on the fastq, they are sent FIFO, before
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle * everything else. Otherwise we choose the first packet from the
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle * batchq and send it. the next packet chosen will be from the session
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle * after this one, then the session after that one, and so on.. So,
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle * for example, if there are 3 ftp session's fighting for bandwidth,
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle * one packet will be sent from the first session, then one packet
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle * from the second session, then one packet from the third, then back
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle * to the first, etc. etc.
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle */
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienlevoid
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienleif_start(PNATState pData)
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle{
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle struct mbuf *ifm, *ifqt;
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle DEBUG_CALL("if_start");
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle if (!if_queued)
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle return; /* Nothing to do */
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle for (;;)
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle {
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle /* check if we can really output */
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle if (!slirp_can_output(pData->pvUser))
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle {
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle Log(("if_start: can't send\n"));
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle return;
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle }
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle /*
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle * See which queue to get next packet from
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle * If there's something in the fastq, select it immediately
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle */
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle if (if_fastq.ifq_next != &if_fastq)
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle ifm = if_fastq.ifq_next;
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle else
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle {
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle /* Nothing on fastq, see if next_m is valid */
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle if (next_m != &if_batchq)
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle ifm = next_m;
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle else
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle ifm = if_batchq.ifq_next;
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle /* Set which packet to send on next iteration */
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle next_m = ifm->ifq_next;
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle }
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle /* Remove it from the queue */
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle ifqt = ifm->ifq_prev;
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle remque(pData, ifm);
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle --if_queued;
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle /* If there are more packets for this session, re-queue them */
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle if (ifm->ifs_next != /* ifm->ifs_prev != */ ifm)
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle {
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle insque(pData, ifm->ifs_next, ifqt);
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle ifs_remque(ifm);
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle }
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle /* Update so_queued */
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle if (ifm->ifq_so)
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle {
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle if (--ifm->ifq_so->so_queued == 0)
8896e80cf352ac72c24eb9c08463f27866aeb68aJason Lemay /* If there's no more queued, reset nqueued */
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle ifm->ifq_so->so_nqueued = 0;
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle }
c777daef5dae2223f9a99ec0e127182ce2388ce3Chad Kienle
2457dfd453eb97df58c0a9392ffd8c3d50e2497dChad Kienle /* Encapsulate the packet for sending */
8896e80cf352ac72c24eb9c08463f27866aeb68aJason Lemay if_encap(pData, ETH_P_IP, (const uint8_t *)ifm->m_data, ifm->m_len);
2457dfd453eb97df58c0a9392ffd8c3d50e2497dChad Kienle
13bd86ef28dc99779ef14d9b30fb2d88dfdaca87Chad Kienle m_free(pData, ifm);
13bd86ef28dc99779ef14d9b30fb2d88dfdaca87Chad Kienle
13bd86ef28dc99779ef14d9b30fb2d88dfdaca87Chad Kienle if (!if_queued)
13bd86ef28dc99779ef14d9b30fb2d88dfdaca87Chad Kienle return;
13bd86ef28dc99779ef14d9b30fb2d88dfdaca87Chad Kienle }
13bd86ef28dc99779ef14d9b30fb2d88dfdaca87Chad Kienle}
2457dfd453eb97df58c0a9392ffd8c3d50e2497dChad Kienle