示例#1
0
int iavc_send(capi_softc_t *capi_sc, struct mbuf *m)
{
    iavc_softc_t *sc = (iavc_softc_t*) capi_sc->ctx;

    if (sc->sc_state != IAVC_UP) {
	printf("iavc%d: attempt to send before device up\n", sc->sc_unit);

	if (m->m_next) i4b_Bfreembuf(m->m_next);
	i4b_Dfreembuf(m);

	return (ENXIO);
    }

    if (_IF_QFULL(&sc->sc_txq)) {
#if defined (__FreeBSD__) && __FreeBSD__ > 4
	_IF_DROP(&sc->sc_txq);
#else
	IF_DROP(&sc->sc_txq);
#endif

	printf("iavc%d: tx overflow, message dropped\n", sc->sc_unit);

	if (m->m_next) i4b_Bfreembuf(m->m_next);
	i4b_Dfreembuf(m);

    } else {
	_IF_ENQUEUE(&sc->sc_txq, m);

	iavc_start_tx(sc);
    }
    
    return 0;
}
示例#2
0
/*
 * Start output on the pflog interface.
 */
void
pflogstart(struct ifnet *ifp)
{
	struct mbuf *m;
#ifndef __FreeBSD__
	int s;
#endif

	for (;;) {
#ifdef __FreeBSD__
		IF_LOCK(&ifp->if_snd);
		_IF_DROP(&ifp->if_snd);
		_IF_DEQUEUE(&ifp->if_snd, m);
		IF_UNLOCK(&ifp->if_snd);
#else
		s = splnet();
		IF_DROP(&ifp->if_snd);
		IF_DEQUEUE(&ifp->if_snd, m);
		splx(s);
#endif

		if (m == NULL)
			return;
		else
			m_freem(m);
	}
}
示例#3
0
文件: if_pflog.c 项目: coyizumi/cs111
/*
 * Start output on the pflog interface.
 */
static void
pflogstart(struct ifnet *ifp)
{
	struct mbuf *m;

	for (;;) {
		IF_LOCK(&ifp->if_snd);
		_IF_DROP(&ifp->if_snd);
		_IF_DEQUEUE(&ifp->if_snd, m);
		IF_UNLOCK(&ifp->if_snd);

		if (m == NULL)
			return;
		else
			m_freem(m);
	}
}
示例#4
0
文件: udbp.c 项目: MarginC/kame
/*
 * Accept data from the hook and queue it for output.
 */
Static int
ng_udbp_rcvdata(hook_p hook, item_p item)
{
	const udbp_p sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
	int error;
	struct ifqueue	*xmitq_p;
	int	s;
	struct mbuf *m;
	meta_p meta;

	NGI_GET_M(item, m);
	NGI_GET_META(item, meta);
	NG_FREE_ITEM(item);
	/* 
	 * Now queue the data for when it can be sent
	 */
	if (meta && meta->priority > 0) {
		xmitq_p = (&sc->xmitq_hipri);
	} else {
		xmitq_p = (&sc->xmitq);
	}
	s = splusb();
	IF_LOCK(xmitq_p);
	if (_IF_QFULL(xmitq_p)) {
		_IF_DROP(xmitq_p);
		IF_UNLOCK(xmitq_p);
		splx(s);
		error = ENOBUFS;
		goto bad;
	}
	_IF_ENQUEUE(xmitq_p, m);
	IF_UNLOCK(xmitq_p);
	if (!(sc->flags & OUT_BUSY))
		udbp_setup_out_transfer(sc);
	splx(s);
	return (0);

bad:	/*
         * It was an error case.
	 * check if we need to free the mbuf, and then return the error
	 */
	NG_FREE_M(m);
	NG_FREE_META(meta);
	return (error);
}
示例#5
0
static int
ng_bt3c_rcvdata(hook_p hook, item_p item)
{
	bt3c_softc_p	 sc = (bt3c_softc_p)NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
	struct mbuf	*m = NULL;
	int		 error = 0;

	if (sc == NULL) {
		error = EHOSTDOWN;
		goto out;
	}

	if (hook != sc->hook) {
		error = EINVAL;
		goto out;
	}

	NGI_GET_M(item, m);

	IF_LOCK(&sc->outq);
	if (_IF_QFULL(&sc->outq)) {
		NG_BT3C_ERR(sc->dev,
"Outgoing queue is full. Dropping mbuf, len=%d\n", m->m_pkthdr.len);

		_IF_DROP(&sc->outq);
		NG_BT3C_STAT_OERROR(sc->stat);

		NG_FREE_M(m);
	} else 
		_IF_ENQUEUE(&sc->outq, m);
	IF_UNLOCK(&sc->outq);

	error = ng_send_fn(sc->node, NULL, bt3c_send, NULL, 0 /* new send */);
out:
        NG_FREE_ITEM(item);

	return (error);
} /* ng_bt3c_rcvdata */
示例#6
0
文件: ip_gre.c 项目: MarginC/kame
static int
gre_input2(struct mbuf *m ,int hlen, u_char proto)
{
	struct greip *gip = mtod(m, struct greip *);
	int s;
	struct ifqueue *ifq;
	struct gre_softc *sc;
	u_short flags;

	if ((sc = gre_lookup(m, proto)) == NULL) {
		/* No matching tunnel or tunnel is down. */
		return (0);
	}

	sc->sc_if.if_ipackets++;
	sc->sc_if.if_ibytes += m->m_pkthdr.len;

	switch (proto) {
	case IPPROTO_GRE:
		hlen += sizeof (struct gre_h);

		/* process GRE flags as packet can be of variable len */
		flags = ntohs(gip->gi_flags);

		/* Checksum & Offset are present */
		if ((flags & GRE_CP) | (flags & GRE_RP))
			hlen += 4;
		/* We don't support routing fields (variable length) */
		if (flags & GRE_RP)
			return(0);
		if (flags & GRE_KP)
			hlen += 4;
		if (flags & GRE_SP)
			hlen +=4;

		switch (ntohs(gip->gi_ptype)) { /* ethertypes */
		case ETHERTYPE_IP: /* shouldn't need a schednetisr(), as */
		case WCCP_PROTOCOL_TYPE: /* we are in ip_input */
			ifq = &ipintrq;
			break;
#ifdef NS
		case ETHERTYPE_NS:
			ifq = &nsintrq;
			schednetisr(NETISR_NS);
			break;
#endif
#ifdef NETATALK
		case ETHERTYPE_ATALK:
			ifq = &atintrq1;
			schednetisr(NETISR_ATALK);
			break;
#endif
		case ETHERTYPE_IPV6:
			/* FALLTHROUGH */
		default:	   /* others not yet supported */
			return(0);
		}
		break;
	default:
		/* others not yet supported */
		return(0);
	}

	m->m_data += hlen;
	m->m_len -= hlen;
	m->m_pkthdr.len -= hlen;

	if (sc->sc_if.if_bpf) {
		struct mbuf m0;
		u_int32_t af = AF_INET;

		m0.m_next = m;
		m0.m_len = 4;
		m0.m_data = (char *)⁡

		BPF_MTAP(&(sc->sc_if), &m0);
	}

	m->m_pkthdr.rcvif = &sc->sc_if;

	s = splnet();		/* possible */
	if (_IF_QFULL(ifq)) {
		_IF_DROP(ifq);
		m_freem(m);
	} else {
		IF_ENQUEUE(ifq,m);
	}
	splx(s);

	return(1);	/* packet is done, no further processing needed */
}
示例#7
0
static void
bt3c_receive(bt3c_softc_p sc)
{
	u_int16_t	i, count, c;

	/* Receive data from the card */
	bt3c_read(sc, 0x7006, count);
	NG_BT3C_INFO(sc->dev, "The card has %d characters\n", count);

	bt3c_set_address(sc, 0x7480);

	for (i = 0; i < count; i++) {
		/* Allocate new mbuf if needed */
		if (sc->m == NULL) {
			sc->state = NG_BT3C_W4_PKT_IND;
			sc->want = 1;

			MGETHDR(sc->m, M_DONTWAIT, MT_DATA);
			if (sc->m == NULL) {
				NG_BT3C_ERR(sc->dev, "Could not get mbuf\n");
				NG_BT3C_STAT_IERROR(sc->stat);

				break; /* XXX lost of sync */
			}

			MCLGET(sc->m, M_DONTWAIT);
			if (!(sc->m->m_flags & M_EXT)) {
				NG_FREE_M(sc->m);

				NG_BT3C_ERR(sc->dev, "Could not get cluster\n");
				NG_BT3C_STAT_IERROR(sc->stat);

				break; /* XXX lost of sync */
			}

			sc->m->m_len = sc->m->m_pkthdr.len = 0;
		}

		/* Read and append character to mbuf */
		bt3c_read_data(sc, c);
		if (sc->m->m_pkthdr.len >= MCLBYTES) {
			NG_BT3C_ERR(sc->dev, "Oversized frame\n");
	
			NG_FREE_M(sc->m);
			sc->state = NG_BT3C_W4_PKT_IND;
			sc->want = 1;

			break; /* XXX lost of sync */
		}

		mtod(sc->m, u_int8_t *)[sc->m->m_len ++] = (u_int8_t) c;
		sc->m->m_pkthdr.len ++;

		NG_BT3C_INFO(sc->dev,
"Got char %#x, want=%d, got=%d\n", c, sc->want, sc->m->m_pkthdr.len);

		if (sc->m->m_pkthdr.len < sc->want)
			continue; /* wait for more */

		switch (sc->state) {
		/* Got packet indicator */
		case NG_BT3C_W4_PKT_IND:
			NG_BT3C_INFO(sc->dev,
"Got packet indicator %#x\n", *mtod(sc->m, u_int8_t *));

			sc->state = NG_BT3C_W4_PKT_HDR;

			/*
			 * Since packet indicator included in the packet 
			 * header just set sc->want to sizeof(packet header).
			 */

			switch (*mtod(sc->m, u_int8_t *)) {
			case NG_HCI_ACL_DATA_PKT:
				sc->want = sizeof(ng_hci_acldata_pkt_t);
				break;

			case NG_HCI_SCO_DATA_PKT:
				sc->want = sizeof(ng_hci_scodata_pkt_t);
				break;

			case NG_HCI_EVENT_PKT:
				sc->want = sizeof(ng_hci_event_pkt_t);
				break;

			default:
       	                	NG_BT3C_ERR(sc->dev,
"Ignoring unknown packet type=%#x\n", *mtod(sc->m, u_int8_t *));

				NG_BT3C_STAT_IERROR(sc->stat);

				NG_FREE_M(sc->m);
				sc->state = NG_BT3C_W4_PKT_IND;
				sc->want = 1;
				break;
			}
			break;

		/* Got packet header */
		case NG_BT3C_W4_PKT_HDR:
			sc->state = NG_BT3C_W4_PKT_DATA;

			switch (*mtod(sc->m, u_int8_t *)) {
			case NG_HCI_ACL_DATA_PKT:
				c = le16toh(mtod(sc->m,
					ng_hci_acldata_pkt_t *)->length);
				break;

			case NG_HCI_SCO_DATA_PKT:
				c = mtod(sc->m, ng_hci_scodata_pkt_t*)->length;
				break;

			case NG_HCI_EVENT_PKT:
				c = mtod(sc->m, ng_hci_event_pkt_t *)->length;
				break;

			default:
				KASSERT(0,
("Invalid packet type=%#x\n", *mtod(sc->m, u_int8_t *)));
				break;
       	        	 }

			NG_BT3C_INFO(sc->dev,
"Got packet header, packet type=%#x, got so far %d, payload size=%d\n",
				*mtod(sc->m, u_int8_t *), sc->m->m_pkthdr.len,
				c);

			if (c > 0) {
				sc->want += c;
				break;
			}

			/* else FALLTHROUGH and deliver frame */
			/* XXX is this true? should we deliver empty frame? */

		/* Got packet data */
		case NG_BT3C_W4_PKT_DATA:
			NG_BT3C_INFO(sc->dev,
"Got full packet, packet type=%#x, packet size=%d\n",
				*mtod(sc->m, u_int8_t *), sc->m->m_pkthdr.len);

			NG_BT3C_STAT_BYTES_RECV(sc->stat, sc->m->m_pkthdr.len);
			NG_BT3C_STAT_PCKTS_RECV(sc->stat);

			IF_LOCK(&sc->inq);
			if (_IF_QFULL(&sc->inq)) {
				NG_BT3C_ERR(sc->dev,
"Incoming queue is full. Dropping mbuf, len=%d\n", sc->m->m_pkthdr.len);

				_IF_DROP(&sc->inq);
				NG_BT3C_STAT_IERROR(sc->stat);

				NG_FREE_M(sc->m);
			} else {
				_IF_ENQUEUE(&sc->inq, sc->m);
				sc->m = NULL;
			}
			IF_UNLOCK(&sc->inq);

			sc->state = NG_BT3C_W4_PKT_IND;
			sc->want = 1;
			break;

		default:
			KASSERT(0,
("Invalid node state=%d", sc->state));
			break;
		}
	}

	bt3c_write(sc, 0x7006, 0x0000);
} /* bt3c_receive */