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); }
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; }