예제 #1
0
파일: lqr.c 프로젝트: 2asoft/freebsd
static void
SendLqrData(struct lcp *lcp)
{
  struct mbuf *bp;
  int extra;

  extra = proto_WrapperOctets(lcp, PROTO_LQR) +
          acf_WrapperOctets(lcp, PROTO_LQR);
  bp = m_get(sizeof(struct lqrdata) + extra, MB_LQROUT);
  bp->m_len -= extra;
  bp->m_offset += extra;

  /*
   * Send on the highest priority queue.  We send garbage - the real data
   * is written by lqr_LayerPush() where we know how to fill in all the
   * fields.  Note, lqr_LayerPush() ``knows'' that we're pushing onto the
   * highest priority queue, and factors out packet & octet values from
   * other queues!
   */
  link_PushPacket(lcp->fsm.link, bp, lcp->fsm.bundle,
                  LINK_QUEUES(lcp->fsm.link) - 1, PROTO_LQR);
}
예제 #2
0
static struct mbuf *
lqr_LayerPush(struct bundle *b, struct link *l, struct mbuf *bp,
              int pri, u_short *proto)
{
  struct physical *p = link2physical(l);
  int len, layer;

  if (!p) {
    /* Oops - can't happen :-] */
    m_freem(bp);
    return NULL;
  }

  bp = m_pullup(bp);
  len = m_length(bp);

  /*-
   * From rfc1989:
   *
   *  All octets which are included in the FCS calculation MUST be counted,
   *  including the packet header, the information field, and any padding.
   *  The FCS octets MUST also be counted, and one flag octet per frame
   *  MUST be counted.  All other octets (such as additional flag
   *  sequences, and escape bits or octets) MUST NOT be counted.
   *
   * As we're stacked higher than the HDLC layer (otherwise HDLC wouldn't be
   * able to calculate the FCS), we must not forget about these additional
   * bytes when we're asynchronous.
   *
   * We're also expecting to be stacked *before* the likes of the proto and
   * acf layers (to avoid alignment issues), so deal with this too.
   */

  p->hdlc.lqm.ifOutUniPackets++;
  p->hdlc.lqm.ifOutOctets += len + 1;		/* plus 1 flag octet! */
  for (layer = 0; layer < l->nlayers; layer++)
    switch (l->layer[layer]->type) {
      case LAYER_ACF:
        p->hdlc.lqm.ifOutOctets += acf_WrapperOctets(&l->lcp, *proto);
        break;
      case LAYER_ASYNC:
        /* Not included - see rfc1989 */
        break;
      case LAYER_HDLC:
        p->hdlc.lqm.ifOutOctets += hdlc_WrapperOctets(&l->lcp, *proto);
        break;
      case LAYER_LQR:
        layer = l->nlayers;
        break;
      case LAYER_PROTO:
        p->hdlc.lqm.ifOutOctets += proto_WrapperOctets(&l->lcp, *proto);
        break;
      case LAYER_SYNC:
        /* Nothing to add on */
        break;
      default:
        log_Printf(LogWARN, "Oops, don't know how to do octets for %s layer\n",
                   l->layer[layer]->name);
        break;
    }

  if (*proto == PROTO_LQR) {
    /* Overwrite the entire packet (created in SendLqrData()) */
    struct lqrdata lqr;
    size_t pending_pkts, pending_octets;
 
    p->hdlc.lqm.lqr.OutLQRs++;

    /*
     * We need to compensate for the fact that we're pushing our data
     * onto the highest priority queue by factoring out packet & octet
     * values from other queues!
     */
    link_PendingLowPriorityData(l, &pending_pkts, &pending_octets);

    memset(&lqr, '\0', sizeof lqr);
    lqr.MagicNumber = p->link.lcp.want_magic;
    lqr.LastOutLQRs = p->hdlc.lqm.lqr.peer.PeerOutLQRs;
    lqr.LastOutPackets = p->hdlc.lqm.lqr.peer.PeerOutPackets;
    lqr.LastOutOctets = p->hdlc.lqm.lqr.peer.PeerOutOctets;
    lqr.PeerInLQRs = p->hdlc.lqm.lqr.Save.InLQRs;
    lqr.PeerInPackets = p->hdlc.lqm.lqr.Save.InPackets;
    lqr.PeerInDiscards = p->hdlc.lqm.lqr.Save.InDiscards;
    lqr.PeerInErrors = p->hdlc.lqm.lqr.Save.InErrors;
    lqr.PeerInOctets = p->hdlc.lqm.lqr.Save.InOctets;
    lqr.PeerOutLQRs = p->hdlc.lqm.lqr.OutLQRs;
    lqr.PeerOutPackets = p->hdlc.lqm.ifOutUniPackets - pending_pkts;
    /* Don't forget our ``flag'' octets.... */
    lqr.PeerOutOctets = p->hdlc.lqm.ifOutOctets - pending_octets - pending_pkts;
    lqr_Dump(l->name, "Output", &lqr);
    lqr_ChangeOrder(&lqr, (struct lqrdata *)MBUF_CTOP(bp));
  }

  return bp;
}