Example #1
0
static void clip_push(struct atm_vcc *vcc, struct sk_buff *skb)
{
	struct clip_vcc *clip_vcc = CLIP_VCC(vcc);

	pr_debug("\n");

	if (!clip_devs) {
		atm_return(vcc, skb->truesize);
		kfree_skb(skb);
		return;
	}

	if (!skb) {
		pr_debug("removing VCC %p\n", clip_vcc);
		if (clip_vcc->entry)
			unlink_clip_vcc(clip_vcc);
		clip_vcc->old_push(vcc, NULL);	/* pass on the bad news */
		kfree(clip_vcc);
		return;
	}
	atm_return(vcc, skb->truesize);
	skb->dev = clip_vcc->entry ? clip_vcc->entry->neigh->dev : clip_devs;
	/* clip_vcc->entry == NULL if we don't have an IP address yet */
	if (!skb->dev) {
		dev_kfree_skb_any(skb);
		return;
	}
	ATM_SKB(skb)->vcc = vcc;
	skb_reset_mac_header(skb);
	if (!clip_vcc->encap ||
	    skb->len < RFC1483LLC_LEN ||
	    memcmp(skb->data, llc_oui, sizeof(llc_oui)))
		skb->protocol = htons(ETH_P_IP);
	else {
		skb->protocol = ((__be16 *)skb->data)[3];
		skb_pull(skb, RFC1483LLC_LEN);
		if (skb->protocol == htons(ETH_P_ARP)) {
			skb->dev->stats.rx_packets++;
			skb->dev->stats.rx_bytes += skb->len;
			clip_arp_rcv(skb);
			return;
		}
	}
	clip_vcc->last_use = jiffies;
	skb->dev->stats.rx_packets++;
	skb->dev->stats.rx_bytes += skb->len;
	memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data));
	netif_rx(skb);
}
Example #2
0
void clip_push(struct atm_vcc *vcc,struct sk_buff *skb)
{
    struct clip_vcc *clip_vcc = CLIP_VCC(vcc);

    DPRINTK("clip push\n");
    if (!skb)
    {
	clip_vcc_remove(clip_vcc);
	return;
    }
    atm_return(vcc, skb->truesize);
    skb->dev = clip_vcc->entry ? clip_vcc->entry->neigh->dev : clip_devs;
    /* clip_vcc->entry == NULL if we don't have an IP address yet */
    if (!skb->dev)
    {
	dev_kfree_skb_any(skb);
	return;
    }
    ATM_SKB(skb)->vcc = vcc;
    skb->mac.raw = skb->data;
    if (!clip_vcc->encap || skb->len < RFC1483LLC_LEN || memcmp(skb->data,
	llc_oui, sizeof(llc_oui))) skb->protocol = htons(ETH_P_IP);
    else
    {
	skb->protocol = ((u16 *) skb->data)[3];
	skb_pull(skb, RFC1483LLC_LEN);
	if (skb->protocol == htons(ETH_P_ARP))
	{
	    PRIV(skb->dev)->stats.rx_packets++;
	    PRIV(skb->dev)->stats.rx_bytes += skb->len;
	    clip_arp_rcv(skb);
	    return;
	}
    }
    clip_vcc->last_use = jiffies;
    PRIV(skb->dev)->stats.rx_packets++;
    PRIV(skb->dev)->stats.rx_bytes += skb->len;
    netif_rx(skb);
}