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

linux的网络设计和实现

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


Higher Level Support Routines
-----------------------------

其中的sock_queue_rcv_skb() 用于处理接收到的数据并有流控处理. 他通常有下面的风格:

sk = my_find_socket(whatever);
if (sock_queue_rcv_skb(sk,skb) == -1) {
myproto_stats.dropped ;
kfree_skb(skb, FREE_READ);
return;
}

该函数会阻止大量的数据进入socket. 当到达一定的限度时, 数据会被抛弃.

在发送方, sock_alloc_send_skb() 用于处理一些标志, 如: 非阻塞等.

skb=sock_alloc_send_skb(sk,....)
if(skb == NULL)
return -err;
skb->sk = sk;
skb_reserve(skb, headroom);
skb_put(skb,len);
memcpy(skb->data, data, len);
protocol_do_something(skb);

比较重要的一行是 skb->sk = sk;
sock_alloc_send_skb() 改变了缓冲区指向的socket, 通过这一行我们告诉内核作
kfree_skb()时, 要有sk作确认. 这样, 当一个设备发送完一个包并且释放了他, 用户能够
继续发更多的包.


Network Devices
---------------

任何的linux网络设备使用相同的函数接口(面向对象的设计).
drivers/net/skeleton.c 包含了一个网络设备的轮廓.

Basic Structure
---------------

-------------------- -----------------------------
| dev_queue_xmit | | netif_rx receivers frames |
| delivers packets | | and queues them up. |
-------------------- -----------------------------
||||||| ||||||||
----------------------------------------------------------------
| Methods and Variables (struct device) |
----------------------------------------------------------------
||||||| ||||||
------------------ ------------------- ---------------------
| Initialisation | | hard_start_time | | mydev_interrupt |
| Routine | | delivers frames | | collects received |
------------------ ------------------- | frames |
||||||| ---------------------
||||||| ||||||
----------------------------------------------------------------
| Physical Device Media |
----------------------------------------------------------------


每个网络设备处理数据从协议层到物理介质的传输并从硬件上接收数据, 接收到的数据被放
到网络层, 由netif_rx()完成, 改函数去掉桢头以被高层协议使用.

每一个设备提供了以一套补充的方法来处理 停止, 开始, 控制和物理封装包.

Naming
------

任何的linux网络设备有唯一的名字, 实际上, 网络设备并没有一个对应的文档, 虽然您能够
自己建一个设备文档. 传统的, 名字标明的设备的类型而不是其制造商. 多个设备通过附加
的数字来标明(数字从零开始).


ethn
以太设备
trn
令牌环
sln
SLIP设备
pppn
PPP设备
plipn
PLIP单元
tunln
IPIP封装通道
nrn
NetROM 虚拟设备
isdnn
ISDN设备
dummyn
空设备
lo
本地回绕设备

Registering A Device
--------------------

每一个设备是通过添写一个 struct device 对象, 使用register_netdev(struct device *)
来注册. 他将您的struct device连入内核的网络设备表. 您不能够释放该结构, 直到, 您使
用 unregister_netdev(struct device *) 来释放该设备. 内核不支持多个设备使用同一个名
字, 假如您的程式是个模块, 您应该使用 struct device * dev_get(const char * name)
来确定这个名字是否被使用了, 假如是, 您应该另选一个名字或是失败.

一个典型的注册程式如下:

int register_my_device(void)
{
int i = 0;
for(i = 0;i < 100;i )
{
sprintf(mydevice.name, "mydev%d",i);
if(dev_get(mydevice.name) == NULL)
{
if(register_netdev(&mydevice) != 0)
return -EIO;
return 0;
}
}
printk("100 mydevs loaded. Unable to load more.\n");
return -ENFILE;
}

The Device Structure
--------------------

任何的一般性信息都放在 struct device 中, 为了创建一个设备您需要初始化他. 下面讨论
他的数据.

Naming
------

首先, name 包含了设备的名字, 这是个字符串指针, 也能够是四个空格, 这样内核会自动
分配一个ethn的名字, 但最好不要使用这一功能.

Bus Interface Parameters
------------------------

这一部分用于维护网络设备在物理上的一些参数.

Protocol Layer Variables
------------------------

关于协议层的一些数据. mtu等.

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

* 我个人的一些心得(仅供参考)

先来看一看网络部分是如何被初始化的. 下面是函数被调用的过程:

start_kernel -> init -> do_basic_setup -> sock_init -> proto-init
inet_proto_init -> ip_init -> dev_add_pack

下面的结构定义了网络协议的初始化入口:

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