示例#1
0
int
pppoutput(struct ifnet *ifp, struct mbuf *m0, struct sockaddr *dst,
	  struct rtentry *rtp)
{
	int error;

	ifnet_serialize_tx(ifp);
	error = pppoutput_serialized(ifp, m0, dst, rtp);
	ifnet_deserialize_tx(ifp);

	return error;
}
示例#2
0
static int
ng_iface_output(struct ifnet *ifp, struct mbuf *m,
		struct sockaddr *dst, struct rtentry *rt0)
{
	const struct ifaltq_subque *ifsq = ifq_get_subq_default(&ifp->if_snd);
	int error;

	ifnet_serialize_tx(ifp, ifsq);
	error = ng_iface_output_serialized(ifp, m, dst, rt0);
	ifnet_deserialize_tx(ifp, ifsq);

	return error;
}
示例#3
0
void
vlan_start_dispatch(netmsg_t msg)
{
	struct netmsg_packet *nmp = &msg->packet;
	struct mbuf *m;
	struct ifnet *ifp;
	struct altq_pktattr pktattr;

	m = nmp->nm_packet;
	ifp = msg->lmsg.u.ms_resultp;

	M_ASSERTPKTHDR(m);
	KASSERT(m->m_flags & M_VLANTAG, ("mbuf has not been vlan tagged!"));

	ifnet_serialize_tx(ifp);

	/*
	 * Make sure that the interface is still UP and RUNNING,
	 * since interface state may have been changed when the
	 * mbuf is pending on the msgport.
	 */
	if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) !=
	    (IFF_UP | IFF_RUNNING)) {
		m_freem(m);
		goto back;
	}

	/*
	 * If ALTQ is enabled on the parent interface, do
	 * classification; the queueing discipline might
	 * not require classification, but might require
	 * the address family/header pointer in the pktattr.
	 */
	if (ifq_is_enabled(&ifp->if_snd))
		altq_etherclassify(&ifp->if_snd, m, &pktattr);

	/*
	 * If underlying interface can do VLAN tag insertion itself,
	 * just pass the packet along.
	 */
	if ((ifp->if_capenable & IFCAP_VLAN_HWTAGGING) == 0) {
		uint16_t vlantag = m->m_pkthdr.ether_vlantag;
		struct ether_vlan_header *evl;

		M_PREPEND(m, EVL_ENCAPLEN, MB_DONTWAIT);
		if (m == NULL) {
			if_printf(ifp, "vlan%u M_PREPEND failed", vlantag);
			goto back;
		}
		/* M_PREPEND takes care of m_len, m_pkthdr.len for us */

		m = m_pullup(m, ETHER_HDR_LEN + EVL_ENCAPLEN);
		if (m == NULL) {
			if_printf(ifp, "vlan%u m_pullup failed", vlantag);
			goto back;
		}
		m->m_pkthdr.csum_lhlen = sizeof(struct ether_vlan_header);

		/*
		 * Transform the Ethernet header into an Ethernet header
		 * with 802.1Q encapsulation.
		 */
		bcopy(mtod(m, char *) + EVL_ENCAPLEN, mtod(m, char *),
		      sizeof(struct ether_header));
		evl = mtod(m, struct ether_vlan_header *);
		evl->evl_proto = evl->evl_encap_proto;
		evl->evl_encap_proto = htons(ETHERTYPE_VLAN);
		evl->evl_tag = htons(vlantag);
#ifdef DEBUG
		kprintf("vlan_start: %*D\n", (int)sizeof *evl,
			(unsigned char *)evl, ":");
#endif
		/* Hardware does not need to setup vlan tagging */
		m->m_flags &= ~M_VLANTAG;
	}