CS144(2024 Winter)Lab Checkpoint 6: building an IP router

0.Overview

check6.pdf

在本次实验中,我们需要完成一个路由器的基本功能:路由表存储、路由查询和数据分组转发。

当然这节实验我们不需要实现 OSPF、RIP、BGP 等路由生成算法,我们只需要基于 check5 的 NetworkInterface 抽象网络接口完成路由器的最长前缀匹配算法即可。

1.需求分析

本节实验也比较简单,这里只大概介绍一下给定的成员方法。

1.1 void Router::add_route 方法

该方法主要负责向路由器的路由表中添加新的路由规则。一条路由规则由以下几个信息组成:

  • uint32_t prefix 路由前缀,即网络号;
  • uint8_t prefix_length 前缀长度,即子网掩码长度;
  • optional<Address> next_hop 下一跳地址,这个信息是可空的,因为当这个路由接口直接连接(点对点)到目的主机上时,下一跳是不存在的(也就是所谓的“直接交付”);
  • size_t interface_num 当前路由规则对应的路由接口编号。

简单查看 Router 中已给好的代码,就可以得知:我们需要使用给定网络前缀找出网络接口编号,并使用方法 Router::interface 选中对应的网络接口,再调用方法 NetworkInterface::send_datagram 发出数据报。

文档提及,路由表可以由任意数据结构实现,但必须保证遍历时的时间复杂度尽可能小;正常来说遍历路由表的最大时间开销是 O(n)(因为最坏情况下也就是试探了所有表项)。

要注意很关键的一点,代码中的 Address 类是允许在 uint32_tAddress 类型本身之间互相转换的,这个转换规则允许我们以数值形式(uint32_t)处理代码中所有的 ip 地址。
Address -> uint32_t 使用 Address::ipv4_numeric,反之使用 Address::from_ipv4_numeric

1.2 void Router::route 方法

代码注释里直接告诉我们,这个方法需要在每次调用时遍历所有网络接口,并处理所有存储在网络接口的缓冲队列中的数据报。

处理数据报时,按照数据报的目的 ip 地址,使用最长前缀匹配算法从路由表中找出最合适的路由项。路由器仅在数据报 TTL 下降到 0、或者找不到路由表项时丢弃数据报。

数据报的 TTL 不仅要在刚从队列中取出时大于 0,并且在经过此路由器、TTL - 1 时也必须大于 0,否则一律丢弃。

在找到匹配的路由表项后,使用路由表中的接口序号、调用 Router::interface 方法选中路由器持有的网络接口,并使用 NetworkInterface::interface 方法转发数据报。

需要注意的是,IP 数据报是带校验和的,因此在更改数据报头部的 TTL 值后一定要调用 IPv4Header::compute_checksum 方法重新计算数据报的校验和。

1.3 Q&A

Q&A 中补充了一些额外的信息,以及单元测试中的网络拓扑结构图。

  • 数据报找不到路由、或 TTL 归零时不必向发送方回传 ICMP 信息。

路由器的网络拓扑结构如下:

network_structure

其实就是从每个接口的缓冲队列中读取数据报,并将这些数据报按路由匹配结果从另一些接口中发出。一些带有 direct 注释的接口表示这个接口和目的主机是点对点连接的。

2.代码实现

路由的关键在于我们要根据子网掩码长度,使用最长前缀匹配算法从路由表中找出最合适的一项。在进行最长前缀匹配时,我们必然是在遍历整个路由表,所以我们需要的路由表是始终有序的列表(容器)。

这种键值组合很自然就能想到使用 std::multimap,其底层的红黑树结构能够保证多条路由规则插入后,路由表始终是按键有序排列,而允许键重复则能够容纳多条子网掩码长度相同的路由规则。

在前缀匹配时,我们只关心待匹配的 ip 地址的前 n 位是否和当前路由表项相同,所以在路由表中我们可以只记录四条信息:子网掩码、网络号、网络接口和可选的下一跳地址(子网掩码就是前缀长度,但我们没必要存储前缀长度)。其中子网掩码作为 std::multimap 的键,并使用 std::greater 指示红黑树按降序排序所有数据。这样一来我们在顺序遍历路由表时,可以非常自然的从前缀长度最长的那一项开始匹配。

因为代码中只给出了前缀长度,而不是直接给出子网掩码,所以我们需要用位运算技巧从前缀长度生成目标子网掩码;一种比较优雅的方式是这样:~( UINT32_MAX >> prefix_length )

在匹配时,我们只需要将路由表中的子网掩码与目的 ip 地址进行按位与,并把结果与网络号作比较,仅在相等时匹配即可。

仔细观察上方的网络拓扑图,我们可以发现程序运行时接收到的路由地址并不总是网络地址,有可能出现网络地址是 128.30.0.0/16 但程序传给我们的是 128.30.76.255/16;所以我们还需要使用子网掩码将给定的 ip 地址进行一次过滤(按位与),才能存储到路由表中。

router

代码行数多是因为格式化代码后的代码风格很丑(不是)。

test_result

  • 24
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: "pathtolatestcheckpoint(default:none)" 表示最新检查点的路径。其中,“default:none”表示如果没有最新的检查点,则默认值为“none”。这通常用于深度学习模型的训练和保存,以便在需要的时候恢复模型的状态。 ### 回答2: "path to latest checkpoint (default: none)" 这句话是指最新检查点的路径(默认为无)。在机器学习中,Checkpoint(检查点)是训练过程中保存模型参数的一种方法。通过保存模型的检查点,我们可以在训练过程中断后重新开始,或者在训练完成后使用保存的检查点来进行模型的评估和推理。 在这里,"path to latest checkpoint" 指的是保存最新模型检查点的路径。模型检查点是以文件的形式保存在计算机中,而路径则表示了存储检查点文件的位置。 如果没有指定最新检查点的路径(即默认为无),那么系统会认为没有保存最新的模型检查点,并且不会进行任何相关操作。在某些情况下,我们可能不需要在训练过程中保存检查点,或者我们可能会使用已存储的检查点来进行训练的起点。 总而言之,这段话的含义是询问是否指定了最新模型检查点的路径,默认情况下不指定。 ### 回答3: "path to latest checkpoint (default: none)" 这句话是指在某个程序或系统中,有一个参数或选项叫做"最新检查点的路径",默认情况下该选项是没有设置的。 在机器学习和深度学习中,模型训练过程通常会不断保存模型的中间状态,以便在训练中断或出现错误时能够继续训练。这些保存的中间状态被称为检查点。最新检查点的路径就是指最后一次保存的模型的位置或路径。 在程序或系统初始化时,可能会需要指定一个最新检查点的路径,这样系统在运行时就可以加载最新的模型参数,继续训练或进行预测任务。如果没有设置最新检查点路径,默认情况下系统将无法加载中间模型的参数,需要重新从头开始训练模型。 因此,在给出"path to latest checkpoint (default: none)"这样的提示时,程序或系统希望用户提供最新检查点的路径,以便加载最新的模型参数。用户可以根据自己保存模型的方式、模型文件的位置等信息来设置正确的路径,从而实现对模型的继续训练或预测。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值