Ejemplo n.º 1
0
static int loopback_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
	struct net_private *np = netdev_priv(dev);

	if (!skb_remove_foreign_references(skb)) {
		np->stats.tx_dropped++;
		dev_kfree_skb(skb);
		return 0;
	}

	dst_release(skb->dst);
	skb->dst = NULL;

	skb_orphan(skb);

	np->stats.tx_bytes += skb->len;
	np->stats.tx_packets++;

	/* Switch to loopback context. */
	dev = np->loopback_dev;
	np  = netdev_priv(dev);

	np->stats.rx_bytes += skb->len;
	np->stats.rx_packets++;

	if (skb->ip_summed == CHECKSUM_HW) {
		/* Defer checksum calculation. */
		skb->proto_csum_blank = 1;
		/* Must be a local packet: assert its integrity. */
		skb->proto_data_valid = 1;
	}

	skb->ip_summed = skb->proto_data_valid ?
		CHECKSUM_UNNECESSARY : CHECKSUM_NONE;

	skb->pkt_type = PACKET_HOST; /* overridden by eth_type_trans() */
	skb->protocol = eth_type_trans(skb, dev);
	skb->dev      = dev;
	dev->last_rx  = jiffies;

	/* Flush netfilter context: rx'ed skbuffs not expected to have any. */
	nf_reset(skb);
	secpath_reset(skb);

	netif_rx(skb);

	return 0;
}
Ejemplo n.º 2
0
static int queue_enqueue(struct sk_buff *skb, struct Qdisc* sch)
{
    struct queue_sched_data *q = qdisc_priv(sch);

    if (likely(sch->qstats.backlog + skb->len <= FIFO_BUF))
    {
        if (!q->stop)
            q->stop = skb;

        if (!skb_remove_foreign_references(skb)) {
            printk("error removing foreign ref\n");
            return qdisc_reshape_fail(skb, sch);
        }

        return qdisc_enqueue_tail(skb, sch);
    }
    printk("queue reported full: %d,%d\n", sch->qstats.backlog, skb->len);

    return qdisc_reshape_fail(skb, sch);
}