在ip_rcv_finish函数的尾端,如果目的地址和本地接口不同,内核必须把封包转发至适当的主机,若目的地址是本地地址,内核必须把封包准备好,以便高层使用。本章主要介绍转发和本地传递是怎么完成的。

转发:

转发的工作由ip_forward函数和ip_forward_finish完成。此时,ip_rcv_finish里已经调用了ip_route_input,所以skb_buff中已经包含了转发封包所需要的所有信息。转发由下列步骤组成:

处理IP选项。

确定封包可以被转发。

递减IP报头的TTL字段。

根据路径相关MTU,必要时处理分片工作。

把封包传送至外出设备。

如果封包无法转发会发送ICMP,或者被转发了,但使用的是次佳路由,因而触发了重导项事件,发送ICMP来通知重导项事件。

和IPsec交互也是转发工作的一部分,由xfrm4_xxx函数实现,这些函数是进入IPsec基础架构的钩子。本书不会讨论IPsec,就是说后续讨论假设IPsec没有配置。

ip_forward函数:

原型:int ip_forward(struct sk_buff *skb);

如果报头中发现了Router Alert选项,则封包现在就会被处理。处理函数ip_call_ra_chain会先重组整个ip封包,然后把封包传给那些Raw套接字(这些套接字设置了IP_ROUTER_ALERT)。然后ip_forward直接返回。

如果报头中没有Router Alert选项,或者存在但没有感兴趣的程序在运行,ip_forward会继续下去:

if(IPCB(skb)->opt.router_alert && ip_call_ra_chain(skb) )

return NET_RX_SUCCESS;

if(skb->pkt_type !=  PACKET_HOST)

goto drop;

skb->ip_summed = CHECKSUM_NONE;//转发封包,不涉及L4,所以用CHECKSUM_NONE指出当前校验和无误,若有些处理工作修改了IP报头,TCP报头或有效载荷,那么在传输前,内核就会重算校验和。

真实的转发流程是由递减TTL字段开始的:

if(iph->ttl <= 1)

goto too_many_hops;

如果IP报头包含一个Strict Source Route选项,且下个跳点和路由子系统找到的不一样,则Source Routing选项失败了,丢弃该封包,发送一个ICMP报文给传送者。

rt = (struct rtable *)skb->dst;

if(opt->is_strictroute && rt->rt_dst != rt->rt_gateway)

goto sr_failed;

多数健康检查做完后,此函数会更新报头,所以需要拷贝缓冲区。

if(skb_cow(skb,LL_RESERVED_SAPCE(rt->u.dst.dev)+rt->udst.header_len))

goto drop;

现在,TTL会由ip_decrease_ttl递减,并且该函数还会更新ip校验和:

ip_decrease_ttl(iph);

如果有比请求的还要更好的下一跳点存在,原来的主机就会收到ICMP REDIRECT 消息(前提是原来的主机没有请求源路由之时??这里怎么理解?)。

if(rt->rt_flags & RTCF_DOREDIRECT && !opt->ssr)

ip_rt_send_redirect(skb);

这里,priority字段是使用ip头的TOS字段设定的,由Traffic Control(Qos层)使用。

skb->priority = rt_tos2priority(iph->tos);

最后,ip_forward函数会要求Netfilter执行ip_forward_finish(如果没有禁止转发的规则)

return NF_HOOK(PF_INET,NF_IP_FORWARD,skb,skb->dev,rt->u.dst.dev,ip_forward_finish);

ip_forward_finish函数:

到了这一步,说明封包已经通过所有会使其停止的检查,而且真的已经就绪,可以传输到另一个系统了。

先前在ip_forward函数中已经处理过Route Alert和Strict Source Routing选项了(还有其他选项,只是列举了这两个例子而已)。ip_forward_finish会调用ip_forward_options来处理那些选项所需的最后工作。最后,ip_forward_finish函数会调用dst_output函数将封包传递出去。

dst_output函数:

无论是本地产生还是转发,所有传输都会通过dst_output上路。此时,IP报头已经完成,内含传输所需信息以及本地系统负责添加的其他任何信息。dst_output函数会调用虚拟函数output,分段也是在该函数内部处理的。最后,会调用ip_finish_output来衔接邻居子系统,只有当Netfilter放行时,ip_finish_output才会被调用,否则丢弃封包。

static inline int dst_out(struct sk_buff *skb)

{

int err;

for(; ;){

err = skb->dst->output(&skb);

if(likely(err = 0))

return err;

if(unlikely(err != NET_XMIT_BYPASS))

return err;

}

}

本地传递:

第三十五章会说明转发(路由)引擎如何得知本地主机是封包的地址。当封包抵达目的主机时,ip_rcv_finish开端调用ip_route_input,就会把skb->dst->input初始化为ip_local_deliver。此外,Netfilter有最后的权力决定do_something函数是否可以调用相应的do_something_finish函数。

int ip_local_deliver(struct sk_buff *skb)

{

if(skb->nh.iph->frag_off & htons(IP_MF | IP_OFFSET)){

skb = ip_defrag(skb,IP_DEFRAG_LOCAL_DELIVER);//转发几乎不需要重组,而本地传递必须重组整个ip封包

if(!skb)

return 0;

}

return NF_HOOK(PF_INET,NF_IP_LOCAL_IN,skb,skb->dev,rt->u.dst.dev,ip_local_deliver_finish); //第二十四章会谈论ip_local_deliver_finish函数的细节

}

第二十章:因特网协议第四版(IPv4):转发和本地传递相关推荐

  1. 深入理解Linux网络技术内幕学习笔记第十九章:因特网协议第四版(IPv4):Linux的原理和功能

    本章主要介绍Linux支持IP的数据结构和基本活动,如入口IP包如何传递至IP接收函数,校验和如何验证,以及IP选项如何处理. 主要的IPv4数据结构: struct iphdr{ };//ip报头 ...

  2. 计算机操作系统 (第四版汤小丹老师) 复习笔记第一章

    教材为西安电子科技大学 汤小丹老师 第四版 1.1操作系统目标和作用 1.目标 目前存在着多种类型的OS,不同类型的OS,其目标各有所侧重.通常在计算机硬件上配置的OS,其目标有以下几点: 方便性 便 ...

  3. Algorithms, 4th Edition(算法-第四版)源码使用系统配置

    关于-Algorithms, 4th Edition (算法-第四版)源代码在本地机器的运行配置. 其实关于这个教程的使用已经在 Java Algorithms and Clients 页面中写出,并 ...

  4. JavaScript高级程序设计第四版学习--第二十四章

    title: JavaScript高级程序设计第四版学习–第二十四章 date: 2021-5-31 10:46:01 author: Xilong88 tags: JavaScript 本章内容: ...

  5. 互联网协议 — IPv4 互联网协议第 4 版

    目录 文章目录 目录 IPv4 IPv4 的报文格式 IPv4 Header IPv4 的地址 IPv4 的子网划分 子网掩码 IPv4 IPv4(Internet Protocol Version ...

  6. 《汇编语言》王爽(第四版) 第十章 实验10

    文章目录 前言 一.子程序1 显示字符串 1.实验任务 2.分析 (1)如何在指定位置显示 (2)如何显示指定颜色 (3)保存子程序中用到的寄存器 3.代码 二.子程序2 解决除法溢出的问题 1.实验 ...

  7. 现代操作系统英文第四版课后习题答案——第二章

    @T现代操作系统第四版参考答案 现代操作系统英文第四版第二章参考答案--进程 先更新第二章的答案,习惯中文的童鞋请左转百度翻译 Solution for chapter 2 The transitio ...

  8. 机器人导论(第四版)学习笔记——第二章

    机器人学导论(第四版)学习笔记--第二章 2. 空间描述和变换 2.1 引言 2.2 描述:位置.姿态与位姿 2.3 映射:从一个坐标系到另一个坐标系的变换 2.4 算子:平行,旋转和变换 2.5 总 ...

  9. 汇编语言 王爽 第四版 第二章 检测点2.2

    汇编语言 王爽 第四版 课后检测点 课后实验 持续更新~~ 检测点2.2 给定段地址为0001H,仅通过变化偏移地址寻址,CPU的寻址范围为 0010H 到 1000FH . 最小肯定是偏移地址为0, ...

最新文章

  1. centos7 安装jdk7
  2. 系统监控:top vs Htop vs Glances
  3. Linux2.6内核--中断线被关闭的情况
  4. python用pil图像放大缩小_python使用PIL缩放网络图片并保存的方法
  5. 【Python】分享几个好用到爆的Python内置模块
  6. ASP.NET Core Web API 与 SSL
  7. 缺失的第一个正数—leetcode41
  8. cad插件制作教程_CAD电子签名制作教程
  9. Python实战从入门到精通第十一讲——可接受任意数量参数的函数
  10. lesson 2.4 - Converting MEL Commands to Python
  11. INFORMATION_SESSION_VARIABLES feature is disabled问题
  12. 关于计算机信息管理的照片,2021年10月青海自考计算机科学与技术(计算机信息管理方向)专业报名照片要什么格式...
  13. 《中英文在自然语言处理上的十大差异点》学习总结
  14. 二维baker映射 matlab,基于Baker映射的混沌图像加密算法
  15. Open3d数据滤波和点云分割
  16. gcc用-O0优化无问题,-O3优化时程序崩溃的问题
  17. 【Android】HAL层浅析
  18. Qt windows下获取CPU、主板、硬盘、网卡等相关信息
  19. python nose
  20. 抓准痛点就能撬动市场!读屏时代的黑科技非它莫属了

热门文章

  1. Windows下安装 msysGit 以及初始化 Git server环境
  2. 经典Seq2Seq与注意力Seq2Seq模型结构详解
  3. my.cnf的常规配置
  4. shp、tif文件坐标系转换
  5. 堆栈~堆栈~是堆还是栈?
  6. mxgraph进阶(三)Web绘图—mxGraph项目实战
  7. opencv检测图片失焦 python_如何在Python中使用OpenCV执行模糊检测
  8. Java程序实现Word文档转为pdf以及出现的问题解决
  9. linux进阶之道 pdf,PDF
  10. Keras loss函数