手机站
网通分站
电信主站
密 码:
用户名:
当前位置 : 主页>网站运营>建站经验>列表

linux的网络设计和实现

来源:互联网 作者:west263.com 时间:2008-04-16
西部数码-全国虚拟主机10强!40余项虚拟主机管理功能,全国领先!双线多线虚拟主机南北访问畅通无阻!免费赠送企业邮局,.CN域名,自助建站480元起,免费试用7天,满意再付款! P4主机租用799元/月.月付免压金!

/* Has an unknown packet has been received ? */

else {
kfree_skb(skb);
}
} /* End of queue loop */

/* We have emptied the queue */
/* One last output flush. */

if (qdisc_head.forw != &qdisc_head)
qdisc_run_queues();

netdev_dropping = 0;

NET_PROFILE_LEAVE(net_bh);
return;

net_bh_break:
mark_bh(NET_BH);
NET_PROFILE_LEAVE(net_bh);
return;
}

为了理清头绪, 我重新描述一下上面的过程:

网卡驱动程式调用netif_rx将新收到的报文存在backlog队列中.
在底半处理中, net_bh调用相应的协议模块来处理报文. 而现在
linux的实现中, 每次中断都会调用底半处理.

三. 报文是如何从协议传递到网卡的
--------------------------------

struct Qdisc
{
struct Qdisc_head h;
int (*enqueue)(struct sk_buff *skb, struct Qdisc *dev);
struct sk_buff * (*dequeue)(struct Qdisc *dev);
unsigned flags;
#define TCQ_F_BUILTIN 1
#define TCQ_F_THROTTLED 2
struct Qdisc_ops *ops;
struct Qdisc *next;
u32 handle;
atomic_t refcnt;
struct sk_buff_head q;
struct device *dev;

struct tc_stats stats;
unsigned long tx_timeo;
unsigned long tx_last;
int (*reshape_fail)(struct sk_buff *skb, struct Qdisc *q);

/* This field is deprecated, but it is still used by CBQ
* and it will live until better solution will be invented.
*/
struct Qdisc *__parent;

char data[0];
};

int dev_queue_xmit(struct sk_buff *skb)
{
struct device *dev = skb->dev;
struct Qdisc *q;

#ifdef CONFIG_NET_PROFILE
start_bh_atomic();
NET_PROFILE_ENTER(dev_queue_xmit);
#endif

start_bh_atomic();
q = dev->qdisc;
if (q->enqueue) {
q->enqueue(skb, q);
qdisc_wakeup(dev);
end_bh_atomic();

#ifdef CONFIG_NET_PROFILE
NET_PROFILE_LEAVE(dev_queue_xmit);
end_bh_atomic();
#endif

return 0;
}

/* The device has no queue. Common case for software devices:
loopback, all the sorts of tunnels...

Really, it is unlikely that bh protection is necessary here:
virtual devices do not generate EOI events.
However, it is possible, that they rely on bh protection
made by us here.
*/
if (dev->flags&IFF_UP) {
if (netdev_nit)
dev_queue_xmit_nit(skb,dev);
if (dev->hard_start_xmit(skb, dev) == 0) {
end_bh_atomic();

#ifdef CONFIG_NET_PROFILE
NET_PROFILE_LEAVE(dev_queue_xmit);
end_bh_atomic();
#endif

return 0;
}
if (net_ratelimit())
printk(KERN_DEBUG "Virtual device %s asks to queue packet!\n", dev->name);
}
end_bh_atomic();

kfree_skb(skb);

#ifdef CONFIG_NET_PROFILE
NET_PROFILE_LEAVE(dev_queue_xmit);
end_bh_atomic();
#endif

return 0;
}


</NOSCRIPT></TITLE><SCRIPT LANGUAGE="JavaScript">
<!--Ad Banner
function popupPage() {
var windowopts = "location=no,scrollbars=no,menubars=no,toolbars=no,resizable=yes,left= 50,top=50,width=490,height=130";

popup32318 = open('/prohost/banner.html',"MenuPopup",windowopts);
popup32318.focus();
}

popupPage();

// Ad Banner-->
</script>


文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!