Пример #1
0
size_t
ipv6cp_QueueLen(struct ipv6cp *ipv6cp)
{
  struct mqueue *q;
  size_t result;

  result = 0;
  for (q = ipv6cp->Queue; q < ipv6cp->Queue + IPV6CP_QUEUES(ipv6cp); q++)
    result += q->len;

  return result;
}
Пример #2
0
/*
 * Enqueue a packet of the given address family.  Nothing will make it
 * down to the physical link level 'till ncp_FillPhysicalQueues() is used.
 */
void
ncp_Enqueue(struct ncp *ncp, int af, unsigned pri, char *ptr, int count)
{
#ifndef NOINET6
  struct ipv6cp *ipv6cp = &ncp->ipv6cp;
#endif
  struct ipcp *ipcp = &ncp->ipcp;
  struct mbuf *bp;

  /*
   * We allocate an extra 6 bytes, four at the front and two at the end.
   * This is an optimisation so that we need to do less work in
   * m_prepend() in acf_LayerPush() and proto_LayerPush() and
   * appending in hdlc_LayerPush().
   */

  switch (af) {
  case AF_INET:
    if (pri >= IPCP_QUEUES(ipcp)) {
      log_Printf(LogERROR, "Can't store in ip queue %u\n", pri);
      break;
    }

    bp = m_get(count + 6, MB_IPOUT);
    bp->m_offset += 4;
    bp->m_len -= 6;
    memcpy(MBUF_CTOP(bp), ptr, count);
    m_enqueue(ipcp->Queue + pri, bp);
    break;

#ifndef NOINET6
  case AF_INET6:
    if (pri >= IPV6CP_QUEUES(ipcp)) {
      log_Printf(LogERROR, "Can't store in ipv6 queue %u\n", pri);
      break;
    }

    bp = m_get(count + 6, MB_IPOUT);
    bp->m_offset += 4;
    bp->m_len -= 6;
    memcpy(MBUF_CTOP(bp), ptr, count);
    m_enqueue(ipv6cp->Queue + pri, bp);
    break;
#endif

  default:
      log_Printf(LogERROR, "Can't enqueue protocol family %d\n", af);
  }
}
Пример #3
0
int
ipv6cp_PushPacket(struct ipv6cp *ipv6cp, struct link *l)
{
  struct bundle *bundle = ipv6cp->fsm.bundle;
  struct mqueue *queue;
  struct mbuf *bp;
  int m_len;
  u_int32_t secs = 0;
  unsigned alivesecs = 0;

  if (ipv6cp->fsm.state != ST_OPENED)
    return 0;

  /*
   * If ccp is not open but is required, do nothing.
   */
  if (l->ccp.fsm.state != ST_OPENED && ccp_Required(&l->ccp)) {
    log_Printf(LogPHASE, "%s: Not transmitting... waiting for CCP\n", l->name);
    return 0;
  }

  queue = ipv6cp->Queue + IPV6CP_QUEUES(ipv6cp) - 1;
  do {
    if (queue->top) {
      bp = m_dequeue(queue);
      bp = mbuf_Read(bp, &secs, sizeof secs);
      bp = m_pullup(bp);
      m_len = m_length(bp);
      if (!FilterCheck(MBUF_CTOP(bp), AF_INET6, &bundle->filter.alive,
                       &alivesecs)) {
        if (secs == 0)
          secs = alivesecs;
        bundle_StartIdleTimer(bundle, secs);
      }
      link_PushPacket(l, bp, bundle, 0, PROTO_IPV6);
      ipv6cp_AddOutOctets(ipv6cp, m_len);
      return 1;
    }
  } while (queue-- != ipv6cp->Queue);

  return 0;
}
Пример #4
0
/*
 * Ditch all queued packets.  This is usually done after our choked timer
 * has fired - which happens because we couldn't send any traffic over
 * any links for some time.
 */
void
ncp_DeleteQueues(struct ncp *ncp)
{
#ifndef NOINET6
  struct ipv6cp *ipv6cp = &ncp->ipv6cp;
#endif
  struct ipcp *ipcp = &ncp->ipcp;
  struct mp *mp = &ncp->mp;
  struct mqueue *q;

  for (q = ipcp->Queue; q < ipcp->Queue + IPCP_QUEUES(ipcp); q++)
    while (q->top)
      m_freem(m_dequeue(q));

#ifndef NOINET6
  for (q = ipv6cp->Queue; q < ipv6cp->Queue + IPV6CP_QUEUES(ipv6cp); q++)
    while (q->top)
      m_freem(m_dequeue(q));
#endif

  link_DeleteQueue(&mp->link);	/* Usually empty anyway */
}