文档库 最新最全的文档下载
当前位置:文档库 › linux tcpip协议栈分析

linux tcpip协议栈分析

sk_buff结构可能是linux网络代码中最重要的数据结构,它表示接收或发送数据包的包头信息。它在

中定义,并包含很多成员变量供网络代码中的各子系统使用。

这个结构在linux内核的发展过程中改动过很多次,或者是增加新的选项,或者是重新组织已存在的成员变量以使得成员变量的布局更加清晰。它的成员变量可以大致分为以下几类:

?Layout 布局

?General 通用

?Feature-specific功能相关

?Management functions管理函数

这个结构被不同的网络层(MAC或者其他二层链路协议,三层的IP,四层的TCP或UDP等)使用,并且其中的成员变量在结构从一层向另一层传递时改变。L4向L3传递前会添加一个L4的头部,同样,L3向L2传递前,会添加一个L3的头部。添加头部比在不同层之间拷贝数据的效率更高。由于在缓冲区的头部添加数据意味着要修改指向缓冲区的指针,这是个复杂的操作,所以内核提供了一个函数skb_reserve (在后面的章节中描述)来完成这个功能。协议栈中的每一层在往下一层传递缓冲区前,第一件事就是调用skb_reserve在缓冲区的头部给协议头预留一定的空间。

skb_reserve同样被设备驱动使用来对齐接收到包的包头。如果缓冲区向上层协议传递,旧的协议层的头部信息就没什么用了。例如,L2的头部只有在网络驱动处理L2的协议时有用,L3是不会关心它的信息的。但是,内核并没有把L2的头部从缓冲区中删除,而是把有效荷载的指针指向L3的头部,这样做,可以节省CPU时间。

1. 网络参数和内核数据结构

就像你在浏览TCP/IP规范或者配置内核时所看到的一样,网络代码提供了很多有用的功能,但是这些功能并不是必须的,比如说,防火墙,多播,还有其他一些功能。大部分的功能都需要在内核数据结构中添加自己的成员变量。因此,sk_buff里面包含了很多像#ifdef这样的预编译指令。例如,在sk_buff结构的最后,你可以找到:

struct sk_buff {

... ... ...

#ifdef CONFIG_NET_SCHED

_ _u32 tc_index;

#ifdef CONFIG_NET_CLS_ACT

_ _u32 tc_verd;

_ _u32 tc_classid;

#endif

#endif

}

它表明,tc_index只有在编译时定义了CONFIG_NET_SCHED符号才有效。这个符号可以通过选择特定的编译选项来定义(例如:"Device Drivers Networking supportNetworking options QoS and/or

fair queueing")。这些编译选项可以由管理员通过make config来选择,或者通过一些自动安装工具来选择。

前面的例子有两个嵌套的选项:CONFIG_NET_CLS_ACT(包分类器)只有在选择支持“QoS and/or fair queueing”时才能生效。

顺便提一下,QoS选项不能被编译成内核模块。原因就是,内核编译之后,由某个选项所控制的数据结构是不能动态变化的。一般来说,如果某个选项会修改内核数据结构(比如说,在sk_buff

里面增加一个项tc_index),那么,包含这个选项的组件就不能被编译成内核模块。

你可能经常需要查找是哪个make config编译选项或者变种定义了某个#ifdef标记,以便理解内核中包含的某段代码。在2.6内核中,最快的,查找它们之间关联关系的方法,就是查找分布在内核源代码树中的kconfig文件中是否定义了相应的符号(每个目录都有一个这样的文件)。在

2.4内核中,你需要查看Documentation/Configure.help文件。

2. Layout Fields

有些sk_buff成员变量的作用是方便查找或者是连接数据结构本身。内核可以把sk_buff组织成一个双向链表。当然,这个链表的结构要比常见的双向链表的结构复杂一点。

就像任何一个双向链表一样,sk_buff中有两个指针next和prev,其中,next指向下一个节点,而prev指向上一个节点。但是,这个链表还有另一个需求:每个sk_buff结构都必须能够很快找到链表头节点。为了满足这个需求,在第一个节点前面会插入另一个结构sk_buff_head,这是一个辅助节点,它的定义如下:

struct sk_buff_head {

/* These two members must be first. */ struct sk_buff * next;

struct sk_buff * prev;

_ _u32 qlen;

spinlock_t lock;

};

qlen代表链表元素的个数。lock用于防止对链表的并发访问。

sk_buff和sk_buff_head的前两个元素是一样的:next和prev指针。这使得它们可以放到同一个链表中,尽管sk_buff_head要比sk_buff小得多。另外,相同的函数可以同样应用于sk_buff和

sk_buff_head。

为了使这个数据结构更灵活,每个sk_buff结构都包含一个指向sk_buff_head的指针。这个指针的名字是list。图1会帮助你理解它们之间的关系。

Figure 1. List of sk_buff elements

其他有趣的成员变量如下:

struct sock *sk

这是一个指向拥有这个sk_buff的sock结构的指针。这个指针在网络包由本机发出或者由本机进程接收时有效,因为插口相关的信息被L4(TCP或UDP)或者用户空间程序使用。如果sk_buff只在转发中使用(这意味着,源地址和目的地址都不是本机地址),这个指针是NULL。

unsigned int len

这是缓冲区中数据部分的长度。它包括主缓冲区中的数据长度(data指针指向它)和分片中的数据长度。它的值在缓冲区从一个层向另一个层传递时改变,因为往上层传递,旧的头部就没有用了,而往下层传递,需要添加本层的头部。len同样包含了协议头的长度。

unsigned int data_len

和len不同,data_len只计算分片中数据的长度。

unsigned int mac_len

这是mac头的长度。

atomic_t users

这是一个引用计数,用于计算有多少实体引用了这个sk_buff缓冲区。它的主要用途是防止释放sk_buff 后,还有其他实体引用这个sk_buff。因此,每个引用这个缓冲区的实体都必须在适当的时候增加或减小这个变量。这个计数器只保护sk_buff结构本身,而缓冲区的数据部分由类似的计数器(dataref)来保护. 有时可以用atomic_inc和atomic_dec函数来直接增加或减小users,但是,通常还是使用函数skb_get 和kfree_skb来操作这个变量。

unsigned int truesize

这是缓冲区的总长度,包括sk_buff结构和数据部分。如果申请一个len字节的缓冲区,alloc_skb函数会把它初始化成len+sizeof(sk_buff)。

struct sk_buff *alloc_skb(unsigned int size,int gfp_mask)

{

... ... ...

skb->truesize = size + sizeof(struct sk_buff);

... ... ...

}

当skb->len变化时,这个变量也会变化。

unsigned char *head

unsigned char *end

unsigned char *data

unsigned char *tail

它们表示缓冲区和数据部分的边界。在每一层申请缓冲区时,它会分配比协议头或协议数据大的空间。head 和end指向缓冲区的头部和尾部,而data和tail指向实际数据的头部和尾部,参见图2。每一层会在head 和data之间填充协议头,或者在tail和end之间添加新的协议数据。图2中右边数据部分会在尾部包含一个附加的头部。

Figure 2. head/end versus data/tail pointers

void (*destructor)(...)

这个函数指针可以初始化成一个在缓冲区释放时完成某些动作的函数。如果缓冲区不属于一个socket,这个函数指针通常是不会被赋值的。如果缓冲区属于一个socket,这个函数指针会被赋值为sock_rfree 或sock_wfree(分别由skb_set_owner_r或skb_set_owner_w函数初始化)。这两个sock_xxx函数用于更新socket的队列中的内存容量。

3. General Fields

本节描述sk_buff的主要成员变量,这些成员变量与特定的内核功能无关:

struct timeval stamp

这个变量只对接收到的包有意义。它代表包接收时的时间戳,或者有时代表包准备发出时的时间戳。它在netif_rx里面由函数net_timestamp设置,而netif_rx是设备驱动收到一个包后调用的函数。

struct net_device *dev

这个变量的类型是net_device,net_device它代表一个网络设备。dev的作用与这个包是准备发出的包还是刚接收的包有关。当收到一个包时,设备驱动会把sk_buff的dev指针指向收到这个包的设备的数据结构,就像下面的vortex_rx里的一段代码所做的一样,这个函数属于3c59x系列以太网卡驱动,用于接收一个帧。(drivers/net/3c59x.c):

static int vortex_rx(struct net_device *dev)

{

... ... ...

skb->dev = dev;

... ... ...

skb->protocol = eth_type_trans(skb, dev);

netif_rx(skb); /* Pass the packet to the higher layer

*/

... ... ...

}

当一个包被发送时,这个变量代表将要发送这个包的设备。在发送网络包时设置这个值的代码

要比接收网络包时设置这个值的代码复杂。有些网络功能可以把多个网络设备组成一个虚拟的

网络设备(也就是说,这些设备没有和物理设备直接关联),并由一个虚拟网络设备驱动管理。

当虚拟设备被使用时,dev指针指向虚拟设备的net_device结构。而虚拟设备驱动会在一组

设备中选择一个设备并把dev指针修改为这个设备的net_device结构。因此,在某些情况下,

指向传输设备的指针会在包处理过程中被改变。

struct net_device *input_dev

这是收到包的网络设备的指针。如果包是本地生成的,这个值为NULL。对以太网设备来说,这个值由eth_type_trans初始化,它主要被流量控制代码使用。

struct net_device *real_dev

这个变量只对虚拟设备有意义,它代表与虚拟设备关联的真实设备。例如,Bonding和VLAN设备都使用它来指向收到包的真实设备。

union {...} h

union {...} nh

union {...} mac

这些是指向TCP/IP各层协议头的指针:h指向L4,nh指向L3,mac指向L2。每个指针的

类型都是一个联合,包含多个数据结构,每一个数据结构都表示内核在这一层可以解析的协议。

例如,h是一个包含内核所能解析的L4协议的数据结构的联合。每一个联合都有一个raw变

量用于初始化,后续的访问都是通过协议相关的变量进行的。

当接收一个包时,处理n层协议头的函数从n-1层收到一个缓冲区,它的skb->data指向n

层协议的头。处理n层协议的函数把本层的指针(例如,L3对应的是skb->nh指针)初始化为

skb->data,因为这个指针的值会在处理下一层协议时改变(skb->data将被初始化成缓冲区

里的其他地址)。在处理n层协议的函数结束时,在把包传递给n+1层的处理函数前,它会把

skb->data指针指向n层协议头的末尾,这正好是n+1层协议的协议头(参见图3)。

发送包的过程与此相反,但是由于要为每一层添加新的协议头,这个过程要比接收包的过程复

杂。

Figure 3. Header's pointer initializations while moving from layer

two to layer three

struct dst_entry dst

这个变量在路由子系统中使用。

char cb[40]

这是一个“control buffer”,或者说是一个私有信息的存储空间,由每一层自己维护并使用。它在分配

sk_buff结构时分配(它目前的大小是40字节,已经足够为每一层存储必要的私有信息了)。在每一层中,访问这个变量的代码通常用宏实现以增强代码的可读性。例如,TCP用这个变量存储tcp_skb_cb结构,这个结构在include/net/tcp.h中定义:

struct tcp_skb_cb {

... ... ...

_ _u32 seq; /* Starting sequence number */

_ _u32 end_seq; /* SEQ + FIN + SYN + datalen*/

_ _u32 when; /* used to compute

rtt's */

_ _u8 flags; /* TCP header

flags. */

... ... ...

};

下面这个宏被TCP代码用来访问cb变量。在这个宏里面,有一个简单的类型转换:

#define TCP_SKB_CB(_ _skb) ((struct tcp_skb_cb *)&((_

_skb)->cb[0]))

下面的例子是TCP子系统在收到一个分段时填充相关数据结构的代码:

int tcp_v4_rcv(struct sk_buff *skb)

{

... ... ...

th = skb->h.th;

TCP_SKB_CB(skb)->seq = ntohl(th->seq);

TCP_SKB_CB(skb)->end_seq = (TCP_SKB_CB(skb)->seq +

th->syn + th->fin +

skb->len - th->doff * 4);

TCP_SKB_CB(skb)->ack_seq = ntohl(th->ack_seq);

TCP_SKB_CB(skb)->when = 0;

TCP_SKB_CB(skb)->flags = skb->nh.iph->tos;

TCP_SKB_CB(skb)->sacked = 0;

... ... ...

}

如果想要了解cb中的参数是如何被取出的,可以查看net/ipv4/tcp_output.c中的

tcp_transmit_skb函数。这个函数被TCP用于向IP层发送一个分段。

unsigned int csum

unsigned char ip_summed

表示校验和以及相关状态标记。

unsigned char cloned

一个布尔标记,当被设置时,表示这个结构是另一个sk_buff的克隆。在“克隆和拷贝缓冲区”一节中有描述。

unsigned char pkt_type

这个变量表示帧的类型,分类是由L2的目的地址来决定的。可能的取值都在include/linux/if_packet.h

中定义。对以太网设备来说,这个变量由eth_type_trans函数初始化。

类型的可能取值如下:

PACKET_HOST

包的目的地址与收到它的网络设备的L2地址相等。换句话说,这个包是发给本机的。

.PACKET_MULTICAST

包的目的地址是一个多播地址,而这个多播地址是收到这个包的网络设备所注册的多播地址。

PACKET_BROADCAST

包的目的地址是一个广播地址,而这个广播地址也是收到这个包的网络设备的广播地址。

PACKET_OTHERHOST

包的目的地址与收到它的网络设备的地址完全不同(不管是单播,多播还是广播),因此,如果

本机的转发功能没有启用,这个包会被丢弃。

PACKET_OUTGOING

这个包将被发出。用到这个标记的功能包括Decnet协议,或者是为每个网络tap都复制一份

发出包的函数。

PACKET_LOOPBACK

这个包发向loopback设备。由于有这个标记,在处理loopback设备时,内核可以跳过一些

真实设备才需要的操作。

PACKET_FASTROUTE

这个包由快速路由代码查找路由。快速路由功能在2.6内核中已经去掉了。

_ _u32 priority

这个变量描述发送或转发包的QoS类别。如果包是本地生成的,socket层会设置priority变量。如果包是将要被转发的,rt_tos2priority函数会根据ip头中的Tos域来计算赋给这个变量的值。这个变量的值与DSCP(DiffServ CodePoint)没有任何关系。

unsigned short protocol

这个变量是高层协议从二层设备的角度所看到的协议。典型的协议包括IP,IPV6和ARP。完整的列表在include/linux/if_ether.h中。由于每个协议都有自己的协议处理函数来处理接收到的包,因此,这个域被设备驱动用于通知上层调用哪个协议处理函数。每个网络驱动都调用netif_rx来通知上层网络协议的协议处理函数,因此protocol变量必须在这些协议处理函数调用之前初始化。

unsigned short security

这是包的安全级别。这个变量最初由IPSec子系统使用,但现在已经作废了。

4. Feature-Specific Fields

linux内核是模块化的,你可以选择包含或者删除某些功能。因此,sk_buff结构里面的一些成员变量只有在内核选择支持某些功能时才有效,比如防火墙(netfilter)或者qos:

unsigned long nfmark

_ _u32 nfcache

_ _u32 nfctinfo

struct nf_conntrack *nfct

unsigned int nfdebug

struct nf_bridge_info *nf_bridge

这些变量被netfilter使用(防火墙代码),内核编译选项是“Devic e Drivers->Networking support-> Networking options-> Network packet filtering”和两个子选项“Network packet filtering debugging”和“Bridged IP/ARP packets filtering”

union {...} private

这个联合结构被高性能并行接口(HIPPI)使用。相应的内核编译选项是“Device->Drivers ->Networking support ->Network device support ->HIPPI driver support”

_ _u32 tc_index

_ _u32 tc_verd

_ _u32 tc_classid

这些变量被流量控制代码使用,内核编译选项是“Device Drivers ->Networking->support

->Networking options ->QoS and/or fair queueing”和它的子选项“Packetclassifier API”

struct sec_path *sp

这个变量被IPSec协议用于跟踪传输的信息。

5. Management Functions

有很多函数,通常都比较短小而且简单,内核用这些函数操作sk_buff的成员变量或者sk_buff

链表。图4会帮助我们理解其中几个重要的函数。我们首先来看分配和释放缓冲区的函数,然后是一些通过移动指针在缓冲区的头部或尾部预留空间的函数。

如果你看过include/linux/skbuff.h和net/core/skbuff.c中的函数,你会发现,基本上每个函数都有两个版本,名字分别是do_something和__do_something。通常第一种函数是一个包装函数,它会在第二种函数的基础上增加合法性检查或者锁。一般来说,类似__do_something的函数不能被直接调用(除非满足特定的条件,比如说锁)。那些违反这条规则而直接引用这些函数的不良代码会最终被更正。

Figure 4. Before and after: (a)skb_put, (b)skb_push, (c)skb_pull, and

(d)skb_reserve

5.1. Allocating memory: alloc_skb and dev_alloc_skb

alloc_skb是net/core/skbuff.c里面定义的,用于分配缓冲区的函数。我们已经知道,数据缓冲区和缓冲区的描述结构(sk_buff结构)是两种不同的实体,这就意味着,在分配一个缓冲区时,需要分配两块内存(一个是缓冲区,一个是缓冲区的描述结构sk_buff)。

alloc_skb调用函数kmem_cache_alloc从缓存中获取一个sk_buff结构,并调用kmalloc分配缓冲区(如果有缓存的话,它同样从缓存中获取内存)。简化后的代码如下:

skb = kmem_cache_alloc(skbuff_head_cache, gfp_mask & ~_ _GFP_DMA); ... ... ...

size = SKB_DATA_ALIGN(size);

data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);

在调用kmalloc前,size参数通过SKB_DATA_ALIGN宏强制对齐。在函数返回前,它会初始化结构中的一些变量,最后的结构如图5所示。在图5右边所示的内存块的底部,你能看到对齐操作所带来的填充区域。

Figure 5. alloc_skb function

dev_alloc_skb也是一个缓冲区分配函数,它主要被设备驱动使用,通常用在中断上下文中。这是一个alloc_skb函数的包装函数,它会在请求分配的大小上增加16字节的空间以优化缓冲区的读写效率,它的分配要求使用原子操作(GFP_ATOMIC),这是因为它是在中断处理函数中被调用的。

static inline struct sk_buff *dev_alloc_skb(unsigned int length)

{

return _ _dev_alloc_skb(length, GFP_ATOMIC);

}

static inline

struct sk_buff *_ _dev_alloc_skb(unsigned int length, int gfp_mask) {

struct sk_buff *skb = alloc_skb(length + 16, gfp_mask);

if (likely(skb))

skb_reserve(skb, 16);

return skb;

}

如果没有体系架构相关的实现,缺省使用__dev_alloc_skb的实现。

5.2. Freeing memory: kfree_skb and dev_kfree_skb

这两个函数释放缓冲区,并把它返回给缓冲池(缓存)。kfree_skb可以直接调用,也可以通过包装函数dev_kfree_skb调用。后面这个函数一般被设备驱动使用,与之功能相反的函数是dev_alloc_skb。dev_kfree_skb仅是一个简单的宏,它什么都不做,只简单地调用kfree_skb。这些函数只有在

skb->users为1地情况下才释放内存(没有人引用这个结构)。否则,它只是简单地减小

skb->users。如果缓冲区有三个引用者,那么只有第三次调用dev_kfree_skb或kfree_skb时才释放内存。

图6中的流程图显示了分配一个缓冲区所需要的步骤。当sk_buff释放后,dst_release同样会被调用以减小相关dst_entry数据结构的引用计数。

如果destructor被初始化过,相应的函数会在此时被调用.

在图5中,我们看到,一个简单的场景是:一个sk_buff结构与另一个内存块相关,这个内存块里存储的是真正的数据。当然,内存块底部的skb_shared_info数据结构可以包含指向其他分片的指针(参见图5)。如果存在分片,kfree_skb同样会释放这些分片所占用的内存。最后,kfree_skb 把sk_buff结构返回给skbuff_head_cache缓存。

5.3. Data reservation and alignment: skb_reserve, skb_put, skb_push, and

skb_pull

skb_reserve可以在缓冲区的头部预留一定的空间,它通常被用来在缓冲区中插入协议头或者在某个边界上对齐。这个函数改变data和tail指针,而data和tail指针分别指向负载的开头和结尾,图4(d)展示了调用skb_reserve(skb,n)的结果。这个函数通常在分配缓冲区之后就调用,此时的

data和tail指针还是指向同一个地方。

如果你查看某个以太网设备驱动的收包函数(例如,drivers/net/3c59x.c中的vortex_rx),你就会发现它在分配缓冲区之后,在向缓冲区中填充数据之前,会调用下面的函数:

skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */

Figure 6. kfree_skb function

由于以太网帧的头部长度是14个八位组,这个函数把缓冲区的头部指针向后移动了2个字节。这样,紧跟在以太网头部之后的IP头部在缓冲区中存储时就可以在16字节的边界上对齐。如图7所示。

Figure 7. (a) be fore skb_reserve, (b) after skb_reserve, and (c) after

copying the frame on the buffer

图8展示了一个在发送过程中使用skb_reserve的例子。

Figure 8. Buffer that is filled in while traversing the stack from the TCP

layer down to the link layer

1.当TCP发送数据时,它根据一些条件分配一个缓冲区(比如,TCP的最大分段长度(mss),是否

支持散读散写I/O等

2.TCP在缓冲区的头部预留足够的空间(用skb_reserve)用于填充各层的头部(如TCP,IP,链

路层等)。MAX_TCP_HEADER参数是各层头部长度的总和,它考虑了最坏的情况:由于tcp

层不知道将要用哪个接口发送包,它为每一层预留了最大的头部长度。它甚至考虑了出现多个

IP头的可能性(如果内核编译支持IP over IP,我们就会遇到多个IP头的情况)。

3.把TCP的负载拷贝到缓冲区。需要注意的是:图8只是一个例子。TCP的负载可能会被组织成

其他形式。例如它可以存储到分片中。

4.TCP层添加自己的头部。

5.TCP层把缓冲区传递给IP层,IP层同样添加自己的头部。

6.IP层把缓冲区传递给邻居层,邻居层添加链路层头部。

当缓冲区在协议栈中向下层传递时,每一层都把skb->data指针向下移动,然后拷贝自己的头部,同时更新skb->len。这些操作都使用图4中所展示的函数完成。

skb_reserve函数并没有把数据移出或移入缓冲区,它只是简单地更新了缓冲区的两个指针,这两个指针在图4(d)中有描述。

static inline void skb_reserve(struct sk_buff *skb, unsigned int len) {

skb->data+=len;

skb->tail+=len;

}

skb_push在缓冲区的开头加入一块数据,而skb_put在缓冲区的末尾加入一块数据。与skb_reserve 类似,这些函数都不会真的往缓冲区中添加数据,相反,它们只是移动缓冲区的头指针和尾指针。数据由其他函数拷贝到缓冲区中。skb_pull通过把head指针往前移来在缓冲区的头部删除一块数据。图4展示了这些函数是如何工作的。

2.1.5.4. The skb_shared_info structure and the skb_shinfo function

如图5所示,在缓冲区数据的末尾,有一个数据结构skb_shared_info,它保存了数据块的附加信息。这个数据结构紧跟在end指针所指的地址之后(end指针指示数据的末尾)。下面是这个结构的定义:

struct skb_shared_info {

atomic_t dataref;

unsigned int nr_frags;

unsigned short tso_size;

unsigned short tso_seqs;

struct sk_buff *frag_list;

skb_frag_t frags[MAX_SKB_FRAGS];

};

dataref表示数据块的“用户”数,这个值在下一节(克隆和拷贝缓冲区)中有描述。nf_frags,frag_list和frags用于存储IP分片。skb_is_nonlinear函数用于测试一个缓冲区是否是分片的,而skb_linearize 可以把分片组合成一个单一的缓冲区。组合分片涉及到数据拷贝,它将严重影响系统性能。

有些网卡硬件可以完成一些传统上由CPU完成的任务。最常见的例子就是计算L3和L4校验和。有些网卡甚至可以维护L4协议的状态机。在下面的例子中,我们主要讨论TCP段卸载TCP segm entation offload,这些网卡实现了TCP层的一部分功能。tso_size和tso_seqs就在这种情况下使用。

需要注意的是:sk_buff中没有指向skb_shared_info结构的指针。如果要访问这个结构,就需要使用skb_info宏,这个宏简单地返回end指针:

#define skb_shinfo(SKB) ((struct skb_shared_info *)((SKB)->end))

下面的语句展示了如何使用这个宏来增加结构中的某个成员变量的值:

skb_shinfo(skb)->dataref++;

2.1.5.5. Cloning and copying buffers

如果一个缓冲区需要被不同的用户独立地操作,而这些用户可能会修改sk_buff中某些变量的值(比如h 和nh值),内核没有必要为每个用户复制一份完整的sk_buff以及相应的缓冲区。相反,为提高性能,内核克隆一个缓冲区。克隆过程只复制sk_buff结构,同时修改缓冲区的引用计数以避免共享的数据被提前释放。克隆缓冲区使用skb_clone函数。

一个使用包克隆的场景是:一个接收包的过程需要把这个包传递给多个接收者,例如包处理函数或者一个或多个网络模块。

被克隆的sk_buff不会放在任何链表中,同时也不会有到socket的引用。原始的和克隆的sk_buff中的skb->cloned值都被置为1。克隆包的skb->users值被置为1,这样,在释放时,可以先释放sk_buff 结构。同时,缓冲区的引用计数(dataref)增加1(因为有多个sk_buff结构指向它)。图9展示了克隆缓冲区的例子。

Figure 9. skb_clone function

skb_cloned函数可以用来测试skb的克隆状态。

图9展示了一个分片缓冲区的例子,这个缓冲区的一些数据保存在分片结构数组frags中。

skb_share_check用于检查引用计数skb->users,如果users变量表明skb是被共享的,则克隆一个新的sk_buff。

如果一个缓冲区被克隆了,这个缓冲区的内容就不能被修改。这就意味着,访问数据的函数没有必要加锁。因此,当一个函数不仅要修改sk_buff,而且要修改缓冲区内容时,就需要同时复制缓冲区。在这种情况下,程序员有两个选择。如果他知道所修改的数据在skb->start和skb->end

之间,他可以使用pskb_copy来复制这部分数据。如果他同时需要修改分片中的数据,他就必须使用skb_copy。图10展示了pskb_copy和skb_copy的结果。skb_shared_info结构也可以包含一个

sk_buff的链表(链表名称是frag_list)。这个链表在pskb_copy和skb_copy中的处理方式与frags数组的处理方式相同(图10忽略了frag_list)。

Figure 10. (a) pskb_copy function and (b) skb_copy function

在决定克隆或复制一个缓冲区时,子系统的程序员不能预测其他内核组件(其他子系统)是否需要使用缓冲区里的原始数据。内核是模块化的,它的状态变化是不可预测的,因此,每个子系统都不知道其他子系统是如何操作缓冲区的。因此,内核程序员需要记录它们对缓冲区的修改,并且在修改缓冲区前,复制一个新的缓冲区,以避免其他子系统在使用缓冲区的原始数据时出现错误。

2.1.5.6. List management functions

这些函数管理sk_buff的链表(也被称作队列)。在中有函数完整列表。以下是一些经常使用的函数:

skb_queue_head_init

初始化sk_buff_head结构,创建一个空队列。

skb_queue_head, skb_queue_tail

把一个缓冲区加入队列的头部或尾部。

skb_dequeue, skb_dequeue_tail

从队列的头部或尾部取下一个缓冲区。第一个函数的名字应该是skb_dequeue_head,以保持和其他函数的名字风格一致。

skb_queue_purge

清空一个队列。

skb_queue_walk

Runs a loop on each element of a queue in turn.

这些函数都是原子操作,它们必须先获取sk_buff_head中的自旋锁,然后才能访问队列中的元素。否则,它们有可能被其他异步的添加或删除操作打断,比如在定时器中调用的函数,这将导致链表出现错误而使得系统崩溃。

因此,每个函数的实现都采用下面这种形式:

static inline function_name ( parameter_list )

{

unsigned long flags;

spin_lock_irqsave(...);

_ _ _function_name ( parameter_list )

spin_unlock_irqrestore(...);

}

这些函数先获取锁,然后调用一个以两个下划线开头的同名函数(这个函数做具体的操作,而且不需要锁),然后释放锁。

Linux系统与网络管理试题09(试卷)

Linux系统与网络管理试卷 考试科目:Linux系统与网络管理试卷代号: B 适用对象:使用学期:2013-2014-1 共4道题总分100分共3页 考生须知: 1)姓名必须写在装订线左侧,其它位置一律作废。 2)请先检查是否缺页,如缺页应向监考教师声明,否则后果由考生负责。 3)答案一律写在答题纸上,可不抄题,但要标清题号。 监考须知:请将两份题签放在上层随答题纸一起装订。 一、填空题(20空,每空2分,共40分) 1.Linux与其他操作系统的最大区别是()。 2.swap交换空间,相当于Windows上的()如果计算机的内存为2GB,则一般需要将交换分区容量设置为()至()。 3.Linux的GNOME菜单的应用程序子菜单位相当于Windows的()菜单中的()。 4.group文件用于保存Linux中组的信息,每一行代表一个组的()数据。 5.Linux系统中文件的属性可以使用( )查看。 6.创建逻辑卷有多种方法,可以在系统安装时创建;也可以在系统安装好后用指令创建与管理,或者在桌面环境中,用()创建与管理。 7.httpd.conf文件中MinSpareThreads表示最小空闲线程数,默认值是()。这个MPM将基于整个服务器监视空闲线程数。如果服务器中总的空闲线程数太少,子进程将产生新的()线程。 8.执行( )命令查看nfs服务器可挂载的目录。 9.邮件服务器在工作时,发件人使用()撰写邮件,完成邮件编辑后进行提交。提交后()使用()协议,将邮件传给发件人所在域的()。 10.一台标准的SendMail服务器,需要安装包括()、()

Linux系统与网络管理 和()等服务器端软件,及()或其他MUA服务程序。 二、选择题(10小题,每小题2分,共20分) 1.UNIX是()操作系统。 A.单用户单任务B.多用户单任务 C.单用户多任务D.多用户多任务 2.()目录是定义Apache服务器站点存放目录; A./var B./var/www C./lib D./www 3.()不是Linux的GNOME桌面环境中“外观首选项”工具提供的配置桌面的各个外观的功能的选项卡。 A.主题B.背景 C.字体D.屏幕保护 4.如果不想退出普通用户,重新用root用户登录,就必须使用()命令切换到root。 A.su B.id C.who D.lastb 5.()命令是linux系统标准的进程查看工具,通过它可查看系统中进程的详细信息 A.ls B.Pstree C.ps D.Top 6.在使用物理RAID5方式工作时,至少需要()块硬盘。 A. 1 B. 2 C. 3 D. 4 7. 用于文件系统直接修改文件权限管理命令为:()。 A. chown B. chgrp C. chmod D. umask 8.Samba的主配置文件是(),默认位于/etc/samba/目录下。 A.smb.conf B.samba.conf C.smb.con D.samba.con

嵌入式TCP_IP协议栈说明书

嵌入式TCP_IP协议栈说明书 杨文斌 2008-9-1

一、总则 本文件是嵌入式TCP/IP协议栈的说明文件,嵌入式TCP/IP应用开发人员可通过阅读本文件,掌握在嵌入式TCP/IP协议栈的基础上开发服务器和客户端应用程序,如FTP服务器,WEB服务器,串口服务器等等。 二、参考文件 1)TCP_IP详解卷1,2,3 2)RFC 959 (rfc959) - File Transfer Protocol.htm 3)rfc1945- Hypertext Transfer Protocol -- HTTP/1.0 三、技术说明 1)用户应用协议栈则需要编写以太网的数据报收发驱动,就可以使用协议栈提供的标准SOCKET API,完成服务器和客户端应用程序的开发。 2)协议栈运行于非操作系统的环境下,因此它的运行速度与一般采用多任务操作系统的TCP/IP协 议,速度相对说来要快。 3)协议栈完成的功能包括ARP,IP,ICMP(ping),TCP,UDP,暂不支持IGMP,RARP。 4)协议栈采用C代码编写,可方便的移植于各种单片机平台。 5)协议栈在ARM7+RTL8019硬件环境下测试,并建立了FTP服务器和WEB服务器,性能稳定。 6)协议栈建立的FTP服务器和WEB服务器与Internet Explorer浏览器和ftp.exe相互兼容。 7)协议栈每一个SOCKET上建了数据缓冲队列(数据结构),用于接收SOCKET的并发数据,实现 多SOCKET的并发数据报处理,可同时运行FTP服务器和WEB服务器。 8)协议栈实现了ACK的延时答应(200ms),支持TCP多包发送和接收,但未支持TCP数据报的 失序处理,因此适合局域网内使用。 四、SOCKET API函数 1)函数SOCKET * socket(u16 af,u16 type,u16 protocol) 本函数功能是从SOCKET pool中分配一个SOCKET插口,供应用程序使用,其参数说明如下: 1.参数af,type—无意义,保留为扩充功能使用。 2.参数protocol—为分配SOCKET的类型,包括TCP_PROTOCOL和UDP_PROTOCOL两个 类型。 3.返回值:函数执行成功,返回SOCKET*指针指向一个SOCKET,失败返回NULL 2)函数u16 bind(SOCKET * sock,struct sockaddr * address,u8 len) 本函数功能是将IP地址和端口绑定到一个SOCKET 指针* sock指向的SOCKET。 1.SOCKET * sock—指向被绑定的SOCKET。 2.struct sockaddr * address—指向IP地址和端口。 3.len—无意义,保留为扩充功能使用。 4.返回值:SUCC。 3)函数u16 listen(SOCKET * sock, u16 QTY) 本函数功能是启动被绑定了地址和端口的SOCKET * sock,触发其为监听状态。本函数由服务 器端应用程序使用。 1.SOCKET * sock—指向被bind的SOCKET。 2.返回值:SUCC。 4)函数u16 connect(SOCKET * sock, struct sockaddr * sevaddr,u8 len) 本函数功能是用于建立一个连接到服务器,服务器的地址和端口由参数sevaddr指定。该函数由 客户端使用。 1.SOCKET * sock—指向被连接的本地SOCKET。 2.struct sockaddr * sevaddr,-- 服务器的地址和端口.

CycloneTCP协议栈移植与使用简介

Arda Technology Arda Tech P.F.FU 2014-12-19 Ver 0.1 #elif defined(USE_XXXXXX) #include "os_port_xxxxxx.h"

NicType type;//控制器类型。0:以太网接口,1:PPP接口,2:6LowPan接口 NicInit init;//控制器初始化函数指针 NicTick tick;//控制器周期性事务处理函数指针 NicEnableIrq enableIrq;//打开控制器中断函数指针 NicDisableIrq disableIrq;//关闭控制器中断函数指针 NicEventHandler eventHandler;//控制器中断响应函数指针,这个是下半段的中断处理部分。 NicSetMacFilter setMacFilter;//配置多播MAC地址过滤函数指针 NicSendPacket sendPacket;//发送包函数指针 NicWritePhyReg writePhyReg;//写PHY寄存器函数指针 NicReadPhyReg readPhyReg;//读PHY寄存器函数指针 bool_t autoPadding;//是否支持自动填充 bool_t autoCrcGen;//是否支持自动生成CRC校验码 bool_t autoCrcCheck;//是否支持自动检查CRC错误 NicSendControlFrame sendControlFrame;//发送控制帧函数指针 NicReceiveControlFrame receiveControlFrame;//接收控制帧函数指针 NicPurgeTxBuffer purgeTxBuffer;//清除发送缓冲函数指针 NicPurgeRxBuffer purgeRxBuffer;//清除接受缓存函数指针 xxxxEthInitGpio(...)//用于在init中初始化GPIO。 xxxxEthInitDmaDesc(...)//用于在init中初始化DMA任务描述符列表。 XXXX_Handler(...)//用于MAC中断的上半段处理。 xxxxEthReceivePacket(...)//用于在eventHandler中收包,把数据从dma的缓冲复制到外部缓冲。xxxxEthCalcCrc(...)//计算CRC值,这个函数基本上是固定的。 xxxxEthDumpPhyReg(...)//用于调试的打印PHY寄存器列表值。

Zigbee协议栈原理基础

1Zigbee协议栈相关概念 1.1近距离通信技术比较: 近距离无线通信技术有wifi、蓝牙、红外、zigbee,在无线传感网络中需求的网络通信恰是近距离需求的,故,四者均可用做无线传感网络的通信技术。而,其中(1)红外(infrared):能够包含的信息过少;频率低波衍射性不好只能视距通信;要求位置固定;点对点传输无法组网。(2)蓝牙(bluetooth):可移动,手机支持;通信距离10m;芯片价格贵;高功耗(3)wifi:高带宽;覆盖半径100m;高功耗;不能自组网;(4)zigbee:价格便宜;低功耗;自组网规模大。?????WSN中zigbee通信技术是最佳方案,但它连接公网需要有专门的网关转换→进一步学习stm32。 1.2协议栈 协议栈是网络中各层协议的总和,其形象的反映了一个网络中文件传输的过程:由上层协议到底层协议,再由底层协议到上层协议。 1.2.1Zigbee协议规范与zigbee协议栈 Zigbee各层协议中物理层(phy)、介质控制层(mac)规范由IEEE802.15.4规定,网络层(NWK)、应用层(apl)规范由zigbee联盟推出。Zigbee联盟推出的整套zigbee规范:2005年第一版ZigBeeSpecificationV1.0,zigbee2006,zigbee2007、zigbeepro zigbee协议栈:很多公司都有自主研发的协议栈,如TI公司的:RemoTI,Z-Stack,SimpliciTI、freakz、msstatePAN 等。 1.2.2z-stack协议栈与zigbee协议栈 z-stack协议栈与zigbee协议栈的关系:z-stack是zigbee协议栈的一种具体实现,或者说是TI公司读懂了zigbee 协议栈,自己用C语言编写了一个软件—---z-stack,是由全球几千名工程师共同开发的。ZStack-CC2530-2.3.1-1.4.0软件可与TI的SmartRF05平台协同工作,该平台包括MSP430超低功耗微控制器(MCU)、CC2520RF收发器以及CC2591距离扩展器,通信连接距离可达数公里。 Z-Stack中的很多关键的代码是以库文件的形式给出来,也就是我们只能用它们,而看不到它们的具体的实现。其中核心部分的代码都是编译好的,以库文件的形式给出的,比如安全模块,路由模块,和Mesh自组网模块。与z-stack 相比msstatePAN、freakz协议栈都是全部真正的开源的,它们的所有源代码我们都可以看到。但是由于它们没有大的商业公司的支持,开发升级方面,性能方面和z-stack相比差距很大,并没有实现商业应用,只是作为学术研究而已。 还可以配备TI的一个标准兼容或专有的网络协议栈(RemoTI,Z-Stack,或SimpliciTI)来简化开发,当网络节点要求不多在30个以内,通信距离500m-1000m时用simpliciti。 1.2.3IEEE802.15.4标准概述 IEEE802.15.4是一个低速率无线个人局域网(LowRateWirelessPersonalAreaNetworks,LR-WPAN)标准。定义了物理层(PHY)和介质访问控制层(MAC)。 LR-WPAN网络具有如下特点: ◆实现250kb/s,40kb/s,20kb/s三种传输速率。 ◆支持星型或者点对点两种网络拓扑结构。 ◆具有16位短地址或者64位扩展地址。 ◆支持冲突避免载波多路侦听技术(carriersensemultipleaccesswithcollisionavoidance,CSMA/CA)。(mac层) ◆用于可靠传输的全应答协议。(RTS-CTS) ◆低功耗。 ◆能量检测(EnergyDetection,ED)。 ◆链路质量指示(LinkQualityIndication,LQI)。 ◆在2.45GHz频带内定义了16个通道;在915MHz频带内定义了10个通道;在868MHz频带内定义了1个通道。 为了使供应商能够提供最低可能功耗的设备,IEEE(InstituteofElectricalandElectronicsEngineers,电气及电子工程师学会)定义了两种不同类型的设备:一种是完整功能设备(full.functionaldevice,FFD),另一种是简化功能设备

基于ARM的嵌入式TCPip协议的实现

基于ARM的嵌入式TCP/IP协议的实现 该系统可以将数据按网络协议处理,实现数据的以太网传输。其是一套基于嵌入式实时操作系统的嵌入式网络软件开发平台,即在μC/OS—II的平台上,实现ARM微处理器的TCP/IP协议,在此平台之上,可以方便地进行嵌入式应用系统的开发。 0 引言 以太网具有通用性强、技术成熟、带宽迅速增加等特性,工业控制领域出现嵌入式技术,尤其是ARM技术的发展和DSP在工业控制领域的广泛应用,利用嵌入式技术实现以太网通信已经不难见到。嵌入式实时操作系统接入网络后将使远程监测、远程控制、远程诊断和远程维护变得越来越容易。从根本上讲,嵌入式设备接入网络,当前基本采用基于TCP/IP的通信协议。该方案以LPC2210为核心元件研究基于ARM的嵌入式TCP/IP协议的实现的硬件电路,同时在μC/OS一Ⅱ平台上编写应用软件程序。下面对系统做详实的阐述,并重点介绍嵌入式实时操作系统μC/OS—II应用于TCP/IP时应进行合理的裁减。 1 系统硬件设计 基于ARM的嵌入式TCP/IP网络通信系统主要包括ARM芯片和以太网控制器等芯片组成的以太网接口、驱动软件和嵌入式TCP/IP 协议栈。硬件原理图如图1所示。

该方案设计相对简单,硬件电路中采用的LPC2210是Philips 公司推出的微处理器,带有16 KBRAM,76个通用I/O口,12个独立外部中断引脚,集成有8通道的10位A/D,能够基于芯片设计复杂的系统。虽然LPC2210具有较快的访问速度,但片内没有集成FLASH,所以这里扩展1片16 Mb FLASH SST39VFl60来保存用户程序。其架构满足μC/OS—II正常运行的基本要求。 RTL8019AS是台湾Realtek半导体公司生产的以太网控制器,其性能包括:支持EthernetII和IEEE802.3标准;支持8/16位数据总线;内置16 KWord的SRAM;全双工,收发同时达到10 Mb/s;支持BNC,AUI,UTP介质。RTLS019AS可提供100脚的TQFP封装,减少了PCB面积,更适合于嵌入式系统。HR901170A是汉仁电子有限公司生产的RJ45接口连接器(带网络变压器/滤波器),该连接器满足IEEES02.3和IEEE902.3ab标准,能够较好地抑制电磁干扰。通过HR901170A系统就可以连接到以太网上。

TCPIP协议栈实践报告

《专业综合实践》 训练项目报告训练项目名称:TCP/IP协议栈

1.IP协议 IP协议是TCP/IP协议的核心,所有的TCP,UDP,IMCP,IGCP的数据都以IP数据格式传输。要注意的是,IP不是可靠的协议,这是说,IP协议没有提供一种数据未传达以后的处理机制--这被认为是上层协议--TCP或UDP要做的事情。所以这也就出现了TCP是一个可靠的协议,而UDP就没有那么可靠的区别。这是后话,暂且不提 1.1.IP协议头如图所示

挨个解释它是教科书的活计,我感兴趣的只是那八位的TTL字段,还记得这个字段是做什么的么?这个字段规定该数据包在穿过多少个路由之后才会被抛弃(这里就体现出来IP协议包的不可靠性,它不保证数据被送达),某个ip数据包每穿过一个路由器,该数据包的TTL数值就会减少1,当该数据包的TTL成为零,它就会被自动抛弃。这个字段的最大值也就是255,也就是说一个协议包也就在路由器里面穿行255次就会被抛弃了,根据系统的不同,这个数字也不一样,一般是32或者是64,Tracerouter这个工具就是用这个原理工作的,tranceroute 的-m选项要求最大值是255,也就是因为这个TTL在IP协议里面只有8bit。 现在的ip版本号是4,所以也称作IPv4。现在还有IPv6,而且运用也越来越广泛了。 1.2.IP路由选择 当一个IP数据包准备好了的时候,IP数据包(或者说是路由器)是如何将数据包送到目的地的呢?它是怎么选择一个合适的路径来"送货"的呢? 最特殊的情况是目的主机和主机直连,那么主机根本不用寻找路由,直接把数据传递过去就可以了。至于是怎么直接传递的,这就要靠ARP协议了,后面会讲到。 稍微一般一点的情况是,主机通过若干个路由器(router)和目的主机连接。那么路由器就要通过ip包的信息来为ip包寻找到一个合适的目标来进行传递,比如合适的主机,或者合适的路由。路由器或者主机将会用如下的方式来处理某一个IP数据包 如果IP数据包的TTL(生命周期)以到,则该IP数据包就被抛弃。 搜索路由表,优先搜索匹配主机,如果能找到和IP地址完全一致的目标

Linux网络管理及应用课后习题参考答案

Linux 网络管理及应用 习题参考答案 第1章Linux网络操作系统 1.Linux的创始人是谁? 答:Linus Torvalds 2.Linux与Unix操作系统有什么关系? 答:Linux是一种类Unix操作系统,完全与POSIX标准兼容,是该标准的一种实现。 3.Linux与GNU项目是什么关系?它是开源软件吗?是自由软件吗? 答:Linux是一个操作系统内核,并不是一个完整的操作系统;GNU项目是面向开发一个操作系统,采用了Linux作为其系统内核。Linux遵守GNU GPL协议,是自由软件,同时它也是开源软件。 4.开源软件与自由软件有什么区别与联系? 答:自由软件指得是对于软件所拥有的“自由”的权利,包括三种自由;开源软件是一种软件开发方法,面向建立高质量软件。用户可以获得源代码是这两者共同之处。 5.安装Linux一般如何分区?选择哪种文件系统? 答:一般至少分为两个区:根文件系统分区和交换分区。根分区一般选择ext3格式的文件系统,交换分区采用swap格式。 6.Linux支持哪几种安装方式? 答:Linux支持多种安装方式:光盘、网络、本地磁盘等。 7.Linux系统中一个文件的全路径为/etc/passwd,表示了文件的哪些信息? 答:表示了文件的位置和文件的命名两部分信息。 8.什么是虚拟机?为什么要使用虚拟机? 答:虚拟机是利用软件虚拟技术虚拟一个计算机硬件环境的软件技术。使用虚拟机可以让一台高性能的计算机充分发挥其硬件的性能,提高系统的利用率;虚拟机也适合需要频繁更换使用不同操作系统的情况,如软件测试、教育等。 9.VMWare虚拟机中可以安装哪些操作系统? 答:可以安装微软Windows系列操作系统、Linux的多种发行版、MSDOS等许多操作系统。

ZigBee测试与协议分析

ZigBee测试与协议分析 1 前言 ZigBee协议栈包括物理层协议(IEEE802.15.4)和上层软件协议(ZigBee 2007以及其他的ZigBee网络协议)。本文将从这两方面来了解这些协议,通过介绍如何捕获及如何理解关键参数,深层次剖析ZigBee技术。有了这些本质性的认识,对于分析解决无线产品应用问题,会有很大的帮助。 2 物理层分析 ZigBee的物理层为IEEE802.15.4标准所规定,定义了ZigBee底层的调制编码方式。这些规约大多是芯片设计者需要关心的,对于应用开发来说,更关心的是衡量一个芯片、一个射频系统性能的参数。在过去的文章中,已介绍了输出功率、接收灵敏度和链路预算等参数,这一讲将更深入地介绍一个调制质量的参数:EVM。EVM指的是误差向量(包括幅度和相位的矢量),表征在一个给定时刻理想无误差基准信号与实际发射信号的向量差,。从EVM参数中,可以了解到一个输出信号的幅度误差及相位误差。 EVM是衡量一个RF系统总体调制质量的指标,定义为信号星座图上测量信号与理想信号之间的误差,它用来表示发射器的调制精度,调制解调器、PA、混频器、收发器等对它都会有影响。EVM数据和眼图。 了解完这个参数之后,再看看实际测试中是如何获取EVM参数的。 ZigBee物理层的测试,在产品研发、生产和维护阶段,可以分别采用不同的仪器。 (1)产品研发阶段要测量EVM参数,需要使用带协议解析的频谱仪,最好是自带相应协议插件的仪器,可以使用安捷伦PXA N9030A频谱分析仪+8960B插件(选配了ZigBee分析插件)。这些仪器可以测试出ZigBee调制信号的星座图、实时数据和眼图等信息,在芯片级开发过程中,需要考量高频电容电感以及滤波器等的单个及组合性能,特别需要注意的是ZigBee信号的临道抑制参数,利用PXA N9030A的高分辨率,可以查看点频的带外信号,这些细节在更换射频器件供应商时,需要仔细测量,一般数字电路抄板比较容易,因为器件性能的影响不是很大,只要值和封装对了就可以,但是射频前端的设计上,即使原样的封装、容值和感值,供应商不一样,射频参数也是不一样的,板材的选用也极大地影响着阻抗匹配,因此复制和再开发都有较大难度。合格的测试工具,加上有质量保证的射频器件供应商资源,方能真正具备RF设计能力。安捷伦PXA N9030A频谱分析仪。 (2)批量生产阶段在批量生产中,不可能将实验室的研发测试仪器搬到工厂,因此,需要便携小巧的测试设备,这时可用罗德与斯瓦茨公司的热功率探头,如NRP-Z22,做一个2.4 GHz的输出功率测试,保证能够输出公差允许的功率信号即可,因为在生产中,射频器件的焊接不良、馈线连接头的接触不良,都会造成输出功率的下降甚至消失。需要注意的是,探头非常容易被静电损坏,必须要带上防静电手套进行操作,返修过程如需要经过德国,则时间长,经费也不便宜,不是很严重的损坏倒是可以在深圳维修中心处理。NRP-Z22。 (3)应用阶段在现场出现问题时,ZigBee节点已经安装到现场,不能逐一拆下来测试,并且周围的电磁环境也是没办法在单个节点上检测到,这时就需要手持式的频谱仪进行现场勘查了,例如安捷伦公司的N9912A手持式频谱仪。使用该频谱仪,可以完成无线系统设计初期的现场勘查工作,检测现场各个地点是否有异常电磁干扰,对于ZigBee来说,当然是检测是否有持续的WIFI信号干扰了。同时,更为详细的现场勘查,还包括在定点进行数据发送,预期覆盖点进行信号强度分析,以实地评估墙体等障碍物的信号衰减,在已经架设好的ZigBee网络中,也可以检测信号覆盖,数据通信是否正常等。N9912A。

传统协议栈和DPDK

一、传统协议栈之数据包从NIC到内核 1、从NIC到内存 概括地说,网络数据包进入内存(接收数据包)的流程为: 网线--> Rj45网口--> MDI 差分线 --> bcm5461(PHY芯片进行数模转换) --> MII总线 --> TSEC的DMA Engine 会自动检查下一个可用的Rx bd -->把网络数据包DMA 到Rx bd所指向的内存,即skb->data

1、首先,内核在主内存中为收发数据建立一个环形的缓冲队列(通常叫DMA环形缓冲区)。 2、内核将这个缓冲区通过DMA映射,把这个队列交给网卡; 3、网卡收到数据,就直接放进这个环形缓冲区了——也就是直接放进主内存了;然后,向系统产生一个中断; 4、内核收到这个中断,就取消DMA映射,这样,内核就直接从主内存中读取数据; 对应以上4步,来看它的具体实现: 1、分配环形DMA缓冲区 Linux内核中,用skb来描述一个缓存,所谓分配,就是建立一定数量的skb,然后把它们组织成一个双向链表 2、建立DMA映射 内核通过调用dma_map_single(struct device *dev,void *buffer,size_tsize,enumdma_data_direction direction) 建立映射关系。 struct device *dev,描述一个设备;buffer:把哪个地址映射给设备;也就是某一个skb——要映射全部,当然是做一个双向链表的循环即可;size:缓存大小;direction:映射方向——谁传给谁:一般来说,是“双向”映射,数据在设备和内存之间双向流动;对于PCI设备而言(网卡一般是PCI的),通过另一个包裹函数pci_map_single,这样,就把buffer交给设备了!设备可以直接从里边读/取数据。 3、这一步由硬件完成; 4、取消映射 ma_unmap_single,对PCI而言,大多调用它的包裹函数pci_unmap_single,不取消的话,缓存控制权还在设备手里,要调用它,把主动权掌握在CPU手里——因为我们已经接收到数据了,应该由CPU把数据交给上层网络栈;当然,不取消之前,通常要读一些状态位信息,诸如此类,一般是调用dma_sync_single_for_cpu() 让CPU在取消映射前,就可以访问DMA

mtcp协议栈

mTCP:A Highly Scalable User-level TCP Stack for Multicore Systems EunYoung Jeong,Shinae Woo,Muhammad Jamshed,Haewon Jeong Sunghwan Ihm*,Dongsu Han,and KyoungSoo Park KAIST*Princeton University Abstract Scaling the performance of short TCP connections on multicore systems is fundamentally challenging.Although many proposals have attempted to address various short-comings,inef?ciency of the kernel implementation still persists.For example,even state-of-the-art designs spend 70%to80%of CPU cycles in handling TCP connections in the kernel,leaving only small room for innovation in the user-level program. This work presents mTCP,a high-performance user-level TCP stack for multicore systems.mTCP addresses the inef?ciencies from the ground up—from packet I/O and TCP connection management to the application inter-face.In addition to adopting well-known techniques,our design(1)translates multiple expensive system calls into a single shared memory reference,(2)allows ef?cient?ow-level event aggregation,and(3)performs batched packet I/O for high I/O ef?ciency.Our evaluations on an8-core machine showed that mTCP improves the performance of small message transactions by a factor of25compared to the latest Linux TCP stack and a factor of3compared to the best-performing research system known so far.It also improves the performance of various popular applications by33%to320%compared to those on the Linux stack. 1Introduction Short TCP connections are becoming widespread.While large content transfers(e.g.,high-resolution videos)con-sume the most bandwidth,short“transactions”1dominate the number of TCP?ows.In a large cellular network,for example,over90%of TCP?ows are smaller than32KB and more than half are less than4KB[45]. Scaling the processing speed of these short connec-tions is important not only for popular user-facing on-line services[1,2,18]that process small messages.It is 1We refer to a request-response pair as a transaction.These transac-tions are typically small in size.also critical for backend systems(e.g.,memcached clus-ters[36])and middleboxes(e.g.,SSL proxies[32]and redundancy elimination[31])that must process TCP con-nections at high speed.Despite recent advances in soft-ware packet processing[4,7,21,27,39],supporting high TCP transaction rates remains very challenging.For exam-ple,Linux TCP transaction rates peak at about0.3million transactions per second(shown in Section5),whereas packet I/O can scale up to tens of millions packets per second[4,27,39]. Prior studies attribute the inef?ciency to either the high system call overhead of the operating system[28,40,43] or inef?cient implementations that cause resource con-tention on multicore systems[37].The former approach drastically changes the I/O abstraction(e.g.,socket API) to amortize the cost of system calls.The practical lim-itation of such an approach,however,is that it requires signi?cant modi?cations within the kernel and forces ex-isting applications to be re-written.The latter one typically makes incremental changes in existing implementations and,thus,falls short in fully addressing the inef?ciencies. In this paper,we explore an alternative approach that de-livers high performance without requiring drastic changes to the existing code base.In particular,we take a clean-slate approach to assess the performance of an untethered design that divorces the limitation of the kernel implemen-tation.To this end,we build a user-level TCP stack from the ground up by leveraging high-performance packet I/O libraries that allow applications to directly access the packets.Our user-level stack,mTCP,is designed for three explicit goals: 1.Multicore scalability of the TCP stack. 2.Ease of use(i.e.,application portability to mTCP). 3.Ease of deployment(i.e.,no kernel modi?cations). Implementing TCP in the user level provides many opportunities.In particular,it can eliminate the expen-sive system call overhead by translating syscalls into inter-process communication(IPC).However,it also in-

linux网络操作系统和实训课后习题答案解析

练习题 一、选择题 1. Linux 最早是由计算机爱好者 B 开发的。 A. Richard Petersen B. Linus Torvalds C. Rob Pick D. Linux Sarwar 2. 下列 C 是自由软件。 A. Windows XP B. UNIX C. Linux D. Windows 2000 3. 下列 B 不是Linux 的特点。 A. 多任务 B. 单用户 C. 设备独立性 D. 开放性 4. Linux 的内核版本2.3.20 是 A 的版本。 A. 不稳定 B. 稳定的 C. 第三次修订 D. 第二次修订 二、填空题 1. GUN 的含义是:GNU's Not UNIX。 2. Linux 一般有3 个主要部分:内核(kernel)、命令解释层(Shell 或其他操作环境)、 实用工具。 三、简答题(略) 1. 简述Red Hat Linux 系统的特点。 2. 简述一些较为知名的Linux 发行版本。 练习题 一、选择题 1. Linux 安装过程中的硬盘分区工具是 D 。 A. PQmagic B. FDISK C. FIPS D. Disk Druid 2. Linux 的根分区系统类型是 C 。 A. FATl6 B. FAT32 C. ext3 D. NTFS 二、填空题 1. 安装Linux 最少需要两个分区,分别是 swap 交换分区和/(根)分区。 2. Linux 默认的系统管理员账号是 root 。 3. X-Window System 由三部分构成:X Server、X Client 和通信通道。 三、简答题(略) 1. Linux 有哪些安装方式 2. 安装Red Hat Linux 系统要做哪些准备工作 3. 安装Red Hat Linux 系统的基本磁盘分区有哪些 4. Red Hat Linux 系统支持的文件类型有哪些 练习题 一、选择题 1. C 命令能用来查找在文件TESTFILE 中包含四个字符的行 A. grep’’TESTFILE B. grep’….’TESTFILE C. grep’^$’TESTFILE D. grep’^….$’TESTFILE 2. B 命令用来显示/home 及其子目录下的文件名。 A. ls -a /home B. ls -R /home C. ls -l /home D. ls -d /home 3. 如果忘记了ls 命令的用法,可以采用 C 命令获得帮助 A. ls B. help ls C. man ls D. get ls 4. 查看系统当中所有进程的命令是 D 。 A. ps all B. ps aix C. ps auf D. ps aux

TI_zigbee协议栈结构分析应用

无线盛世《快速进入ZB世界》
Ver:1

进入Zigbee世界的准备工作
§ 首先,我们需具备一些硬件设备及平台。以下 我就罗列一下Zigbee开发基本工具: § 计算机:不管是设计电路还是编程开发都是离 不开它的。 § Zigbee开发板:对于初学者来说,Zigbee开发 板无疑是最佳选择。有了开发板,你可以在我 们成熟设计的基础上学习或者做自己的设计。 § Zigbee模块:集MCU,RF,天线设计于一体 的Zigbee模块。使用它,我们可省去设计天线 及IC周边电路设计的复杂工作。

进入Zigbee世界的准备工作
§ Zigbee仿真器:是集烧写程序、在线编程和在线仿真 功能于一身的开发过程工作中必不可少的开发工具。 编程器既能对CC243x芯片(其实包括TI产品中的CC 系列的大部分芯片)进行烧写程序(hex标准文件程序 ),也能对CC243x芯片进行在线编程和仿真,让我们 能方便地在线调试开发,从而大大地提高了开发效率 。 § Zigbee协议分析仪:ZigBee的设计开发者必不可少的 工具!ZigBee协议分析仪具有广泛的功能,包括:分 析以及解码在PHY、MAC、NETWORK/SECURITY、 APPLICATION FRAMEWORK、和APPLICATION PROFICES等各层协议上的信息包;显示出错的包以 及接入错误;指示触发包;在接收和登记过程中可连 续显示包。

进入Zigbee世界的准备工作
§ 再次,我们需要在将用于开发Zigbee的计 算机平台上安装这些软件: § Zigbee协议分析软件(sniffer) § 程序烧写软件(Flash Programmer) § IAR公司的EW8051 version 7.20I/W32 。

tcp、ip协议栈移植

This article was downloaded by: [University of Jiangnan] On: 27 March 2015, At: 06:51 Publisher: Taylor & Francis Informa Ltd Registered in England and Wales Registered Number: 1072954 Registered office: Mortimer House, 37-41 Mortimer Street, London W1T 3JH, UK Journal of Discrete Mathematical Sciences and Cryptography Publication details, including instructions for authors and subscription information: https://www.wendangku.net/doc/9014618716.html,/loi/tdmc20 An abridged protocol stack for micro controller in place of TCP/IP R. Seshadri a a Computer Centre, S.V. University , Tirupati , 517 502 , India Published online: 03 Jun 2013. PLEASE SCROLL DOWN FOR ARTICLE

An abridged protocol stack for micro controller in place of TCP/IP R.Seshadri ? Computer Centre S.V .University Tirupati 517502India Abstract The existing TCP/IP protocol stack running in hosts takes lot of overhead while the node in network is for a speci?c purpose.For example transferring simple messages across network.If the node in the network is not a PC but,some thing like a micro controller,which measures some values and stores in its local memory,then it becomes lavishness in using the micro controller’s memory.As it is a node in a network,working with TCP/IP ,it should be able to transfer those values in the form of messages to other hosts which are in either local network or global network. But in micro controller terms the memory is expensive and compact.The existing TCP/IP stack consumes a few mega bytes of memory.Therefore it can’t be accommodated in the memory of micro controller.Hence one needs to reduce the memory consumption.In this regard,an abridged protocol which replaces the existing TCP/IP has been designed to suit the above needs.For this purpose,the TCP/IP have been combined with KEIL C51features for 8051micro controller to make it work in transferring messages in local area network as well as global network. The above scheme was implemented and tested and the system was working satisfac-torily.The results are found to be more effective in communicating information/message from the micro controller to a PC. Keywords :Ethernet,stack,Transmission Control Protocol (TCP ),Internet Protocol (IP ).Introduction to TCP/IP The name TCP/IP refers to a suite of communication protocols.The name is misleading because TCP and IP are the only two of the dozens of protocols that compose the suite.Its name comes from two of the most ?E-mail :ravalaseshadri@yahoo.co.in —————————————————– Journal of Discrete Mathematical Sciences &Cryptography Vol.9(2006),No.3,pp.523–536 c Taru Publications D o w n l o a d e d b y [U n i v e r s i t y o f J i a n g n a n ] a t 06:51 27 M a r c h 2015

相关文档