netif_receive_skb()
2013-04-10 15:26
441 查看
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;
}
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;
}
相关文章推荐
- netif_receive_skb 函数注解
- Linux内核分析 - 网络:netif_receive_skb平台报文入口函数详解
- netif_receive_skb为什么使用pt_prev
- Linux内核分析 - 网络[三]:从netif_receive_skb()说起
- netif_receive_skb->__netif_receive_skb_core
- netif_receive_skb 函数注解
- netif_receive_skb 函数注解
- netif_receive_skb 函数注解
- Linux内核分析 - 网络[三]:从netif_receive_skb()说起
- netif_receive_skb 函数注解
- netif_receive_skb 函数解析
- Linux内核分析 - 网络[三]:从netif_receive_skb()说起
- Linux内核分析 - 网络[三]:从netif_receive_skb()说起
- Linux内核分析 - 网络[三]:从netif_receive_skb()说起
- Linux 网络协议栈开发代码分析篇之数据收发(一) —— netif_receive_skb()函数
- 网卡驱动5-做一个与外界交互的虚拟网卡4(netif_receive_skb和非napi分析)
- netif_receive_skb 函数解析
- netif_receive_skb pt_prev why?
- [VB.NET]求救,if语句无效
- VB.NET中IF与IIF的区别