ImageVerifierCode 换一换
格式:DOCX , 页数:45 ,大小:142.33KB ,
资源ID:11836954      下载积分:10 金币
快捷注册下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

开通VIP
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.zixin.com.cn/docdown/11836954.html】到电脑端继续下载(重复下载【60天内】不扣币)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

开通VIP折扣优惠下载文档

            查看会员权益                  [ 下载后找不到文档?]

填表反馈(24小时):  下载求助     关注领币    退款申请

开具发票请登录PC端进行申请

   平台协调中心        【在线客服】        免费申请共赢上传

权利声明

1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:0574-28810668;投诉电话:18658249818。

注意事项

本文(ipv6初始化和处理流程分析.docx)为本站上传会员【仙人****88】主动上传,咨信网仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知咨信网(发送邮件至1219186828@qq.com、拔打电话4009-655-100或【 微信客服】、【 QQ客服】),核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载【60天内】不扣币。 服务填表

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

1、Ipv6初始化和处理流程分析 一.Ipv6的初始化 1.网络子系统概述 Linux 内核中,与网络相关的代码是一个相对独立的子系统,称为网络子系统。 网络子系统是一个层次化的结构,可分为以下几个层次: 1)Socket 层 Linux 在发展过程中,采用 BSD socket APIs 作为自己的网络相关的 API 接口。同时,Linux 的目标又要能支持各种不同的协议族,而且这些协议族都可以使用 BSD socket APIs 作为应用层的编程接口。因此,在 socket APIs 与协议族层之间抽象出一个 socket 层,用于将 user space 的 socket API

2、 调用,转给具体的协议族做处理。 2)协议族层(INET协议族、INET6协议族等) Linux 网络子系统功能上相当完备,它不仅支持 INET 协议族(也就是通常所说的 TCP/IP stack),而且还支持其它很多种协议族,如 DECnet, ROSE, NETBEUI 等。INET6 就是一种新增加的协议族。 对于 INET、INET6 协议族来说, 又进一步划分为传输层和网络层。  3)设备驱动层 设备驱动层则主要将协议族层与物理的网络设备隔离开。它不在本文的讨论范围之内。 下图是 Linux 网络系统层次结构图。 2.网络子系统的初始化 1) Socket 层的初

3、始化: Init()->do_basic_setup()->sock_init() Sock_init():对 sock 和 skbuff 结构进行 SLAB 内存的初始化工作 2)各种网络协议族的初始化: Do_initcalls(): 对于编译到内核中的功能模块(而不是以模块的形式动态加载),它的初始化函数会在这个地方被调用到。  内核映象中专门有一个初始化段,所有编译到内核中的功能模块的初始化函数都会加入到这个段中;而 do_initcalls() 就是依次执行初始化段中的这些函数。 INET 协议族通常是被编译进内核的;它的模块初始化函数是 net/ipv4/af_ine

4、t.c 中的 inet_init() 而INET6 是作为一个模块编译的。它的模块初始化函数是 net/ipv6/af_inet6.c 中的 inet6_init() 3.协议族 Linux 网络子系统可以支持不同的协议族,Linux 所支持的协议族定义在 include/linux/socket.h 1)协议族数据结构 协议族数据结构是 struct net_proto_family。 struct net_proto_family {             int                     family;             int         

5、            (*create)(struct socket *sock, int protocol);             short                 authentication;             short                 encryption;             short                 encrypt_net;             struct module    *owner; }; 这个结构中,最重要的是create 函数,一个新的协议族,必须提供此函数的实现。这是因为:   

6、  不同的网络协议族,从user space的使用方法来说,都是一样的,都是先调用socket()来创建一个 socket fd,然后通过这个fd发送/接收数据。 在user space 通过 socket() 系统调用进入内核后,根据第一个参数协议族类型,来调用相应协议族create()函数。对INET6来说,这个函数inet6_create()。 因此,要实现一个新的协议族,首先需要提供一个create() 的实现。关于 create() 里面具体做了什么,后面再叙述。 Linux 系统通过这种方式,可以很方便的支持新的网络协议族,而不用修改已有的代码。这很好的符合了 “开-闭原

7、则”,对扩展开放,对修改封闭。 2)协议族注册 Linux 维护一个struct net_proto_family  的数组net_families[] 如果要支持一个新的网络协议族,那么需要定义自己的struct net_proto_family,并且通过调用 sock_register 将它注册到 net_families[] 中。 4.sock层 socket 层又叫 “socket access protocol layer”。它处于 BSD socket APIs 与底层具体的协议族之间。这是一个抽象层,它起着承上启下的作用。在这一层的数据结构也有着这种特点 1)数据结构

8、 在 user space,通过 socket() 创建的socket fd,在内核中对应的就是一个 struct socket。 struct socket {             socket_state                 state;             unsigned long                flags;             struct proto_ops           *ops;             struct fasync_struct       *fasync_list;             struc

9、t file                       *file;             struct sock                    *sk;             wait_queue_head_t       wait;             short                             type; }; 它定义于 include/linux/net.h 中。 Struct socket 的 ops 域指向一个 struct proto_ops 结构,struct proto_ops定义于 include/linux/net.h

10、 中,它是 socket 层提供给上层的接口,这个结构中,都是 BSD socket API 的具体实现的函数指针。 一个 socket API 通过系统调用进入内核后,首先由 socket 层处理。Socket 层找到对应的 struct socket,通过它找到 struct proto_ops,然后由它所指向的函数进行进一步处理。 以 sendmsg() 这个函数为例,从 user space 通过系统调用进入 kernel 后,由 sys_sendmsg()、sock_sendmsg() 依次处理,然后交给 struct proto_ops 的 sendmsg() 处理。 2)s

11、ock层和传输层的关联 INET 和 INET6 这两种协议族,可以支持多种传输层协议,包括 TCP、UDP、RAW,在 2.6 内核中,又增加了一种新的传输层协议:SCTP。 从内核角度看,要实现 INET6 协议族的某种传输层协议,则必须既提供 socket 层的 struct proto_ops 的实现,也提供 struct proto 的实现。除此之外,还需要提供一种手段,把这两个结构关联起来,也就是把 socket 层和传输层关联起来。 Linux 提供了一个 struct inet_protosw 的结构,用于 socket 层与传输层的关联。 struct inet_pr

12、otosw {             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   

13、    *prot;             struct proto_ops *ops;             int              capability; /* Which (if any) capability do                                                       * we need to use this socket                                                       * interface?*/             char        

14、     no_check;   /* checksum on rcv/xmit/none? */             unsigned char    flags;      /* See INET_PROTOSW_* below.  */ }; 这个结构定义于  include/net/protocol.h 中,从它的命名上可以看到它属于 INET 和 INET6 协议族,但是没有查到资料为什么叫做 protosw。 这个结构中,ops 指向 socket 层的 struct proto_ops,prot 指向传输层的 struct proto。 因此,对 INET6 这种要

15、支持多种传输层协议的协议族,从内核的角度来说,只需要为每一种传输层协议定义相应的 struct proto_ops、struct proto,然后再定义 struct inet_protosw,并将三者关联起来即可。 以 INET6 所支持的 TCP 为例:  static struct proto_ops inet6_sockraw_ops = {             .family =           PF_INET6,             .owner =          THIS_MODULE,             .release =         in

16、et6_release,             .bind =             inet6_bind,             .connect =        inet_dgram_connect,                 /* ok                */             .socketpair =    sock_no_socketpair,                /* a do nothing  */             .accept =          sock_no_accept,                   

17、               /* a do nothing  */             .getname =       inet6_getname,             .poll =              datagram_poll,                          /* ok                */             .ioctl =  inet6_ioctl,                                /* must change  */             .listen =            so

18、ck_no_listen,                         /* ok                */             .shutdown =     inet_shutdown,                         /* ok                */             .setsockopt =   sock_common_setsockopt,                  /* ok                */             .getsockopt =   sock_common_getsockopt,

19、                  /* ok                */             .sendmsg =       inet_sendmsg,                           /* ok                */             .recvmsg =       sock_common_recvmsg,                      /* ok                */             .mmap =                       sock_no_mmap,           

20、  .sendpage =      sock_no_sendpage, }; struct proto tcpv6_prot = {             .name                           = "TCPv6",             .owner                          = THIS_MODULE,             .close                           = tcp_close,             .connect                       = tcp_v6_co

21、nnect,             .disconnect                   = tcp_disconnect,             .accept                         = inet_csk_accept,             .ioctl                             = tcp_ioctl,             .init                               = tcp_v6_init_sock,             .destroy                 

22、       = tcp_v6_destroy_sock,             .shutdown                     = tcp_shutdown,             .setsockopt                   = tcp_setsockopt,             .getsockopt                  = tcp_getsockopt,             .sendmsg                      = tcp_sendmsg,             .recvmsg           

23、            = tcp_recvmsg,             .backlog_rcv                = tcp_v6_do_rcv,             .hash                            = tcp_v6_hash,             .unhash                         = tcp_unhash,             .get_port                      = tcp_v6_get_port,             .enter_memory_press

24、ure           = tcp_enter_memory_pressure,             .sockets_allocated        = &tcp_sockets_allocated,             .memory_allocated       = &tcp_memory_allocated,             .memory_pressure        = &tcp_memory_pressure,             .orphan_count              = &tcp_orphan_count,        

25、     .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

26、),             .twsk_obj_size             = sizeof(struct tcp6_timewait_sock),             .rsk_prot                      = &tcp6_request_sock_ops, }; static struct inet_protosw tcpv6_protosw = {             .type                 =          SOCK_STREAM,             .protocol          =        

27、  IPPROTO_TCP,             .prot                 =          &tcpv6_prot,             .ops                  =          &inet6_stream_ops,             .capability         =          -1,             .no_check        =          0,             .flags                =          INET_PROTOSW_PERMANENT,

28、 }; Linux 为 INET6 协议族定义一个 struct inet_protosw 的链表数组inetsw6[] 。 要支持某种传输层协议,首先实现相应的 struct proto_ops、struct proto,然后实现struct inet_protosw,将两者关联,最后,通过 inet6_register_protosw() ,将此 struct inet_protosw 注册到 inet6_sw[] 中。 注册的时候,根据 struct inet_protosw 的 type ,将它放到 inet6_sw[type] 所在的链表中,相同的 type, 不同的 pro

29、tocol,会在同一个链表上。 3)数据结构之间的联系 从 user space 角度看,要使用 INET6 协议族的某种传输层协议,首先需要通过 socket() 调用创建一个相应的 socket fd,然后再通过这个 socket fd,接收和发送数据。  socket() 的原型是: int socket(int domain, int type, int protocol); domain 指定了协议族.  type 表明在网络中通信所遵循的模式。主要的值有:SOCK_STREAM、SOCK_DGRAM、SOCK_RAW等。 SOCK_STREAM 是面向流的通信方式,而

30、 SOCK_DGRAM 是面向报文的通信方式。不同的通信方式,在接收数据和发送数据时,具有不同的处理方式。  Protocol 则指明具体的传输层协议。不同的传输层协议,可能具有相同的 type,例如 TCP 和 SCTP 都是 SOCK_STREAM 类型。 以 socket(PF_INET6, SOCK_STREAM, 0) 为例,在进入内核空间后,  根据 domain,找到inet6_family_ops。 创建 struct socket 调用inet6_family_opsde  create(),也就是inet6_create() inet6_create() 根据

31、 type 和 protocol 在 inet6_sw[] 中找到对应的 struct inet_protosw,也就是tcpv6_protosw 创建 struct sock,将 struct socket 和 struct sock 关联起来 将 struct socket 和 tcpv6_protosw 的 ops ,也就是inet6_stream_ops 关联起来 将 struct sock 和 tcpv6_protosw 的 prot,也就是tcpv6_prot 关联起来。 这样,socket 层和传输层的数据结构之间的关系建立起来了,此后,应用层通过 socket fd 接

32、收或者发送数据的时候,就会先经过 socket 层 inet6_stream_ops 处理,然后经过传输层的 tcpv6_prot 处理。 二.网卡接收数据 这部分是说明数据报文在在链路层的处理,以及如何将报文送交给对应的网络层协议来处理。这些功能基本都是在驱动中实现的。 1. 网络中接收数据报文的两个终端:硬中断和软中断 (1).硬中断的中断处理函数是在驱动中注册,一般在device open()函数或者 device init()函数中注册,使用request_irq()来注册硬中断处理函数。当网卡接收到数据的时候,就会调用这个终端处理函数来处理。比如8139too.c函数就用 

33、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)。触发这个中断信号(raise irq)一般是在硬中断处理流程中,当硬中断处理基本结束的时候,通过调用__raise_softirq_irqoff(NET_RX_SOFTIRQ)来触发这个中断。 2.接收软中断

34、 接收软中断(net_rx_action)主要还是通过调用驱动中的poll的方法进行接收。在poll方法中,会提取接收包,根据它所在的设备和协议类型传递给各自的包处理器。以rtl8139_poll为例,它会调用rtl8139_rx()来把尽可能多的数据在一次中断处理中处理完,而不是一个软中断只处理一个数据包,这样可以提高效率。每个数据包都会通过netif_receive_skb()函数,根据报文的协议类型,调用上层的包处理器。如果网卡本身驱动没有poll函数,将是调用bakclog_dev的process_backlog函数。 3.包处理器注册 包处理器用dev_add_pack()注册,

35、如果注册的设备号是零则表明它接收所有设备的包, 如果注册的包类型是(ETH_P_ALL),则表示它接收所有类型的包。 netif_receive_skb()函数会根据接受数据的协议类型,在ptype_all和ptype_base列表中去查找对应的处理协议,再将数据包传递给对应的协议处理函数。 对于ipv4,就是在af_inet.c中的inet_init()函数中,初始化了ip_packet_type.func = ip_rcv,因此,ip_rcv()将接收ipv4的报文。在inet_init()中调用dev_add_pack(&ip_packet_type)去在ptype_all和ptype

36、base中注册协议处理函数。ipv4的IP头类型值是ETH_P_IP:0x0800。 对于ipv6,则在af_inet6.c中的inet6_init()函数中完成初始化, inet6_init()调用ipv6_packet_init()来注册协议处理报文。Ipv6的IP头类型值是 ETH_P_IPV6  0x86DD。其注册的接收处理程序是ipv6_rcv()。 三.网络层的处理 这部分是说明数据报文在网络层的处理。上面一部分已经说明了在链路层的处理。在链路层的处理,基本都是在驱动中已经实现了的。接着链路层的处理,对于ipv6协议,处理过程在ipv6_recv()中。 ipv6_rc

37、v()中,会做一些必要的检查和更新MIB的一些信息,接着处理hopbyhop报头。然后进入NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL, ip6_rcv_finish); 对于NF_HOOK的作用解释。 如果没有配置netfilter,可以简单认为NF_HOOK就等于直接调用ip6_rcv_finish (skb)。 Ipv6_rcv()会处理hopbyhop报头,在ipv6_parse_hopopts()函数中处理。注意ip6_parse_tlv()的处理过程,它本身只处理PAD0和PAD1的type,就是rfc2460里面最早定义的

38、两个选项,其它选项都是通过tlvprochopopt_lst中定义的回调函数来处理的。这样就能够根据将来协议的发展,灵活的添加新的hopbyhop类型,而不需要修改这个函数本身。 对于除hopbyhop以外的扩展报头的处理,是通过路由表来进行的。在ip6_rcv_finish()里面,会调用ip6_route_input(skb),这个函数返回的是路由表中对应的fib6_node,这个节点的input函数,就会根据不同的目的地调用不同的函数来处理。具体说来: (1)If the destination address matches FE80:: skb->dst->inp

39、ut=ip6_input  skb->dst->output=ip6_output (2)Else if the destination address’s first 10 bits matches FE80:: skb->dst->input=ip6_forward skb->dst->output=ip6_output (3)Else if the destination address’s first 8 bits matches FF00:: skb->dst->input=ip6_mc_input skb->dst->output=ip6_output (4)Els

40、e ( no match) skb->dst->input= ip6_pkt_discard skb->dst->output=ip6_pkt_discard 对于ip6_route_input(skb)函数的分析,我们后面讲路由查找的时候再叙述,这里先跳过去。 说明一下到本机的路由表项的初始化过程。到本机的路由表的初始化是在给网卡分配ipv6地址的时候初始化的,代码在addrconf.c中。比如当用户在给网卡手动赋ipv6地址的时候,会通过netlink接口,传递到内核以后,就由rtnetlink_rcv_msg()来处理。Rtnetlink_recv_msg()会根据family的

41、值,在rtnetlink_links[family]表中进行查找,找到对应协议簇的处理表。对于ipv6而言是PF_INET6协议簇,调用的是inet6_rtnetlink_table[]。在inet6_rtnetlink_table[]表中,对应添加网卡ipv6地址的处理函数是inet6_rtm_newaddr()函数,因此整个处理过程是inet6_rtm_newaddr()àipv6_add_addr() à addrconf_dst_alloc() à rt->u.dst.input = ip6_input(),从而转入ip6_input()函数的处理。 转发路由表项的初始化和到本机的路

42、由表的初始化过程类似。从netlink再到ip6_route_add(),添加ip6_forward()的处理函数。 接上面第2点,在ip6_route_input(skb)函数调用中,返回的是路由表中对应的fib6_node结构,它会调用 skb->dst->input()函数。如果数据报文是到本机,这个函数就是ip6_input()函数。扩展报头的处理就在ip6_input()函数中。然后调用ip6_input_finish() à ipprot->handler(&skb) , 然后调用在inet6_protos[]里面注册了的ipv6各个扩展报头的处理函数。 在ipv6协议簇中的函

43、数调用流程如下图所示。 在tcpv6_init()函数中,通过inet6_add_protocol()向inet6_protos[]注册了处理函数tcp_v6_rcv(),这样,协议就会交给tcp_v6_rcv()处理了。这样就交给了传输层的协议栈来处理了。ICMPv6和UPDv6协议的处理类似。 这里注意各个处理函数的返回值,像icmpv6_rcv()返回0,表示这个数据报不再处理了,已经处理完了。而ipv6_destopt_rcv()则返回-1/1,-1表示出错了,就不再处理;1表示当前的报头已经处理完了,要接着处理这个数据报的下一个报头。这样,就把报文传送到了传输层了。对于传输层

44、我们选择一个简单的updv6协议,它注册的处理函数是udpv6_rcv(),这部分会在传输层的处理中论述。 四.路由模块的处理 路由节点结构是fib6_node的结构,通过这个结构来组织成一棵路由树。这个结构主要是用来组织路由结构树的,具体的路由信息是存放在fib6_node->leaf结构中,这是一个rt6_info的结构体。每个fib6_node伴随着一个rt6_info。查找路由的时候,遍历整个路由树,根据每个fib6_node节点的rt6_info信息,判断是否是自己需要的节点。如果是,则返回,然后根据这个节点的rt6_info信息进行路由。 路由表的组织结构如下图所示。 这

45、里多说两句,定义CONFIG_IPV6_SUBTREES情况,fib6_lookup_1会递归调用,但最多只能递归一次(因为subtree里不会再有subtree)。递归的那次fib6_lookup_1调用只对src进行了匹配,因为args[1]里的addr是src。 下图中的蓝色部分,表示每个fib6_node都伴随着一个rt6_info结构用来携带具体的路由信息。 ipv6的路由表是是一个radix树,根对应默认路由,结点的层次和路由prefix_len对应。在fib6_lookup_1()中下面的循环把fn设为叶子结点,然后从他开始匹配,如果不符就fn = fn->parent。

46、这样就做到了最长匹配原则。 for (;;)  {            struct fib6_node *next;             dir = addr_bit_set(args->addr, fn->fn_bit);             next = dir ? fn->right : fn->left;             if (next) {              fn = next; continue; }             break; }; 关于radix树的介绍,可以google,这里简单介绍一下,参考了blog: 

47、Radix tree 是一种搜索树,采用二进制数据进行查找,但对于路由表,采用的是二叉树的方式,只有一个Left和right两个子节点。(好像fn_bit表示的是prefix_len,就是路由前缀的长度,不确定?) 五.数据包接收流程分析 接收的流程为:ipv6_rcv--->ipv6_rcv_finish---->dst_input-àip6_input-àip6_input_finish 或者ipv6_rcv--->ipv6_rcv_finish---->ip6_route_input或者ipv6_rcv--->ipv6_rcv_finish---->dst_input-à

48、ip6_forward-àip6_forward_finish static struct packet_type ipv6_packet_type__read_mostly = {          .type= cpu_to_be16(ETH_P_IPV6),          .func= ipv6_rcv,          .gso_send_check= ipv6_gso_send_check,          .gso_segment= ipv6_gso_segment,          .gro_receive= ipv6_gro_receive,      

49、    .gro_complete= ipv6_gro_complete, };   //执行一些检查,判断数据包是否转发、有效性、正确性 intipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,struct net_device *orig_dev) {          structipv6hdr *hdr;          u32                   pkt_len;          structinet6_dev *idev; //获取数据包网卡          structnet *net = dev_net(skb->dev); //丢弃发送给其他主机的数据包          if(skb->pkt_type == PACKET_OTHERHOST) {                    kfree_skb(skb);                    return0;          }            rcu_read_lock();

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2025 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服