static void CcpLayerFinish(struct fsm *fp) { /* We're now down */ struct ccp *ccp = fsm2ccp(fp); struct ccp_opt *next; log_Printf(LogCCP, "%s: LayerFinish.\n", fp->link->name); /* * Nuke options that may be left over from sending a REQ but never * coming up. */ while (ccp->out.opt) { next = ccp->out.opt->next; free(ccp->out.opt); ccp->out.opt = next; } if (ccp_Required(ccp)) { if (fp->link->lcp.fsm.state == ST_OPENED) log_Printf(LogLCP, "%s: Closing due to CCP completion\n", fp->link->name); fsm_Close(&fp->link->lcp.fsm); } }
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; }