netif_receive_skb()

本文深入探讨了Linux内核2.6.19版本中netif_receive_skb函数的实现细节,该函数负责处理接收的数据包,并通过各种过滤器进行传递。文章详细介绍了如何根据设备类型和数据包类型将数据包传递给相应的处理程序。
process_backlog()  --> netif_receive_skb()

/usr/src/linux-2.6.19/net/core/dev.c

int netif_receive_skb(struct sk_buff *skb)
{
    struct  packet_type  *ptype, *pt_prev;
    struct  net_device  *orig_dev;
    int ret = NET_RX_DROP;
    unsigned short type;

    if (skb->dev->poll && netpoll_rx(skb))
        return NET_RX_DROP;
    if (!skb->tstamp.off_sec)
        net_timestamp(skb);
    if (!skb->input_dev)
        skb->input_dev = skb->dev;

    orig_dev = skb_bond(skb);
    if (!orig_dev)
        return NET_RX_DROP;

    __get_cpu_var(netdev_rx_stat).total++;
    skb->h.raw = skb->nh.raw = skb->data;
    skb->mac_len = skb->nh.raw - skb->mac.raw;
    pt_prev = NULL;
    rcu_read_lock();

#ifdef CONFIG_NET_CLS_ACT
    if (skb->tc_verd & TC_NCLS) {
        skb->tc_verd = CLR_TC_NCLS(skb->tc_verd);
        goto ncls;
    }
#endif

    list_for_each_entry_rcu(ptype, &ptype_all, list) {
        if (!ptype->dev || ptype->dev == skb->dev) {
            if (pt_prev)
                ret = deliver_skb(skb, pt_prev, orig_dev);
            pt_prev = ptype;
        }
    }

#ifdef CONFIG_NET_CLS_ACT
    if (pt_prev) {
        ret = deliver_skb(skb, pt_prev, orig_dev);
        pt_prev = NULL; 
    } else {
        skb->tc_verd = SET_TC_OK2MUNGE(skb->tc_verd);
    }
    ret = ing_filter(skb);    
    if (ret == TC_ACT_SHOT || (ret == TC_ACT_STOLEN)) {
        kfree_skb(skb);
        goto out;
    }
    skb->tc_verd = 0;
ncls:
#endif

    handle_diverter(skb);
    if (handle_bridge(&skb, &pt_prev, &ret, orig_dev))
        goto out;
    type = skb->protocol;

    list_for_each_entry_rcu(ptype, &ptype_base[ntohs(type)&15], list) {
        if (ptype->type == type &&
            (!ptype->dev || ptype->dev == skb->dev)) {
            if (pt_prev)
                ret = deliver_skb(skb, pt_prev, orig_dev);
            pt_prev = ptype;
        }
    }

    if (pt_prev) {
        ret =  pt_prev->func (skb, skb->dev, pt_prev, orig_dev);
    } else {
        kfree_skb(skb);
        ret = NET_RX_DROP;
    }

out:
    rcu_read_unlock();
    return ret;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值