ipv6初始化和处理流程分析.docx

上传人:b****7 文档编号:9803084 上传时间:2023-02-06 格式:DOCX 页数:57 大小:42.96KB
下载 相关 举报
ipv6初始化和处理流程分析.docx_第1页
第1页 / 共57页
ipv6初始化和处理流程分析.docx_第2页
第2页 / 共57页
ipv6初始化和处理流程分析.docx_第3页
第3页 / 共57页
ipv6初始化和处理流程分析.docx_第4页
第4页 / 共57页
ipv6初始化和处理流程分析.docx_第5页
第5页 / 共57页
点击查看更多>>
下载资源
资源描述

ipv6初始化和处理流程分析.docx

《ipv6初始化和处理流程分析.docx》由会员分享,可在线阅读,更多相关《ipv6初始化和处理流程分析.docx(57页珍藏版)》请在冰豆网上搜索。

ipv6初始化和处理流程分析.docx

ipv6初始化和处理流程分析

Ipv6初始化和处理流程分析

一.Ipv6的初始化

1.网络子系统概述

Linux内核中,与网络相关的代码是一个相对独立的子系统,称为网络子系统。

网络子系统是一个层次化的结构,可分为以下几个层次:

1)Socket层

Linux在发展过程中,采用BSDsocketAPIs作为自己的网络相关的API接口.同时,Linux的目标又要能支持各种不同的协议族,而且这些协议族都可以使用BSDsocketAPIs作为应用层的编程接口。

因此,在socketAPIs与协议族层之间抽象出一个socket层,用于将userspace的socketAPI调用,转给具体的协议族做处理。

2)协议族层(INET协议族、INET6协议族等)

Linux网络子系统功能上相当完备,它不仅支持INET协议族(也就是通常所说的TCP/IPstack),而且还支持其它很多种协议族,如DECnet,ROSE,NETBEUI等。

INET6就是一种新增加的协议族。

对于INET、INET6协议族来说,又进一步划分为传输层和网络层. 

3)设备驱动层

设备驱动层则主要将协议族层与物理的网络设备隔离开.它不在本文的讨论范围之内。

下图是Linux网络系统层次结构图。

2.网络子系统的初始化

1)Socket层的初始化:

Init()—〉do_basic_setup()->sock_init()

Sock_init():

对sock和skbuff结构进行SLAB内存的初始化工作

2)各种网络协议族的初始化:

Do_initcalls():

对于编译到内核中的功能模块(而不是以模块的形式动态加载),它的初始化函数会在这个地方被调用到。

 内核映象中专门有一个初始化段,所有编译到内核中的功能模块的初始化函数都会加入到这个段中;而do_initcalls()就是依次执行初始化段中的这些函数。

INET协议族通常是被编译进内核的;它的模块初始化函数是net/ipv4/af_inet.c中的inet_init()

而INET6是作为一个模块编译的。

它的模块初始化函数是net/ipv6/af_inet6.c中的inet6_init()

3.协议族

Linux网络子系统可以支持不同的协议族,Linux所支持的协议族定义在include/linux/socket.h

1)协议族数据结构

协议族数据结构是structnet_proto_family。

struct net_proto_family {

            int                     family;

            int                     (*create)(struct socket *sock, int protocol);

            short                 authentication;

            short                 encryption;

            short                 encrypt_net;

            struct module    *owner;

};

这个结构中,最重要的是create函数,一个新的协议族,必须提供此函数的实现。

这是因为:

    

不同的网络协议族,从userspace的使用方法来说,都是一样的,都是先调用socket()来创建一个socketfd,然后通过这个fd发送/接收数据。

在userspace通过socket()系统调用进入内核后,根据第一个参数协议族类型,来调用相应协议族create()函数。

对INET6来说,这个函数inet6_create()。

因此,要实现一个新的协议族,首先需要提供一个create()的实现.关于create()里面具体做了什么,后面再叙述.

Linux系统通过这种方式,可以很方便的支持新的网络协议族,而不用修改已有的代码。

这很好的符合了“开—闭原则”,对扩展开放,对修改封闭。

2)协议族注册

Linux维护一个structnet_proto_family 的数组net_families[]

如果要支持一个新的网络协议族,那么需要定义自己的structnet_proto_family,并且通过调用sock_register将它注册到net_families[]中.

4。

sock层

socket层又叫“socketaccessprotocollayer”。

它处于BSDsocketAPIs与底层具体的协议族之间。

这是一个抽象层,它起着承上启下的作用。

在这一层的数据结构也有着这种特点

1)数据结构

在userspace,通过socket()创建的socketfd,在内核中对应的就是一个structsocket。

struct socket {

            socket_state                 state;

            unsigned long                flags;

            struct proto_ops           *ops;

            struct fasync_struct       *fasync_list;

            struct file                       *file;

            struct sock                    *sk;

            wait_queue_head_t       wait;

            short                             type;

};

它定义于include/linux/net。

h中。

Structsocket的ops域指向一个structproto_ops结构,structproto_ops定义于include/linux/net。

h中,它是socket层提供给上层的接口,这个结构中,都是BSDsocketAPI的具体实现的函数指针。

一个socketAPI通过系统调用进入内核后,首先由socket层处理。

Socket层找到对应的structsocket,通过它找到structproto_ops,然后由它所指向的函数进行进一步处理。

以sendmsg()这个函数为例,从userspace通过系统调用进入kernel后,由sys_sendmsg()、sock_sendmsg()依次处理,然后交给structproto_ops的sendmsg()处理。

2)sock层和传输层的关联

INET和INET6这两种协议族,可以支持多种传输层协议,包括TCP、UDP、RAW,在2。

6内核中,又增加了一种新的传输层协议:

SCTP.

从内核角度看,要实现INET6协议族的某种传输层协议,则必须既提供socket层的structproto_ops的实现,也提供structproto的实现.除此之外,还需要提供一种手段,把这两个结构关联起来,也就是把socket层和传输层关联起来.

Linux提供了一个structinet_protosw的结构,用于socket层与传输层的关联。

struct inet_protosw {

            struct list_head list;

        /* These two fields form the lookup key.  */

            unsigned short   type;       /* This is the 2nd argument to socket

(2)。

 */

            int                     protocol; /* This is the L4 protocol number。

  */ 

            struct proto       *prot;

            struct proto_ops *ops;

            int              capability; /* Which (if any) capability do

                                                      * we need to use this socket

                                                      * interface?

*/

            char             no_check;   /* checksum on rcv/xmit/none?

 */

            unsigned char    flags;      /* See INET_PROTOSW_* below。

  */

};

这个结构定义于 include/net/protocol.h中,从它的命名上可以看到它属于INET和INET6协议族,但是没有查到资料为什么叫做protosw。

这个结构中,ops指向socket层的structproto_ops,prot指向传输层的structproto。

因此,对INET6这种要支持多种传输层协议的协议族,从内核的角度来说,只需要为每一种传输层协议定义相应的structproto_ops、structproto,然后再定义structinet_protosw,并将三者关联起来即可。

以INET6所支持的TCP为例:

 

static struct proto_ops inet6_sockraw_ops = {

            。

family =           PF_INET6,

            .owner =          THIS_MODULE,

            。

release =         inet6_release,

            .bind =             inet6_bind,

            。

connect =        inet_dgram_connect,                 /* ok                */

            .socketpair =    sock_no_socketpair,                /* a do nothing  */

            .accept =          sock_no_accept,                                  /* a do nothing  */

            .getname =       inet6_getname,

            .poll =              datagram_poll,                          /* ok                */

            。

ioctl =  inet6_ioctl,                                /* must change  */

            .listen =            sock_no_listen,                         /* ok                */

            。

shutdown =     inet_shutdown,                         /* ok                */

            .setsockopt =   sock_common_setsockopt,                  /* ok                */

            。

getsockopt =   sock_common_getsockopt,                  /* ok                */

            。

sendmsg =       inet_sendmsg,                           /* ok                */

            .recvmsg =       sock_common_recvmsg,                      /* ok                */

            。

mmap =                       sock_no_mmap,

            。

sendpage =      sock_no_sendpage,

};

struct proto tcpv6_prot = {

            。

name                           = ”TCPv6",

            。

owner                          = THIS_MODULE,

            。

close                           = tcp_close,

            。

connect                       = tcp_v6_connect,

            .disconnect                   = tcp_disconnect,

            。

accept                         = inet_csk_accept,

            。

ioctl                             = tcp_ioctl,

            。

init                               = tcp_v6_init_sock,

            .destroy                        = tcp_v6_destroy_sock,

            .shutdown                     = tcp_shutdown,

            。

setsockopt                   = tcp_setsockopt,

            。

getsockopt                  = tcp_getsockopt,

            .sendmsg                      = tcp_sendmsg,

            。

recvmsg                       = tcp_recvmsg,

            。

backlog_rcv                = tcp_v6_do_rcv,

            .hash                            = tcp_v6_hash,

            。

unhash                         = tcp_unhash,

            .get_port                      = tcp_v6_get_port,

            .enter_memory_pressure           = tcp_enter_memory_pressure,

            。

sockets_allocated        = &tcp_sockets_allocated,

            .memory_allocated       = &tcp_memory_allocated,

            .memory_pressure        = &tcp_memory_pressure,

            。

orphan_count              = &tcp_orphan_count,

            .sysctl_mem                  = sysctl_tcp_mem,

            .sysctl_wmem               = sysctl_tcp_wmem,

            。

sysctl_rmem                = sysctl_tcp_rmem,

            。

max_header                 = MAX_TCP_HEADER,

            。

obj_size                       = sizeof(struct tcp6_sock),

            。

twsk_obj_size             = sizeof(struct tcp6_timewait_sock),

            .rsk_prot                      = &tcp6_request_sock_ops,

};

static struct inet_protosw tcpv6_protosw = {

            .type                 =          SOCK_STREAM,

            .protocol          =          IPPROTO_TCP,

            。

prot                 =          &tcpv6_prot,

            。

ops                  =          &inet6_stream_ops,

            。

capability         =          -1,

            .no_check        =          0,

            .flags                =          INET_PROTOSW_PERMANENT,

};

Linux为INET6协议族定义一个structinet_protosw的链表数组inetsw6[]。

要支持某种传输层协议,首先实现相应的structproto_ops、structproto,然后实现structinet_protosw,将两者关联,最后,通过inet6_register_protosw(),将此structinet_protosw注册到inet6_sw[]中。

注册的时候,根据structinet_protosw的type,将它放到inet6_sw[type]所在的链表中,相同的type,不同的protocol,会在同一个链表上。

3)数据结构之间的联系

从userspace角度看,要使用INET6协议族的某种传输层协议,首先需要通过socket()调用创建一个相应的socketfd,然后再通过这个socketfd,接收和发送数据。

 

socket()的原型是:

intsocket(intdomain,inttype,intprotocol);

domain指定了协议族. 

type表明在网络中通信所遵循的模式。

主要的值有:

SOCK_STREAM、SOCK_DGRAM、SOCK_RAW等。

SOCK_STREAM是面向流的通信方式,而SOCK_DGRAM是面向报文的通信方式.不同的通信方式,在接收数据和发送数据时,具有不同的处理方式。

 

Protocol则指明具体的传输层协议。

不同的传输层协议,可能具有相同的type,例如TCP和SCTP都是SOCK_STREAM类型。

以socket(PF_INET6,SOCK_STREAM,0)为例,在进入内核空间后, 

根据domain,找到inet6_family_ops。

创建structsocket

调用inet6_family_opsde create(),也就是inet6_create()

inet6_create()根据type和protocol在inet6_sw[]中找到对应的structinet_protosw,也就是tcpv6_protosw

创建structsock,将structsocket和structsock关联起来

将structsocket和tcpv6_protosw的ops,也就是inet6_stream_ops关联起来

将structsock和tcpv6_protosw的prot,也就是tcpv6_prot关联起来.

这样,socket层和传输层的数据结构之间的关系建立起来了,此后,应用层通过socketfd接收或者发送数据的时候,就会先经过socket层inet6_stream_ops处理,然后经过传输层的tcpv6_prot处理。

二。

网卡接收数据

这部分是说明数据报文在在链路层的处理,以及如何将报文送交给对应的网络层协议来处理。

这些功能基本都是在驱动中实现的.

1。

网络中接收数据报文的两个终端:

硬中断和软中断

(1)。

硬中断的中断处理函数是在驱动中注册,一般在deviceopen()函数或者deviceinit()函数中注册,使用request_irq()来注册硬中断处理函数。

当网卡接收到数据的时候,就会调用这个终端处理函数来处理。

比如8139too.c函数就用 retval=request_irq(dev—〉irq,rtl8139_interrupt,SA_SHIRQ,dev->name,dev)来注册硬中断处理函数。

(2)。

软中断是通过NET_RX_SOFTIRQ信号来触发的,处理函数是net_rx_action。

注册函数是open_softirq(NET_RX_SOFTIRQ,net_rx_action,NULL).触发这个中断信号(raiseirq)一般是在硬中断处理流程中,当硬中断处理基本结束的时候,通过调用__raise_softirq_irqoff(NET_RX_SOFTIRQ)来触发这个中断。

2。

接收软中断

接收软中断(net_rx_action)主要还是通过调用驱动中的poll的方法进行接收.在poll方法中,会提取接收包,根据它所在的设备和协议类型传递给各自的包处理器.以rtl8

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 总结汇报 > 学习总结

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1